summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2021-05-09 04:21:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2021-05-09 04:21:55 +0000
commit453cc058d9ee6d7cb47529d99061216e72149a5f (patch)
tree38e3683d9cb52c2f181d65ba513554a5e1387f20
parentInitial commit. (diff)
downloadprogress-linux-tools-453cc058d9ee6d7cb47529d99061216e72149a5f.tar.xz
progress-linux-tools-453cc058d9ee6d7cb47529d99061216e72149a5f.zip
Adding bin.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
l---------bin/badd.sh1
l---------bin/bbuild.sh1
-rwxr-xr-xbin/bfh-chroot328
l---------bin/bget.sh1
l---------bin/bimport.sh1
l---------bin/bmove.sh1
l---------bin/bsign.sh1
l---------bin/bupdate.sh1
l---------bin/bupload.sh1
-rwxr-xr-xbin/clean_challenge.nsupdate.sh26
-rwxr-xr-xbin/debian-chroot367
-rwxr-xr-xbin/debian-patches-apply28
-rwxr-xr-xbin/debian-patches-test28
-rwxr-xr-xbin/debian-patches-unapply28
-rwxr-xr-xbin/debian-sponsor.sh68
-rwxr-xr-xbin/debsign.sh69
-rwxr-xr-xbin/dehydrated-cron7
-rwxr-xr-xbin/dehydrated-hook.d297
-rwxr-xr-xbin/dehydrated-knotupdate83
-rwxr-xr-xbin/deploy_cert.fullchain-privkey.sh9
-rwxr-xr-xbin/deploy_cert.slapd.sh78
-rwxr-xr-xbin/deploy_challenge.nsupdate.sh26
-rwxr-xr-xbin/deploy_ocsp.fullchain-privkey.sh8
-rwxr-xr-xbin/exit_hook.fix-permissions.sh15
-rwxr-xr-xbin/exit_hook.service-reload.sh13
-rwxr-xr-xbin/exit_hook.slapd.sh42
-rwxr-xr-xbin/git-amend-all11
l---------bin/git-bfh-add1
l---------bin/git-bfh-changelog1
l---------bin/git-bfh-check1
l---------bin/git-bfh-check.d1
l---------bin/git-bfh-init1
l---------bin/git-bfh-release1
l---------bin/git-bfh-tag1
-rwxr-xr-xbin/git-checkout-all28
-rwxr-xr-xbin/git-checkout-branches44
-rwxr-xr-xbin/git-cherry-pick-recursive37
-rwxr-xr-xbin/git-clone.sh33
-rwxr-xr-xbin/git-commit-lazy11
-rwxr-xr-xbin/git-debian-add25
-rwxr-xr-xbin/git-debian-changelog197
-rwxr-xr-xbin/git-debian-check132
-rwxr-xr-xbin/git-debian-check.d/branch_initial-empty-commit.sh31
-rwxr-xr-xbin/git-debian-check.d/comit_good-signatures.sh32
-rwxr-xr-xbin/git-debian-check.d/comit_signed-off-lines.sh32
-rwxr-xr-xbin/git-debian-check.d/commit_message-begin-with-capital-letter.sh36
-rwxr-xr-xbin/git-debian-check.d/commit_message-end-with-full-stop.sh36
-rwxr-xr-xbin/git-debian-check.d/commit_release-commits-have-release-tags.sh38
-rwxr-xr-xbin/git-debian-check.d/packaging_debian-maintainer-fields.sh29
-rwxr-xr-xbin/git-debian-check.d/packaging_debian-source-compression.sh43
-rwxr-xr-xbin/git-debian-check.d/packaging_debian-source-format.sh31
-rwxr-xr-xbin/git-debian-check.d/packaging_debian-source-local-options.sh29
-rwxr-xr-xbin/git-debian-check.d/packaging_debian-upload-urgency.sh48
-rwxr-xr-xbin/git-debian-check.d/packaging_debian-vcs-fields.sh35
-rwxr-xr-xbin/git-debian-check.d/packaging_no-direct-upstream-changes.sh31
-rwxr-xr-xbin/git-debian-check.d/repository_branches-exist.sh34
-rwxr-xr-xbin/git-debian-check.d/repository_branches-not-exist.sh34
-rwxr-xr-xbin/git-debian-check.d/repository_clean-working-directory.sh30
-rwxr-xr-xbin/git-debian-check.d/tag_all-tags-are-on-branch.sh36
-rwxr-xr-xbin/git-debian-check.d/tag_messages-match-release-commit.sh36
-rwxr-xr-xbin/git-debian-check.d/tag_messages-match-version.sh36
-rwxr-xr-xbin/git-debian-check.d/tag_signatures-with-gnupg.sh34
-rwxr-xr-xbin/git-debian-import72
-rwxr-xr-xbin/git-debian-init113
-rwxr-xr-xbin/git-debian-release33
-rwxr-xr-xbin/git-debian-tag19
-rwxr-xr-xbin/git-dpkg-source231
-rwxr-xr-xbin/git-new.sh49
l---------bin/git-progress-linux-add1
l---------bin/git-progress-linux-changelog1
l---------bin/git-progress-linux-check1
l---------bin/git-progress-linux-check.d1
l---------bin/git-progress-linux-init1
l---------bin/git-progress-linux-release1
l---------bin/git-progress-linux-tag1
-rwxr-xr-xbin/git-remove-origin-branches10
-rwxr-xr-xbin/git-remove-origin-tags10
-rwxr-xr-xbin/git-repo-repack45
-rwxr-xr-xbin/git-upstream-add39
-rwxr-xr-xbin/git-upstream-tag17
-rwxr-xr-xbin/git-whoami33
-rwxr-xr-xbin/gpg-sig20
-rwxr-xr-xbin/gpg-sign14
-rwxr-xr-xbin/list-versions-engywuck-backports.sh63
-rwxr-xr-xbin/list-versions-engywuck.sh71
-rwxr-xr-xbin/list-versions_engywuck.sh63
-rwxr-xr-xbin/padd.sh160
-rwxr-xr-xbin/pbuild.sh314
-rwxr-xr-xbin/pget.sh68
-rwxr-xr-xbin/pimport.sh534
-rwxr-xr-xbin/pmove.sh144
-rwxr-xr-xbin/psign.sh108
-rwxr-xr-xbin/pupdate.sh265
-rwxr-xr-xbin/pupload.sh53
-rwxr-xr-xbin/reprepro_add.sh76
-rwxr-xr-xbin/reprepro_check-buildinfo.sh49
-rwxr-xr-xbin/reprepro_fix-changes.sh139
-rwxr-xr-xbin/reprepro_foreign.sh23
-rwxr-xr-xbin/reprepro_html.sh58
-rwxr-xr-xbin/reprepro_init.sh37
-rwxr-xr-xbin/reprepro_mirror.sh35
-rwxr-xr-xbin/reprepro_pull.sh49
-rwxr-xr-xbin/reprepro_re-import.sh55
-rwxr-xr-xbin/reprepro_reset.sh14
-rwxr-xr-xbin/reprepro_sync.sh38
-rwxr-xr-xbin/reverse12
-rwxr-xr-xbin/sha512sums13
-rwxr-xr-xbin/ssh-keygen-new-host.sh25
108 files changed, 5922 insertions, 0 deletions
diff --git a/bin/badd.sh b/bin/badd.sh
new file mode 120000
index 0000000..b7a6ce0
--- /dev/null
+++ b/bin/badd.sh
@@ -0,0 +1 @@
+padd.sh \ No newline at end of file
diff --git a/bin/bbuild.sh b/bin/bbuild.sh
new file mode 120000
index 0000000..678e093
--- /dev/null
+++ b/bin/bbuild.sh
@@ -0,0 +1 @@
+pbuild.sh \ No newline at end of file
diff --git a/bin/bfh-chroot b/bin/bfh-chroot
new file mode 100755
index 0000000..a611cd6
--- /dev/null
+++ b/bin/bfh-chroot
@@ -0,0 +1,328 @@
+#!/bin/sh
+
+set -e
+
+COMMAND="${1:-enter}"
+
+if [ -n "${2}" ]
+then
+ DISTRIBUTION="$(echo ${2} | awk -F- '{ print $1 }')"
+else
+ DISTRIBUTION="${2:-sid}"
+fi
+
+if [ -n "${3}" ]
+then
+ ARCHITECTURE="${3:-$(dpkg --print-architecture)}"
+else
+ ARCHITECTURE="$(echo ${2} | awk -F- '{ print $2 }')"
+ ARCHITECTURE="${ARCHITECTURE:-amd64}"
+fi
+
+case "${DISTRIBUTION}" in
+ *)
+ MIRROR="debian.ethz.ch"
+ ;;
+esac
+
+CHROOT="/srv/chroots/${DISTRIBUTION}-${ARCHITECTURE}"
+
+Chroot ()
+{
+ if [ "${ARCHITECTURE}" = "$(dpkg --print-architecture)" ]
+ then
+ chroot "${CHROOT}" /usr/bin/env -i HOME="/root" PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" TERM="${TERM}" ${@}
+ else
+ linux32 chroot "${CHROOT}" /usr/bin/env -i HOME="/root" PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" TERM="${TERM}" ${@}
+ fi
+}
+
+case "${COMMAND}" in
+ create)
+ if [ ! -d "${CHROOT}" ]
+ then
+ debootstrap --arch=${ARCHITECTURE} --include=progress-linux ${DISTRIBUTION} "${CHROOT}" http://${MIRROR}/debian
+ else
+ echo "${CHROOT}: file or directory already exists."
+ exit 1
+ fi
+
+ # Configure apt
+
+cat > "${CHROOT}/etc/apt/apt.conf.d/chroot.conf" << EOF
+Acquire::PDiffs "false";
+APT::Clean-Installed "true";
+APT::Install-Recommends "false";
+APT::Install-Suggests "false";
+EOF
+
+cat > "${CHROOT}/etc/apt/sources.list" << EOF
+deb http://${MIRROR}/debian ${DISTRIBUTION} main contrib non-free
+EOF
+
+ case "${DISTRIBUTION}" in
+ sid)
+
+cat >> "${CHROOT}/etc/apt/sources.list" << EOF
+deb http://${MIRROR}/debian experimental main contrib non-free
+EOF
+
+ ;;
+
+ buster)
+
+cat > "${CHROOT}/etc/apt/sources.list.d/progress-linux.sources" << EOF
+Types: deb
+URIs: https://cdn.deb.progress-linux.org/packages
+Suites: engywuck-backports
+Components: main contrib non-free restricted
+PDiffs: no
+Signed-By: /usr/share/progress-linux/pgp-keys/apt.progress-linux.org.gpg
+EOF
+
+ ;;
+ esac
+
+ # Configure bash
+
+cat > "${CHROOT}/etc/profile.d/chroot.sh" << EOF
+#!/bin/sh
+
+alias ls="ls --color=auto"
+
+export DEBEMAIL="maintainers@lists.progress-linux.org"
+export DEBFULLNAME="Progress Linux Maintainers"
+
+export LANG="en_US.UTF-8"
+export LANGUAGE="en_US:en"
+export LC_ALL="C.UTF-8"
+EOF
+
+ # Configure dpkg
+ if [ -e "${CHROOT}/etc/dpkg" ]
+ then
+
+cat > "${CHROOT}/etc/dpkg/dpkg.cfg.d/chroot" << EOF
+force-unsafe-io
+EOF
+
+ fi
+
+ if [ -e "${CHROOT}/sbin/start-stop-daemon" ]
+ then
+ mv "${CHROOT}/sbin/start-stop-daemon" "${CHROOT}/sbin/start-stop-daemon.orig"
+ fi
+
+cat > "${CHROOT}/sbin/start-stop-daemon" << EOF
+#!/bin/sh
+
+exit 0
+EOF
+
+ chmod 0755 "${CHROOT}/sbin/start-stop-daemon"
+
+ # Configure sysv-rc
+ if [ -e "${CHROOT}/usr/sbin/policy-rc.d" ]
+ then
+ mv "${CHROOT}/usr/sbin/policy-rc.d" "${CHROOT}/usr/sbin/policy-rc.d.orig"
+ fi
+
+cat > "${CHROOT}/usr/sbin/policy-rc.d" << EOF
+#!/bin/sh
+
+echo "All runlevel operations denied by policy" >&2
+
+exit 101
+EOF
+
+ chmod 0755 "${CHROOT}/usr/sbin/policy-rc.d"
+
+ # Configure debian
+ echo "${DISTRIBUTION}_${ARCHITECTURE}" > "${CHROOT}/etc/debian_chroot"
+
+ Chroot apt update
+ Chroot apt upgrade --yes
+ Chroot apt dist-upgrade --yes
+
+ Chroot apt install --yes \
+ build-essential debhelper fakeroot
+
+ Chroot apt install --yes \
+ gnupg sudo wget
+
+ Chroot apt install --yes \
+ git rsync ca-certificates wget
+
+ Chroot apt clean
+
+ echo "Root password"
+
+ Chroot "passwd"
+ Chroot "adduser --home /build --ingroup sudo build"
+
+ echo ". /etc/profile" >> "${CHROOT}/build/.bashrc"
+
+ case $(cat /etc/hostname) in
+ all*)
+ BASH_HISTORY="indep"
+ ;;
+
+ source*)
+ BASH_HISTORY="source"
+ ;;
+
+ *)
+ BASH_HISTORY="arch"
+ ;;
+ esac
+
+ case "${BASH_HISTORY}" in
+ arch)
+
+cat > "${CHROOT}/build/.bash_history" << EOF
+cd */ && sudo apt-get build-dep -y . && dpkg-buildpackage -B && cd .. && rm -rf */
+sudo apt-get install -y -t engywuck-backports debhelper
+clear && bbuild.sh -b binary-arch -d buster-backports -p
+rsync -aPv --progress --stats * apt.bfh.science::upload && rm -rf *
+EOF
+
+ ;;
+
+ indep)
+
+cat > "${CHROOT}/build/.bash_history" << EOF
+cd */ && sudo apt-get build-dep -y . && dpkg-buildpackage -A && cd .. && rm -rf */
+sudo apt-get install -y -t engywuck-backports debhelper
+clear && bbuild.sh -b binary-indep -d buster-backports -p
+rsync -aPv --progress --stats * apt.bfh.science::upload && rm -rf *
+EOF
+
+ ;;
+
+ source)
+
+cat > "${CHROOT}/build/.bash_history" << EOF
+cd */ && sudo apt-get build-dep -y . && dpkg-buildpackage -A && cd .. && rm -rf */
+sudo apt-get install -y -t engywuck-backports debhelper
+clear && bbuild.sh -b source -d buster-backports -p
+rsync -aPv --progress --stats * apt.bfh.science::upload && rm -rf *
+EOF
+
+ ;;
+ esac
+
+ chown 1000:1000 "${CHROOT}/build/.bash_history"
+
+ echo "build ALL=NOPASSWD: ALL" >> "${CHROOT}/etc/sudoers"
+ ;;
+
+ chroot)
+ Chroot "su - build"
+ ;;
+
+ update)
+ Chroot chmod 777 /dev/ptmx
+ Chroot apt-get --force-yes --yes update
+ Chroot apt-get --force-yes --yes upgrade
+ Chroot apt-get --force-yes --yes dist-upgrade
+ Chroot apt-get --force-yes --yes clean
+ ;;
+
+ save)
+ killall -9 syslogd > /dev/null 2>&1 || true
+ killall -9 klogd > /dev/null 2>&1 || true
+
+ for FILESYSTEM in /sys /proc /lib/init/rw /dev/shm /dev/pts /dev
+ do
+ umount -f "${CHROOT}/${FILESYSTEM}" > /dev/null 2>&1 || true
+ done
+
+ rm -f "${CHROOT}/root/.bash_history"
+ rm -f "${CHROOT}/root/.viminfo"
+ rm -f "${CHROOT}/build/.viminfo"
+ rm -rf "${CHROOT}/var/tmp/vi.recover"
+ rm -f "${CHROOT}/etc/machine-id"
+
+ case $(cat /etc/hostname) in
+ all*)
+ BASH_HISTORY="indep"
+ ;;
+
+ source*)
+ BASH_HISTORY="source"
+ ;;
+
+ *)
+ BASH_HISTORY="arch"
+ ;;
+ esac
+
+ case "${BASH_HISTORY}" in
+ arch)
+
+cat > "${CHROOT}/build/.bash_history" << EOF
+cd */ && sudo apt-get build-dep -y . && dpkg-buildpackage -B && cd .. && rm -rf */
+sudo apt-get install -y -t engywuck-backports debhelper
+clear && bbuild.sh -b binary-arch -d buster-backports -p
+rsync -aPv --progress --stats * apt.bfh.science::upload && rm -rf *
+EOF
+
+ ;;
+
+ indep)
+
+cat > "${CHROOT}/build/.bash_history" << EOF
+cd */ && sudo apt-get build-dep -y . && dpkg-buildpackage -A && cd .. && rm -rf */
+sudo apt-get install -y -t engywuck-backports debhelper
+clear && bbuild.sh -b binary-indep -d buster-backports -p
+rsync -aPv --progress --stats * apt.bfh.science::upload && rm -rf *
+EOF
+
+ ;;
+
+ source)
+
+cat > "${CHROOT}/build/.bash_history" << EOF
+cd */ && sudo apt-get build-dep -y . && dpkg-buildpackage -A && cd .. && rm -rf */
+sudo apt-get install -y -t engywuck-backports debhelper
+clear && bbuild.sh -b source -d buster-backports -p
+rsync -aPv --progress --stats * apt.bfh.science::upload && rm -rf *
+EOF
+ ;;
+ esac
+
+ rsync -av --delete "${CHROOT}"/ "${CHROOT}".orig
+
+ mount proc-$(basename ${CHROOT}) "${CHROOT}/proc" -t proc
+ mount devpts-$(basename ${CHROOT}) "${CHROOT}/dev/pts" -t devpts
+ mount sysfs-$(basename ${CHROOT}) "${CHROOT}/sys" -t sysfs
+ mount /dev/shm -o bind "${CHROOT}/dev/shm"
+ ;;
+
+ restore)
+ killall -9 syslogd > /dev/null 2>&1 || true
+ killall -9 klogd > /dev/null 2>&1 || true
+
+ for FILESYSTEM in /sys /proc /lib/init/rw /dev/shm /dev/pts /dev
+ do
+ umount -f "${CHROOT}/${FILESYSTEM}" > /dev/null 2>&1 || true
+ done
+
+ rsync -av --delete "${CHROOT}".orig/ "${CHROOT}"
+
+ mount proc-$(basename ${CHROOT}) "${CHROOT}/proc" -t proc
+ mount devpts-$(basename ${CHROOT}) "${CHROOT}/dev/pts" -t devpts
+ mount sysfs-$(basename ${CHROOT}) "${CHROOT}/sys" -t sysfs
+ mount /dev/shm -o bind "${CHROOT}/dev/shm"
+ ;;
+
+ reset)
+ "${0}" restore ${DISTRIBUTION} ${ARCHITECTURE}
+ "${0}" update ${DISTRIBUTION} ${ARCHITECTURE}
+ "${0}" save ${DISTRIBUTION} ${ARCHITECTURE}
+ ;;
+
+ *)
+ echo "Wrong option."
+ exit 1
+esac
diff --git a/bin/bget.sh b/bin/bget.sh
new file mode 120000
index 0000000..fc4cec2
--- /dev/null
+++ b/bin/bget.sh
@@ -0,0 +1 @@
+pget.sh \ No newline at end of file
diff --git a/bin/bimport.sh b/bin/bimport.sh
new file mode 120000
index 0000000..370f09d
--- /dev/null
+++ b/bin/bimport.sh
@@ -0,0 +1 @@
+pimport.sh \ No newline at end of file
diff --git a/bin/bmove.sh b/bin/bmove.sh
new file mode 120000
index 0000000..e028cc5
--- /dev/null
+++ b/bin/bmove.sh
@@ -0,0 +1 @@
+pmove.sh \ No newline at end of file
diff --git a/bin/bsign.sh b/bin/bsign.sh
new file mode 120000
index 0000000..fe89e1e
--- /dev/null
+++ b/bin/bsign.sh
@@ -0,0 +1 @@
+psign.sh \ No newline at end of file
diff --git a/bin/bupdate.sh b/bin/bupdate.sh
new file mode 120000
index 0000000..5adb2ce
--- /dev/null
+++ b/bin/bupdate.sh
@@ -0,0 +1 @@
+pupdate.sh \ No newline at end of file
diff --git a/bin/bupload.sh b/bin/bupload.sh
new file mode 120000
index 0000000..9afb543
--- /dev/null
+++ b/bin/bupload.sh
@@ -0,0 +1 @@
+pupload.sh \ No newline at end of file
diff --git a/bin/clean_challenge.nsupdate.sh b/bin/clean_challenge.nsupdate.sh
new file mode 100755
index 0000000..05ffb40
--- /dev/null
+++ b/bin/clean_challenge.nsupdate.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+set -e
+
+NAMESERVERS="$(kdig -4 +short @ns.bfh.science ns.bfh.science)"
+ZONE="$(cat /etc/hostname | awk -F. '{ print $(NF-1) "." $NF}')"
+
+for NAMESERVER in ${NAMESERVERS}
+do
+ echo -n " + Deleting TXT record (_acme-challenge.${DOMAIN})..."
+
+ NSUPDATE="$(mktemp nsupdate.XXXX)"
+
+cat > "${NSUPDATE}" << EOF
+server ${NAMESERVER}
+zone ${ZONE}
+ttl 300
+update delete _acme-challenge.${DOMAIN} 300 TXT ${TOKEN_VALUE}
+send
+EOF
+
+ knsupdate "${NSUPDATE}"
+ rm -f "${NSUPDATE}"
+
+ echo " done."
+done
diff --git a/bin/debian-chroot b/bin/debian-chroot
new file mode 100755
index 0000000..9251244
--- /dev/null
+++ b/bin/debian-chroot
@@ -0,0 +1,367 @@
+#!/bin/sh
+
+set -e
+
+COMMAND="${1:-enter}"
+
+if [ -n "${2}" ]
+then
+ DISTRIBUTION="$(echo ${2} | awk -F- '{ print $1 }')"
+else
+ DISTRIBUTION="${2:-sid}"
+fi
+
+if [ -n "${3}" ]
+then
+ ARCHITECTURE="${3:-$(dpkg --print-architecture)}"
+else
+ ARCHITECTURE="$(echo ${2} | awk -F- '{ print $2 }')"
+ ARCHITECTURE="${ARCHITECTURE:-amd64}"
+fi
+
+case "${DISTRIBUTION}" in
+ buster*)
+ DERIVATIVE_DISTRIBUTION="engywuck"
+ ;;
+
+ bullseye*)
+ DERIVATIVE_DISTRIBUTION="fuchur"
+ ;;
+esac
+
+MIRROR="debian.ethz.ch"
+
+CHROOT="/srv/chroots/${DISTRIBUTION}-${ARCHITECTURE}"
+
+Chroot ()
+{
+ if [ "${ARCHITECTURE}" = "$(dpkg --print-architecture)" ]
+ then
+ chroot "${CHROOT}" /usr/bin/env -i HOME="/root" PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" TERM="${TERM}" ${@}
+ else
+ linux32 chroot "${CHROOT}" /usr/bin/env -i HOME="/root" PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" TERM="${TERM}" ${@}
+ fi
+}
+
+case "${COMMAND}" in
+ create)
+ if [ ! -d "${CHROOT}" ]
+ then
+ debootstrap --arch=${ARCHITECTURE} --include=progress-linux ${DISTRIBUTION} "${CHROOT}" http://${MIRROR}/debian
+ else
+ echo "${CHROOT}: file or directory already exists."
+ exit 1
+ fi
+
+ # Configure apt
+
+cat > "${CHROOT}/etc/apt/apt.conf.d/chroot.conf" << EOF
+Acquire::PDiffs "false";
+APT::Clean-Installed "true";
+APT::Install-Recommends "false";
+APT::Install-Suggests "false";
+EOF
+
+cat > "${CHROOT}/etc/apt/sources.list" << EOF
+deb http://${MIRROR}/debian ${DISTRIBUTION} main contrib non-free
+EOF
+
+ case "${DISTRIBUTION}" in
+ sid*)
+
+cat >> "${CHROOT}/etc/apt/sources.list" << EOF
+deb http://${MIRROR}/debian experimental main contrib non-free
+EOF
+
+ ;;
+
+ buster*)
+
+cat > "${CHROOT}/etc/apt/sources.list.d/progress-linux.sources" << EOF
+Types: deb
+URIs: https://deb.progress-linux.org/packages
+Suites: ${DERIVATIVE_DISTRIBUTION}-backports
+Components: main contrib non-free restricted
+PDiffs: no
+Signed-By: /usr/share/progress-linux/pgp-keys/apt.progress-linux.org.gpg
+EOF
+
+ ;;
+
+ bullseye*)
+
+cat > "${CHROOT}/etc/apt/sources.list.d/progress-linux.sources" << EOF
+Types: deb
+URIs: https://deb.progress-linux.org/packages
+Suites: ${DERIVATIVE_DISTRIBUTION}-backports
+Components: main contrib non-free restricted
+PDiffs: no
+Signed-By: /usr/share/progress-linux/pgp-keys/apt.progress-linux.org.gpg
+EOF
+
+ ;;
+ esac
+
+ # Configure bash
+
+cat > "${CHROOT}/etc/profile.d/chroot.sh" << EOF
+#!/bin/sh
+
+alias ls="ls --color=auto"
+
+export DEBEMAIL="maintainers@lists.progress-linux.org"
+export DEBFULLNAME="Progress Linux Maintainers"
+
+export LANG="en_US.UTF-8"
+export LANGUAGE="en_US:en"
+export LC_ALL="C.UTF-8"
+EOF
+
+ # Configure dpkg
+ if [ -e "${CHROOT}/etc/dpkg" ]
+ then
+
+cat > "${CHROOT}/etc/dpkg/dpkg.cfg.d/chroot" << EOF
+force-unsafe-io
+EOF
+
+ fi
+
+ if [ -e "${CHROOT}/sbin/start-stop-daemon" ]
+ then
+ mv "${CHROOT}/sbin/start-stop-daemon" "${CHROOT}/sbin/start-stop-daemon.orig"
+ fi
+
+cat > "${CHROOT}/sbin/start-stop-daemon" << EOF
+#!/bin/sh
+
+exit 0
+EOF
+
+ chmod 0755 "${CHROOT}/sbin/start-stop-daemon"
+
+ # Configure sysv-rc
+ if [ -e "${CHROOT}/usr/sbin/policy-rc.d" ]
+ then
+ mv "${CHROOT}/usr/sbin/policy-rc.d" "${CHROOT}/usr/sbin/policy-rc.d.orig"
+ fi
+
+cat > "${CHROOT}/usr/sbin/policy-rc.d" << EOF
+#!/bin/sh
+
+echo "All runlevel operations denied by policy" >&2
+
+exit 101
+EOF
+
+ chmod 0755 "${CHROOT}/usr/sbin/policy-rc.d"
+
+ # Configure debian
+ echo "${DISTRIBUTION}_${ARCHITECTURE}" > "${CHROOT}/etc/debian_chroot"
+
+ Chroot apt update
+ Chroot apt upgrade --yes
+ Chroot apt dist-upgrade --yes
+
+ Chroot apt install --yes \
+ build-essential debhelper fakeroot
+
+ Chroot apt install --yes \
+ gnupg sudo wget
+
+ Chroot apt install --yes \
+ git rsync ca-certificates wget
+
+ Chroot apt clean
+
+ echo "Root password"
+
+ Chroot "passwd"
+ Chroot "adduser --home /build --ingroup sudo build"
+
+ echo ". /etc/profile" >> "${CHROOT}/build/.bashrc"
+
+ case $(cat /etc/hostname) in
+ all*)
+ BASH_HISTORY="indep"
+ ;;
+
+ source*)
+ BASH_HISTORY="source"
+ ;;
+
+ *)
+ BASH_HISTORY="arch"
+ ;;
+ esac
+
+ case "${BASH_HISTORY}" in
+ arch)
+
+cat > "${CHROOT}/build/.bash_history" << EOF
+cd */ && sudo apt-get build-dep -y . && dpkg-buildpackage -B && cd .. && rm -rf */
+sudo apt-get install -y -t ${DERIVATIVE_DISTRIBUTION}-backports debhelper
+clear && pbuild.sh -b binary-arch -d ${DERIVATIVE_DISTRIBUTION}-backports -p
+rsync -aPv --progress --stats * apt.progress-linux.org::upload && rm -rf *
+EOF
+
+ ;;
+
+ indep)
+
+cat > "${CHROOT}/build/.bash_history" << EOF
+cd */ && sudo apt-get build-dep -y . && dpkg-buildpackage -A && cd .. && rm -rf */
+sudo apt-get install -y -t ${DERIVATIVE_DISTRIBUTION}-backports debhelper
+clear && pbuild.sh -b binary-indep -d ${DERIVATIVE_DISTRIBUTION}-backports -p
+rsync -aPv --progress --stats * apt.progress-linux.org::upload && rm -rf *
+EOF
+
+ ;;
+
+ source)
+
+cat > "${CHROOT}/build/.bash_history" << EOF
+cd */ && sudo apt-get build-dep -y . && dpkg-buildpackage -A && cd .. && rm -rf */
+sudo apt-get install -y -t ${DERIVATIVE_DISTRIBUTION}-backports debhelper
+clear && pbuild.sh -b source -d ${DERIVATIVE_DISTRIBUTION}-backports -p
+rsync -aPv --progress --stats * apt.progress-linux.org::upload && rm -rf *
+EOF
+
+ ;;
+ esac
+
+ case "${DISTRIBUTION}" in
+ sid)
+
+cat >> "${CHROOT}/build/.bash_history" << EOF
+dpkg-buildpackage --changes-option=-S
+EOF
+
+ ;;
+ esac
+
+ chown 1000:1000 "${CHROOT}/build/.bash_history"
+
+ echo "build ALL=NOPASSWD: ALL" >> "${CHROOT}/etc/sudoers"
+ ;;
+
+ chroot)
+ Chroot "su - build"
+ ;;
+
+ update)
+ Chroot chmod 777 /dev/ptmx
+ Chroot apt-get --force-yes --yes update
+ Chroot apt-get --force-yes --yes upgrade
+ Chroot apt-get --force-yes --yes dist-upgrade
+ Chroot apt-get --force-yes --yes clean
+ ;;
+
+ save)
+ killall -9 syslogd > /dev/null 2>&1 || true
+ killall -9 klogd > /dev/null 2>&1 || true
+
+ for FILESYSTEM in /sys /proc /lib/init/rw /dev/shm /dev/pts /dev
+ do
+ umount -f "${CHROOT}/${FILESYSTEM}" > /dev/null 2>&1 || true
+ done
+
+ rm -f "${CHROOT}/root/.bash_history"
+ rm -f "${CHROOT}/root/.viminfo"
+ rm -f "${CHROOT}/build/.viminfo"
+ rm -rf "${CHROOT}/var/tmp/vi.recover"
+ rm -f "${CHROOT}/etc/machine-id"
+
+ case $(cat /etc/hostname) in
+ all*)
+ BASH_HISTORY="indep"
+ ;;
+
+ source*)
+ BASH_HISTORY="source"
+ ;;
+
+ *)
+ BASH_HISTORY="arch"
+ ;;
+ esac
+
+ case "${BASH_HISTORY}" in
+ arch)
+
+cat > "${CHROOT}/build/.bash_history" << EOF
+cd */ && sudo apt-get build-dep -y . && dpkg-buildpackage -B && cd .. && rm -rf */
+sudo apt-get install -y -t ${DERIVATIVE_DISTRIBUTION}-backports debhelper
+clear && pbuild.sh -b binary-arch -d ${DERIVATIVE_DISTRIBUTION}-backports -p
+rsync -aPv --progress --stats * apt.progress-linux.org::upload && rm -rf *
+EOF
+
+ ;;
+
+ indep)
+
+cat > "${CHROOT}/build/.bash_history" << EOF
+cd */ && sudo apt-get build-dep -y . && dpkg-buildpackage -A && cd .. && rm -rf */
+sudo apt-get install -y -t ${DERIVATIVE_DISTRIBUTION}-backports debhelper
+clear && pbuild.sh -b binary-indep -d ${DERIVATIVE_DISTRIBUTION}-backports -p
+rsync -aPv --progress --stats * apt.progress-linux.org::upload && rm -rf *
+EOF
+
+ ;;
+
+ source)
+
+cat > "${CHROOT}/build/.bash_history" << EOF
+cd */ && sudo apt-get build-dep -y . && dpkg-buildpackage -A && cd .. && rm -rf */
+sudo apt-get install -y -t ${DERIVATIVE_DISTRIBUTION}-backports debhelper
+clear && pbuild.sh -b source -d ${DERIVATIVE_DISTRIBUTION}-backports -p
+rsync -aPv --progress --stats * apt.progress-linux.org::upload && rm -rf *
+EOF
+ ;;
+ esac
+
+ case "${DISTRIBUTION}" in
+ sid)
+
+cat >> "${CHROOT}/build/.bash_history" << EOF
+dpkg-buildpackage --changes-option=-S
+EOF
+
+ ;;
+ esac
+
+ rsync -av --delete "${CHROOT}"/ "${CHROOT}".orig
+
+ mount proc-$(basename ${CHROOT}) "${CHROOT}/proc" -t proc
+ mount devpts-$(basename ${CHROOT}) "${CHROOT}/dev/pts" -t devpts
+ mount sysfs-$(basename ${CHROOT}) "${CHROOT}/sys" -t sysfs
+ mount /dev/shm -o bind "${CHROOT}/dev/shm"
+ ;;
+
+ restore)
+ killall -9 syslogd > /dev/null 2>&1 || true
+ killall -9 klogd > /dev/null 2>&1 || true
+
+ for FILESYSTEM in /sys /proc /lib/init/rw /dev/shm /dev/pts /dev
+ do
+ umount -f "${CHROOT}/${FILESYSTEM}" > /dev/null 2>&1 || true
+ done
+
+ rsync -av --delete "${CHROOT}".orig/ "${CHROOT}"
+
+ mount proc-$(basename ${CHROOT}) "${CHROOT}/proc" -t proc
+ mount devpts-$(basename ${CHROOT}) "${CHROOT}/dev/pts" -t devpts
+ mount sysfs-$(basename ${CHROOT}) "${CHROOT}/sys" -t sysfs
+ mount /dev/shm -o bind "${CHROOT}/dev/shm"
+ ;;
+
+ reset)
+ "${0}" restore ${DISTRIBUTION} ${ARCHITECTURE}
+ "${0}" update ${DISTRIBUTION} ${ARCHITECTURE}
+ "${0}" save ${DISTRIBUTION} ${ARCHITECTURE}
+ ;;
+
+ *)
+ echo "Wrong option."
+ exit 1
+esac
diff --git a/bin/debian-patches-apply b/bin/debian-patches-apply
new file mode 100755
index 0000000..a1920eb
--- /dev/null
+++ b/bin/debian-patches-apply
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+if [ -e patches/series ] && [ "$(basename ${PWD})" = "debian" ]
+then
+ cd ..
+fi
+
+if [ -e debian/patches/series ]
+then
+ for PATCH in $(grep -v '^#' debian/patches/series)
+ do
+ echo -n "${PATCH}:"
+
+ patch -Np1 -s -i "debian/patches/${PATCH}" > /dev/null 2>&1
+
+ case "${?}" in
+ 0)
+ echo " Ok"
+ ;;
+
+ *)
+ echo " Failed"
+ ;;
+ esac
+ done
+else
+ echo "package does not have patches"
+fi
diff --git a/bin/debian-patches-test b/bin/debian-patches-test
new file mode 100755
index 0000000..18aea57
--- /dev/null
+++ b/bin/debian-patches-test
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+if [ -e patches/series ] && [ "$(basename ${PWD})" = "debian" ]
+then
+ cd ..
+fi
+
+if [ -e debian/patches/series ]
+then
+ for PATCH in $(grep -v '^#' debian/patches/series)
+ do
+ echo -n "${PATCH}:"
+
+ patch -Np1 -s -i "debian/patches/${PATCH}" --dry-run > /dev/null 2>&1
+
+ case "${?}" in
+ 0)
+ echo " Ok"
+ ;;
+
+ *)
+ echo " Failed"
+ ;;
+ esac
+ done
+else
+ echo "package does not have patches"
+fi
diff --git a/bin/debian-patches-unapply b/bin/debian-patches-unapply
new file mode 100755
index 0000000..fc7f204
--- /dev/null
+++ b/bin/debian-patches-unapply
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+if [ -e patches/series ] && [ "$(basename ${PWD})" = "debian" ]
+then
+ cd ..
+fi
+
+if [ -e debian/patches/series ]
+then
+ for PATCH in $(grep -v '^#' debian/patches/series | reverse)
+ do
+ echo -n "${PATCH}:"
+
+ patch -Np1 -R -s -i "debian/patches/${PATCH}" > /dev/null 2>&1
+
+ case "${?}" in
+ 0)
+ echo " Ok"
+ ;;
+
+ *)
+ echo " Failed"
+ ;;
+ esac
+ done
+else
+ echo "package does not have patches"
+fi
diff --git a/bin/debian-sponsor.sh b/bin/debian-sponsor.sh
new file mode 100755
index 0000000..17191f5
--- /dev/null
+++ b/bin/debian-sponsor.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+
+set -e
+
+DSC="${1}"
+
+case "${DSC}" in
+ *.dsc)
+ ;;
+
+ *)
+ echo "Usage: ${0} DSC"
+ ;;
+esac
+
+SOURCE="$(basename ${DSC} | awk -F_ '{ print $1 }')"
+
+# Download sources
+mkdir -p NEW OLD
+
+cd NEW
+DGET_VERIFY=no dget --insecure -u -d "${DSC}"
+cd "${OLDPWD}"
+
+cd OLD
+apt source --only-source --download-only ${SOURCE}
+cd "${OLDPWD}"
+
+# Compare upstream tarballs
+if [ -e NEW/$(basename OLD/*.orig.tar.*) ]
+then
+ OLD_MD5="$(md5sum OLD/*.orig.tar.* | awk '{ print $1 }')"
+ NEW_MD5="$(md5sum OLD/*.orig.tar.* | awk '{ print $1 }')"
+
+ if [ "${OLD_MD5}" != "${NEW_MD5}" ]
+ then
+ echo "E: upstream tarballs do not match!"
+ echo "E: new version?"
+ fi
+fi
+
+# Unpack upstream
+cd NEW
+dpkg-source -x --skip-debianization *.dsc ${SOURCE}
+cd "${OLDPWD}"
+
+cd OLD
+dpkg-source -x --skip-debianization *.dsc ${SOURCE}
+cd "${OLDPWD}"
+
+# Compare upstream
+set +e
+diff -Naurp OLD/${SOURCE} NEW/${SOURCE} > upstream.diff
+set -e
+
+# Unpack debian
+cd "NEW/${SOURCE}"
+tar xf ../*debian.tar.*
+cd "${OLDPWD}"
+
+cd "OLD/${SOURCE}"
+tar xf ../*debian.tar.*
+cd "${OLDPWD}"
+
+# Compare debian
+set +e
+diff -Naurp OLD/${SOURCE}/debian NEW/${SOURCE}/debian > debian.diff
+set -e
diff --git a/bin/debsign.sh b/bin/debsign.sh
new file mode 100755
index 0000000..af334c8
--- /dev/null
+++ b/bin/debsign.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+
+set -e
+
+for CHANGES in *.changes
+do
+ if [ ! -e "${CHANGES}" ]
+ then
+ continue
+ fi
+
+ DISTRIBUTION="$(grep -m1 '^Distribution: ' ${CHANGES} | awk '{ print $2 }')"
+
+ case "${DISTRIBUTION}" in
+ artax|artax-security|artax-updates|artax-lts|artax-extras)
+ DESCRIPTION="Progress Linux 1 (artax) Archive Key"
+ KEY="F5BE3737078C3235"
+ ;;
+
+ artax-backports*)
+ DESCRIPTION="Progress Linux 1+ (artax-backports) Archive Key"
+ KEY="3C39F3949268F7A7"
+ ;;
+
+ baureo|baureo-security|baureo-updates|baureo-lts|baureo-extras)
+ DESCRIPTION="Progress Linux 2 (baureo) Archive Key"
+ KEY="36B53C8861FD101F"
+ ;;
+
+ baureo-backports*)
+ DESCRIPTION="Progress Linux 2+ (baureo-backports) Archive Key"
+ KEY="03DB4D28C21BF7BD"
+ ;;
+
+ cairon|cairon-security|cairon-updates|cairon-lts|cairon-extras)
+ DESCRIPTION="Progress Linux 3 (cairon) Archive Key"
+ KEY="D55976A2ABDC1FDE"
+ ;;
+
+ cairon-backports*)
+ DESCRIPTION="Progress Linux 3+ (cairon-backports) Archive Key"
+ KEY="65D1668551C0BCFC"
+ ;;
+
+ dschinn*)
+ DESCRIPTION="Progress Linux 4 (dschinn) Archive Key"
+ KEY="C77F83EA"
+ ;;
+
+ *)
+ # Debian
+ DESCRIPTION="Daniel Baumann (2014) Key"
+ KEY="55CF1BF986ABB9C7"
+ ;;
+ esac
+
+ # FIXME: BFH
+
+ DSC="$(echo ${FILE} | sed -e 's|.changes$|.dsc|')"
+
+ if [ -e "${DSC}" ]
+ then
+ echo "Signing ${DSC} with: ${DESCRIPTION}"
+ debsign -k${KEY} --re-sign ${DSC}
+ fi
+
+ echo "Signing ${CHANGES} with: ${DESCRIPTION}"
+ debsign -k${KEY} --re-sign ${CHANGES}
+done
diff --git a/bin/dehydrated-cron b/bin/dehydrated-cron
new file mode 100755
index 0000000..bd3bcf5
--- /dev/null
+++ b/bin/dehydrated-cron
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+set -e
+
+dehydrated -c
+dehydrated -gc
+rm -f /var/lib/dehydrated/archive/*
diff --git a/bin/dehydrated-hook.d b/bin/dehydrated-hook.d
new file mode 100755
index 0000000..62095e5
--- /dev/null
+++ b/bin/dehydrated-hook.d
@@ -0,0 +1,297 @@
+#!/bin/sh
+HOOKS_DIR="/etc/dehydrated/hook.d"
+
+deploy_challenge ()
+{
+ local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}"
+
+ # This hook is called once for every domain that needs to be
+ # validated, including any alternative names you may have listed.
+ #
+ # Parameters:
+ # - DOMAIN
+ # The domain name (CN or subject alternative name) being
+ # validated.
+ # - TOKEN_FILENAME
+ # The name of the file containing the token to be served for HTTP
+ # validation. Should be served by your web server as
+ # /.well-known/acme-challenge/${TOKEN_FILENAME}.
+ # - TOKEN_VALUE
+ # The token value that needs to be served for validation. For DNS
+ # validation, this is what you want to put in the _acme-challenge
+ # TXT record. For HTTP validation it is the value that is expected
+ # be found in the $TOKEN_FILENAME file.
+
+ export DOMAIN
+ export TOKEN_FILENAME
+ export TOKEN_VALUE
+ run-parts --regex '^deploy_challenge.*.sh$' ${HOOKS_DIR}
+ unset DOMAIN
+ unset TOKEN_FILENAME
+ unset TOKEN_VALUE
+}
+
+clean_challenge ()
+{
+ local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}"
+
+ # This hook is called after attempting to validate each domain,
+ # whether or not validation was successful. Here you can delete
+ # files or DNS records that are no longer needed.
+ #
+ # The parameters are the same as for deploy_challenge.
+
+ export DOMAIN
+ export TOKEN_FILENAME
+ export TOKEN_VALUE
+ run-parts --regex '^clean_challenge.*.sh$' ${HOOKS_DIR}
+ unset DOMAIN
+ unset TOKEN_FILENAME
+ unset TOKEN_VALUE
+}
+
+sync_cert ()
+{
+ local KEYFILE="${1}" CERTFILE="${2}" FULLCHAINFILE="${3}" CHAINFILE="${4}" REQUESTFILE="${5}"
+
+ # This hook is called after the certificates have been created but before
+ # they are symlinked. This allows you to sync the files to disk to prevent
+ # creating a symlink to empty files on unexpected system crashes.
+ #
+ # This hook is not intended to be used for further processing of certificate
+ # files, see deploy_cert for that.
+ #
+ # Parameters:
+ # - KEYFILE
+ # The path of the file containing the private key.
+ # - CERTFILE
+ # The path of the file containing the signed certificate.
+ # - FULLCHAINFILE
+ # The path of the file containing the full certificate chain.
+ # - CHAINFILE
+ # The path of the file containing the intermediate certificate(s).
+ # - REQUESTFILE
+ # The path of the file containing the certificate signing request.
+
+ export KEYFILE
+ export CERTFILE
+ export FULLCHAINFILE
+ export CHAINFILE
+ export REQUESTFILE
+ run-parts --regex '^sync_cert.*.sh$' ${HOOKS_DIR}
+ unset KEYFILE
+ unset CERTFILE
+ unset FULLCHAINFILE
+ unset CHAINFILE
+ unset REQUESTFILE
+}
+
+deploy_cert ()
+{
+ local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}" TIMESTAMP="${6}"
+
+ # This hook is called once for each certificate that has been
+ # produced. Here you might, for instance, copy your new certificates
+ # to service-specific locations and reload the service.
+ #
+ # Parameters:
+ # - DOMAIN
+ # The primary domain name, i.e. the certificate common
+ # name (CN).
+ # - KEYFILE
+ # The path of the file containing the private key.
+ # - CERTFILE
+ # The path of the file containing the signed certificate.
+ # - FULLCHAINFILE
+ # The path of the file containing the full certificate chain.
+ # - CHAINFILE
+ # The path of the file containing the intermediate certificate(s).
+ # - TIMESTAMP
+ # Timestamp when the specified certificate was created.
+
+ export DOMAIN
+ export KEYFILE
+ export CERTFILE
+ export FULLCHAINFILE
+ export CHAINFILE
+ export TIMESTAMP
+ run-parts --regex '^deploy_cert.*.sh$' ${HOOKS_DIR}
+ unset DOMAIN
+ unset CERTFILE
+ unset FULLCHAINFILE
+ unset CHAINFILE
+ unset TIMESTAMP
+}
+
+deploy_ocsp ()
+{
+ local DOMAIN="${1}" OCSPFILE="${2}" TIMESTAMP="${3}"
+
+ # This hook is called once for each updated ocsp stapling file that has
+ # been produced. Here you might, for instance, copy your new ocsp stapling
+ # files to service-specific locations and reload the service.
+ #
+ # Parameters:
+ # - DOMAIN
+ # The primary domain name, i.e. the certificate common
+ # name (CN).
+ # - OCSPFILE
+ # The path of the ocsp stapling file
+ # - TIMESTAMP
+ # Timestamp when the specified ocsp stapling file was created.
+
+ export DOMAIN
+ export OCSPFILE
+ export TIMESTAMP
+ run-parts --regex '^deploy_ocsp.*.sh$' ${HOOKS_DIR}
+ unset DOMAIN
+ unset OCSPFILE
+ unset TIMESTAMP
+}
+
+unchanged_cert ()
+{
+ local DOMAIN="${1}" KEYFILE="${2}" CERTFILE="${3}" FULLCHAINFILE="${4}" CHAINFILE="${5}"
+
+ # This hook is called once for each certificate that is still
+ # valid and therefore wasn't reissued.
+ #
+ # Parameters:
+ # - DOMAIN
+ # The primary domain name, i.e. the certificate common
+ # name (CN).
+ # - KEYFILE
+ # The path of the file containing the private key.
+ # - CERTFILE
+ # The path of the file containing the signed certificate.
+ # - FULLCHAINFILE
+ # The path of the file containing the full certificate chain.
+ # - CHAINFILE
+ # The path of the file containing the intermediate certificate(s).
+
+ export DOMAIN
+ export KEYFILE
+ export CERTFILE
+ export FULLCHAINFILE
+ export CHAINFILE
+ run-parts --regex '^unchanged_cert.*.sh$' ${HOOKS_DIR}
+ unset DOMAIN
+ unset CERTFILE
+ unset FULLCHAINFILE
+ unset CHAINFILE
+}
+
+invalid_challenge ()
+{
+ local DOMAIN="${1}" RESPONSE="${2}"
+
+ # This hook is called if the challenge response has failed, so domain
+ # owners can be aware and act accordingly.
+ #
+ # Parameters:
+ # - DOMAIN
+ # The primary domain name, i.e. the certificate common
+ # name (CN).
+ # - RESPONSE
+ # The response that the verification server returned
+
+ # Simple example: Send mail to root
+ # printf "Subject: Validation of ${DOMAIN} failed!\n\nOh noez!" | sendmail root
+ export DOMAIN
+ export RESPONSE
+ run-parts --regex '^invalid_challenge.*.sh$' ${HOOKS_DIR}
+ unset DOMAIN
+ unset RESPONSE
+}
+
+request_failure ()
+{
+ local STATUSCODE="${1}" REASON="${2}" REQTYPE="${3}" HEADERS="${4}"
+
+ # This hook is called when an HTTP request fails (e.g., when the ACME
+ # server is busy, returns an error, etc). It will be called upon any
+ # response code that does not start with '2'. Useful to alert admins
+ # about problems with requests.
+ #
+ # Parameters:
+ # - STATUSCODE
+ # The HTML status code that originated the error.
+ # - REASON
+ # The specified reason for the error.
+ # - REQTYPE
+ # The kind of request that was made (GET, POST...)
+ # - HEADERS
+ # HTTP headers returned by the CA
+
+ export STATUSCODE
+ export REASON
+ export REQTYPE
+ export HEADERS
+ run-parts --regex '^request_failure.*.sh$' ${HOOKS_DIR}
+ unset STATUSCODE
+ unset REASON
+ unset REQTYPE
+ unset HEADERS
+}
+
+generate_csr ()
+{
+ local DOMAIN="${1}" CERTDIR="${2}" ALTNAMES="${3}"
+
+ # This hook is called before any certificate signing operation takes place.
+ # It can be used to generate or fetch a certificate signing request with external
+ # tools.
+ # The output should be just the cerificate signing request formatted as PEM.
+ #
+ # Parameters:
+ # - DOMAIN
+ # The primary domain as specified in domains.txt. This does not need to
+ # match with the domains in the CSR, it's basically just the directory name.
+ # - CERTDIR
+ # Certificate output directory for this particular certificate. Can be used
+ # for storing additional files.
+ # - ALTNAMES
+ # All domain names for the current certificate as specified in domains.txt.
+ # Again, this doesn't need to match with the CSR, it's just there for convenience.
+
+ # Simple example: Look for pre-generated CSRs
+ # if [ -e "${CERTDIR}/pre-generated.csr" ]; then
+ # cat "${CERTDIR}/pre-generated.csr"
+ # fi
+ export DOMAIN
+ export CERTDIR
+ export ALTNAMES
+ run-parts --regex '^generate_csr.*.sh$' ${HOOKS_DIR}
+ unset DOMAIN
+ unset CERTDIR
+ unset ALTNAMES
+}
+
+startup_hook ()
+{
+ # This hook is called before the cron command to do some initial tasks
+ # (e.g. starting a webserver).
+
+ run-parts --regex '^startup.*.sh$' ${HOOKS_DIR}
+}
+
+exit_hook ()
+{
+ local ERROR="${1:-}"
+
+ # This hook is called at the end of the cron command and can be used to
+ # do some final (cleanup or other) tasks.
+ #
+ # Parameters:
+ # - ERROR
+ # Contains error message if dehydrated exits with error
+ export ERROR
+ run-parts --regex '^exit_hook.*.sh$' ${HOOKS_DIR}
+ unset ERROR
+}
+
+HANDLER="$1"; shift
+if echo "${HANDLER}" | grep -o -E '^(deploy_challenge|clean_challenge|sync_cert|deploy_cert|deploy_ocsp|unchanged_cert|invalid_challenge|request_failure|generate_csr|startup_hook|exit_hook)$'
+then
+ "$HANDLER" "$@"
+fi
diff --git a/bin/dehydrated-knotupdate b/bin/dehydrated-knotupdate
new file mode 100755
index 0000000..1a56f80
--- /dev/null
+++ b/bin/dehydrated-knotupdate
@@ -0,0 +1,83 @@
+#!/bin/bash
+
+#
+# Example how to deploy a DNS challenge using nsupdate
+#
+# https://github.com/lukas2511/dehydrated/wiki/example-dns-01-nsupdate-script
+# slightly modified by kdrexel
+
+# example:
+#update add monitor2-test.bfh.host 7200 TXT "if-you-can-dig-it-everything-works-fine"
+#printf "server %s\nzone %s.\nttl %d\nupdate add _acme-challenge.%s. %d TXT \"%s\"\nsend\n" "${DNSSERVER}" "${ZONE}" "${TTL}" "${2}" "${TTL}" "${CHALLENGE}" | $NSUPDATE
+
+set -e
+set -u
+set -o pipefail
+
+if [ $# -lt 3 ]; then
+ logger "$0 called with too few ARGS: $@"
+ exit 42
+fi
+
+# Params from hook.sh
+DOMAIN="$2"
+CHALLENGE="$3"
+
+ZONE=$(cat /etc/hostname |awk -F '.' '{ print $(NF-1),$NF}'| sed -e 's/ /./')
+NSUPDATE="knsupdate"
+#NSUPDATE="nsupdate -k /path/to/Kdnsupdatekey.private" #bind only
+DNSSERVER=$(kdig -4 @ns.bfh.science ns.bfh.science +short)
+
+TTL=300
+
+case "$1" in
+ "deploy_challenge")
+ for NS in $DNSSERVER
+ do
+ TEMPFILE=$(tempfile -s -dehydrated)
+ cat << EOF >> $TEMPFILE
+server $NS
+zone ${ZONE}.
+ttl $TTL
+update add _acme-challenge.${DOMAIN} $TTL TXT $CHALLENGE
+send
+EOF
+ $NSUPDATE $TEMPFILE
+ done
+ ;;
+
+ "clean_challenge")
+ for NS in $DNSSERVER
+ do
+ TEMPFILE=$(tempfile -s -dehydrated-del)
+ cat << EOF >> $TEMPFILE
+server $NS
+zone ${ZONE}.
+ttl $TTL
+update delete _acme-challenge.${DOMAIN} $TTL TXT $CHALLENGE
+send
+EOF
+ if [ -t 1 ]
+ then
+ echo "Deleting TXT Record _acme-challenge.${DOMAIN}..."
+ fi
+ sleep 10
+ $NSUPDATE $TEMPFILE
+ done
+ ;;
+ "deploy_cert")
+ # optional:
+ # /path/to/deploy_cert.sh "$@"
+ ;;
+ "unchanged_cert")
+ # do nothing for now
+ ;;
+ "startup_hook")
+ # do nothing for now
+ ;;
+ "exit_hook")
+ # do nothing for now
+ ;;
+esac
+
+exit 0
diff --git a/bin/deploy_cert.fullchain-privkey.sh b/bin/deploy_cert.fullchain-privkey.sh
new file mode 100755
index 0000000..9946281
--- /dev/null
+++ b/bin/deploy_cert.fullchain-privkey.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+set -e
+
+DIRECTORY="$(dirname ${FULLCHAINFILE})"
+FILE="cert.fullchain-privkey-${TIMESTAMP}.pem"
+
+cat "${FULLCHAINFILE}" "${KEYFILE}" > "${DIRECTORY}/${FILE}"
+ln -sf "${FILE}" "${DIRECTORY}/cert.fullchain-privkey.pem"
diff --git a/bin/deploy_cert.slapd.sh b/bin/deploy_cert.slapd.sh
new file mode 100755
index 0000000..e40060d
--- /dev/null
+++ b/bin/deploy_cert.slapd.sh
@@ -0,0 +1,78 @@
+#!/bin/sh
+
+set -e
+
+#CA_FROM_INTERNET="TRUE"
+CA_LINK_FILE_NAME="ca"
+CA_CHAIN_NAME="cachain"
+CERT_PATH="$(dirname ${CHAINFILE})"
+CA_LINK_FILE="${CERT_PATH}/${CA_LINK_FILE_NAME}.pem"
+
+Ca_from_internet ()
+{
+ echo "Downloading CA file from internet!"
+
+ ISSUER_URL="$(openssl x509 -in "${CHAINFILE}" -noout -text | grep 'CA Issuers' | cut -d ':' -f 2-)"
+ TEMPDIR="$(mktemp -d /tmp/dehydrated-hook.XXXX)"
+
+ wget --quiet "${ISSUER_URL}" -O "${TEMPDIR}/${CA_LINK_FILE_NAME}"
+
+ if openssl x509 -in "${TEMPDIR}/${CA_LINK_FILE_NAME}" -text > /dev/null 2>&1
+ then
+ echo "Root certificate format is text PEM"
+ /usr/bin/mv "${TEMPDIR}/${CA_LINK_FILE_NAME}" "${CA_LINK_FILE}.new"
+ elif openssl x509 -inform DER -in "${TEMPDIR}/${CA_LINK_FILE_NAME}" -text > /dev/null 2>&1
+ then
+ echo "Root certificate format is binary DER"
+ openssl x509 -in "${TEMPDIR}/${CA_LINK_FILE_NAME}" -inform DER -out "${CA_LINK_FILE}.new"
+ elif openssl pkcs7 -inform der -in "${TEMPDIR}/${CA_LINK_FILE_NAME}" > /dev/null 2>&1
+ then
+ echo "Root certificate format is binary pkcs7"
+ openssl pkcs7 -print_certs -inform der -in "${TEMPDIR}/${CA_LINK_FILE_NAME}" -out "${CA_LINK_FILE}.new"
+ elif openssl pkcs12 -in "${TEMPDIR}/${CA_LINK_FILE_NAME}" -info > /dev/null 2>&1
+ then
+ echo "${0}: root certificate format is binary pkcs12"
+ echo "Error, root certificate is in unhandled format." >&2
+ exit 1
+ else
+ echo "${0}: error, root certificate is in unhandled format." >&2
+ exit 1
+ fi
+
+ openssl verify -trusted "${CA_LINK_FILE}.new" -untrusted "${CHAINFILE}" "${CERTFILE}" 1> /dev/null
+
+ CA_COMMON_NAME="$(openssl x509 -noout -subject -nameopt multiline -in "${CA_LINK_FILE}.new" | grep commonName | sed -n 's/ *commonName *= //p')"
+ CA_FILE="${CERT_PATH}/${CA_COMMON_NAME}.pem"
+
+ mv "${CA_LINK_FILE}.new" "${CA_FILE}"
+ rm -rf "${TEMPDIR}"
+}
+
+unset CA_FILE
+
+for FILE in $(find /etc/ssl/certs -not -name "????????.?" -not -name ca-certificates.crt)
+do
+ if openssl verify -no-CApath -CAfile "${FILE}" "${CHAINFILE}" > /dev/null 2>&1
+ then
+ CA_FILE="${FILE}"
+ break
+ fi
+done
+
+if [ -z "${CA_FILE}" ]
+then
+ echo "Could not find root CA on this system."
+
+ if [ "${CA_FROM_INTERNET}" = "TRUE" ]
+ then
+ Ca_from_internet
+ else
+ exit 1
+ fi
+fi
+
+echo "Found trusted root CA file: ${CA_FILE}"
+ln -sf "${CA_FILE}" "${CA_LINK_FILE}"
+#cp "${CA_FILE}" "${CA_LINK_FILE}"
+openssl verify -trusted "${CA_LINK_FILE}" -untrusted "${CHAINFILE}" "${CERTFILE}" 1> /dev/null
+cat "${CA_LINK_FILE}" "${CHAINFILE}" "${CERTFILE}" > "${CERT_PATH}/${CA_CHAIN_NAME}.pem"
diff --git a/bin/deploy_challenge.nsupdate.sh b/bin/deploy_challenge.nsupdate.sh
new file mode 100755
index 0000000..3b55840
--- /dev/null
+++ b/bin/deploy_challenge.nsupdate.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+set -e
+
+NAMESERVERS="$(kdig -4 +short @ns.bfh.science ns.bfh.science)"
+ZONE="$(cat /etc/hostname | awk -F. '{ print $(NF-1) "." $NF}')"
+
+for NAMESERVER in ${NAMESERVERS}
+do
+ echo -n " + Adding TXT record (_acme-challenge.${DOMAIN})..."
+
+ NSUPDATE="$(mktemp nsupdate.XXXX)"
+
+cat > "${NSUPDATE}" << EOF
+server ${NAMESERVER}
+zone ${ZONE}.
+ttl 300
+update add _acme-challenge.${DOMAIN} 300 TXT ${TOKEN_VALUE}
+send
+EOF
+
+ knsupdate "${NSUPDATE}"
+ rm -f "${NSUPDATE}"
+
+ echo " done."
+done
diff --git a/bin/deploy_ocsp.fullchain-privkey.sh b/bin/deploy_ocsp.fullchain-privkey.sh
new file mode 100755
index 0000000..9418590
--- /dev/null
+++ b/bin/deploy_ocsp.fullchain-privkey.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+set -e
+
+FILE="$(readlink ${OCSPFILE})"
+DIRECTORY="$(dirname ${OCSPFILE})"
+
+ln -sf "${FILE}" "${DIRECTORY}/cert.fullchain-privkey.pem.ocsp"
diff --git a/bin/exit_hook.fix-permissions.sh b/bin/exit_hook.fix-permissions.sh
new file mode 100755
index 0000000..74074cd
--- /dev/null
+++ b/bin/exit_hook.fix-permissions.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+echo " + Fixing permissions..."
+
+if getent group ssl-cert > /dev/null 2>&1
+then
+ echo -n " + /var/lib/dehydrated/certs:"
+
+ find /var/lib/dehydrated/certs -type d -exec chmod 0750 {} \;
+ find /var/lib/dehydrated/certs -type f -exec chmod 0640 {} \;
+
+ chown -R root:ssl-cert /var/lib/dehydrated/certs
+
+ echo " done."
+fi
diff --git a/bin/exit_hook.service-reload.sh b/bin/exit_hook.service-reload.sh
new file mode 100755
index 0000000..d434b71
--- /dev/null
+++ b/bin/exit_hook.service-reload.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+echo " + Reloading services..."
+
+for PACKAGE in apache2 haproxy postgresql
+do
+ if /usr/sbin/service ${PACKAGE} status > /dev/null 2>&1
+ then
+ echo -n " + ${PACKAGE}:"
+ /usr/sbin/service ${PACKAGE} reload
+ echo " done."
+ fi
+done
diff --git a/bin/exit_hook.slapd.sh b/bin/exit_hook.slapd.sh
new file mode 100755
index 0000000..2cb74cf
--- /dev/null
+++ b/bin/exit_hook.slapd.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+set -e
+
+NAME="$(cat /etc/hostname)"
+DEHYDRATED_PATH="/srv/${NAME}/dehydrated/certs/${NAME}"
+SLAPD_CERT_PATH="/etc/crypto/tls"
+CA_CHAIN_NAME="cachain"
+
+mkdir -p "${SLAPD_CERT_PATH}"
+unset CHANGE
+
+if ! cmp -s "${DEHYDRATED_PATH}/${CA_CHAIN_NAME}.pem" "${SLAPD_CERT_PATH}/${NAME}-${CA_CHAIN_NAME}.pem"
+then
+ /usr/bin/cp "${DEHYDRATED_PATH}/${CA_CHAIN_NAME}.pem" "${SLAPD_CERT_PATH}/${NAME}-${CA_CHAIN_NAME}.pem"
+ CHANGE=true
+fi
+
+if ! cmp -s "${DEHYDRATED_PATH}/cert.pem" "${SLAPD_CERT_PATH}/${NAME}.pem"
+then
+ /usr/bin/cp "${DEHYDRATED_PATH}/cert.pem" "${SLAPD_CERT_PATH}/${NAME}.pem"
+ CHANGE=true
+fi
+
+if ! cmp -s "${DEHYDRATED_PATH}/privkey.pem" "${SLAPD_CERT_PATH}/${NAME}.key"
+then
+ /usr/bin/cp "${DEHYDRATED_PATH}/privkey.pem" "${SLAPD_CERT_PATH}/${NAME}.key"
+ CHANGE=true
+fi
+
+if ! cmp -s "${DEHYDRATED_PATH}/fullchain.pem" "${SLAPD_CERT_PATH}/${NAME}-fullchain.pem"
+then
+ /usr/bin/cp "${DEHYDRATED_PATH}/fullchain.pem" "${SLAPD_CERT_PATH}/${NAME}-fullchain.pem"
+ CHANGE=true
+fi
+
+if [ ! -z ${CHANGE} ]
+then
+ chmod 0640 /etc/crypto/tls/${NAME}*
+ chgrp ssl-cert /etc/crypto/tls/${NAME}*
+ systemctl restart slapd.service
+fi
diff --git a/bin/git-amend-all b/bin/git-amend-all
new file mode 100755
index 0000000..9621a0d
--- /dev/null
+++ b/bin/git-amend-all
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+set -e
+
+if [ -n "$(git config --get user.signingKey)" ]
+then
+ GIT_OPTIONS="-S"
+fi
+
+git add -A
+git commit -a --amend -C HEAD ${GIT_OPTIONS}
diff --git a/bin/git-bfh-add b/bin/git-bfh-add
new file mode 120000
index 0000000..eceef43
--- /dev/null
+++ b/bin/git-bfh-add
@@ -0,0 +1 @@
+git-debian-add \ No newline at end of file
diff --git a/bin/git-bfh-changelog b/bin/git-bfh-changelog
new file mode 120000
index 0000000..5153454
--- /dev/null
+++ b/bin/git-bfh-changelog
@@ -0,0 +1 @@
+git-debian-changelog \ No newline at end of file
diff --git a/bin/git-bfh-check b/bin/git-bfh-check
new file mode 120000
index 0000000..aa1c6f7
--- /dev/null
+++ b/bin/git-bfh-check
@@ -0,0 +1 @@
+git-debian-check \ No newline at end of file
diff --git a/bin/git-bfh-check.d b/bin/git-bfh-check.d
new file mode 120000
index 0000000..efb059c
--- /dev/null
+++ b/bin/git-bfh-check.d
@@ -0,0 +1 @@
+git-debian-check.d \ No newline at end of file
diff --git a/bin/git-bfh-init b/bin/git-bfh-init
new file mode 120000
index 0000000..dc32360
--- /dev/null
+++ b/bin/git-bfh-init
@@ -0,0 +1 @@
+git-debian-init \ No newline at end of file
diff --git a/bin/git-bfh-release b/bin/git-bfh-release
new file mode 120000
index 0000000..eda23ed
--- /dev/null
+++ b/bin/git-bfh-release
@@ -0,0 +1 @@
+git-debian-release \ No newline at end of file
diff --git a/bin/git-bfh-tag b/bin/git-bfh-tag
new file mode 120000
index 0000000..801085e
--- /dev/null
+++ b/bin/git-bfh-tag
@@ -0,0 +1 @@
+git-debian-tag \ No newline at end of file
diff --git a/bin/git-checkout-all b/bin/git-checkout-all
new file mode 100755
index 0000000..eef1ad6
--- /dev/null
+++ b/bin/git-checkout-all
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+set -e
+
+CURRENT_BRANCH="$(git branch | awk '/^\* / { print $2 }')"
+REMOTE_BRANCHES="$(git branch -r | awk '{ print $1 }')"
+
+for REMOTE_BRANCH in ${REMOTE_BRANCHES}
+do
+ BRANCH="$(echo ${REMOTE_BRANCH} | cut -d/ -f 2-)"
+
+ if [ "${BRANCH}" = "HEAD" ]
+ then
+ continue
+ fi
+
+ if git branch | grep -q "${BRANCH}$"
+ then
+ continue
+ fi
+
+ git checkout -b ${BRANCH} ${REMOTE_BRANCH}
+done
+
+if [ "$(git branch | awk '/^\* / { print $2 }')" != "${CURRENT_BRANCH}" ]
+then
+ git checkout ${CURRENT_BRANCH}
+fi
diff --git a/bin/git-checkout-branches b/bin/git-checkout-branches
new file mode 100755
index 0000000..770551d
--- /dev/null
+++ b/bin/git-checkout-branches
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+CURRENT_BRANCH="$(git branch | awk '/^\* / { print $2 }')"
+REMOTE_BRANCHES="$(git branch -r | awk '{ print $1 }')"
+
+for REMOTE_BRANCH in ${REMOTE_BRANCHES}
+do
+ BRANCH="$(echo ${REMOTE_BRANCH} | cut -d/ -f 2-)"
+
+ if [ "${BRANCH}" = "HEAD" ]
+ then
+ continue
+ fi
+
+ if git branch | grep -q "${BRANCH}$"
+ then
+ continue
+ fi
+
+ git checkout -b ${BRANCH} ${REMOTE_BRANCH}
+done
+
+if [ "$(git branch | awk '/^\* / { print $2 }')" != "${CURRENT_BRANCH}" ]
+then
+ git checkout ${CURRENT_BRANCH}
+fi
diff --git a/bin/git-cherry-pick-recursive b/bin/git-cherry-pick-recursive
new file mode 100755
index 0000000..96707f5
--- /dev/null
+++ b/bin/git-cherry-pick-recursive
@@ -0,0 +1,37 @@
+git log master | awk '/^commit / { print $2 }' | reverse | sed 1d
+#!/bin/sh
+
+# source-tools - Manage Git repositories effectively and efficiently
+# Copyright (C) 2014-2017 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+BRANCH="${1}"
+ID="${2}"
+
+if [ -z "${BRANCH}" ] || [ -z "${ID}" ]
+then
+ echo "Usage: $0 BRANCH ID"
+ exit 1
+fi
+
+COMMITS="$(git log ${BRANCH} -- | awk '/^commit / { print $2 }')"
+COMMITS="$(echo ${COMMITS} | sed -e "s|${ID}.*$|${ID}|" | awk '{ a[NR]=$0 } END { for(i=NR; i; --i) print a[i] } ')"
+
+for COMMIT in ${COMMITS}
+do
+ git cherry-pick ${COMMIT}
+done
diff --git a/bin/git-clone.sh b/bin/git-clone.sh
new file mode 100755
index 0000000..4a619c5
--- /dev/null
+++ b/bin/git-clone.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+set -e
+
+for DIRECTORY in \
+ /srv/local/bin /srv/local/web \
+ /srv/data/*/bin /srv/data/*/web \
+ /srv/*/bin /srv/*/web
+do
+ if [ ! -e "${DIRECTORY}/.git/config" ]
+ then
+ continue
+ fi
+
+ URL="$(awk '/url = / { print $3 }' ${DIRECTORY}/.git/config)"
+
+ if [ -z "${URL}" ]
+ then
+ continue
+ fi
+
+ git clone "${URL}" "${DIRECTORY}.tmp"
+
+ cd "${DIRECTORY}.tmp"
+ git submodule init
+ git submodule update
+ cd "${OLDPWD}"
+
+ rm -rf "${DIRECTORY}"
+ mv "${DIRECTORY}.tmp" "${DIRECTORY}"
+
+ chown 1000:1000 "${DIRECTORY}" -R
+done
diff --git a/bin/git-commit-lazy b/bin/git-commit-lazy
new file mode 100755
index 0000000..a661f91
--- /dev/null
+++ b/bin/git-commit-lazy
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+set -e
+
+if [ -n "$(git config --get user.signingKey)" ]
+then
+ GIT_OPTIONS="-S"
+fi
+
+git add -A
+git commit -a -s --allow-empty -m "Updating." ${GIT_OPTIONS}
diff --git a/bin/git-debian-add b/bin/git-debian-add
new file mode 100755
index 0000000..06e25b9
--- /dev/null
+++ b/bin/git-debian-add
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+set -e
+
+if [ -n "$(git config --get user.signingKey)" ]
+then
+ GIT_OPTIONS="-S"
+fi
+
+MODE="$(basename ${0} | sed -e 's|^git-||' -e 's|-add$||')"
+
+if [ -n "${1}" ]
+then
+ VERSION="${1}"
+else
+ VERSION="$(dpkg-parsechangelog | awk '/^Version: / { print $2 }')"
+fi
+
+HASH="${2}"
+
+chmod 0755 debian/rules
+
+git add -A -f
+git commit -a -s -m "Adding ${MODE} version ${VERSION}." ${GIT_OPTIONS}
+git-${MODE}-tag ${VERSION} ${HASH}
diff --git a/bin/git-debian-changelog b/bin/git-debian-changelog
new file mode 100755
index 0000000..2197979
--- /dev/null
+++ b/bin/git-debian-changelog
@@ -0,0 +1,197 @@
+#!/bin/sh
+
+set -e
+
+if [ ! -x "$(which gbp 2> /dev/null)" ]
+then
+ echo "gbp - command not found" >&2
+ exit 1
+fi
+
+if [ ! -e debian/changelog ]
+then
+ echo "E: debian/changelog - no such file" >&2
+ exit 1
+fi
+
+MODE="$(basename ${0} | sed -e 's|^git-||' -e 's|-changelog$||')"
+
+WRAP_SCRIPT="/usr/share/doc/git-buildpackage/examples/wrap_cl.py"
+
+if [ -e "/usr/share/doc/git-buildpackage/examples/wrap_cl.py" ]
+then
+ CUSTOMIZATION="--customization ${WRAP_SCRIPT}"
+fi
+
+ID="${1}"
+
+if [ -z "${ID}" ]
+then
+ if [ -n "$(git log | grep -m1 'Adding version ')" ]
+ then
+ ID="$(git log | grep -B4 -m1 "Adding version " | awk '/^commit / { print $2 }')"
+ fi
+
+ if [ -z "${ID}" ] && [ -n "$(git log | grep -m1 'Releasing version ')" ]
+ then
+ ID="$(git log | grep -B4 -m1 "Releasing version " | awk '/^commit / { print $2 }')"
+ fi
+
+ if [ -z "${ID}" ] && [ -n "$(git log | grep -m1 "Releasing ${MODE} version ")" ]
+ then
+ ID="$(git log | grep -B4 -m1 "Releasing ${MODE} version " | awk '/^commit / { print $2 }')"
+ fi
+
+ if [ -z "${ID}" ] && [ -n "$(git log | grep -m1 "Adding ${MODE} version ")" ]
+ then
+ ID="$(git log | grep -B4 -m1 "Adding ${MODE} version " | awk '/^commit / { print $2 }')"
+ fi
+else
+ shift
+fi
+
+if [ -e debian/gbp.conf ]
+then
+ TEMPFILE="$(mktemp -p . -u)"
+ mv debian/gbp.conf "${TEMPFILE}"
+fi
+
+SOURCE="$(dpkg-parsechangelog -S Source)"
+URGENCY="$(dpkg-parsechangelog -S Urgency)"
+
+if grep -qs "git.*.progress-linux.org" .git/config && grep -qs maintainers@lists.progress-linux.org debian/control
+then
+ DIST="$(git config --get remote.origin.url | awk -F/ '{ print $(NF-1) }')"
+ DISTRIBUTION="--distribution=${DIST}"
+
+ VERSION="$(dpkg-parsechangelog -S Version)"
+
+ case "${VERSION}" in
+ *progress*)
+ VERSION=""
+ ;;
+
+ *)
+ case "${DIST}" in
+ engywuck)
+ case "${VERSION}" in
+ *-*)
+ # non-native
+ VERSION="--dch-opt=-b -N ${VERSION}progress5u1"
+ ;;
+
+ *)
+ # native
+ VERSION="--dch-opt=-b -N ${VERSION}-0progress5u1"
+ ;;
+ esac
+ ;;
+
+ engywuck-backports)
+ case "${VERSION}" in
+ *-*)
+ # non-native
+ VERSION="--dch-opt=-b -N ${VERSION}~progress5+u1"
+ ;;
+
+ *)
+ # native
+ VERSION="--dch-opt=-b -N ${VERSION}-0.0~progress5+u1"
+ ;;
+ esac
+ ;;
+
+ fuchur)
+ case "${VERSION}" in
+ *-*)
+ # non-native
+ VERSION="--dch-opt=-b -N ${VERSION}progress6u1"
+ ;;
+
+ *)
+ # native
+ VERSION="--dch-opt=-b -N ${VERSION}-0progress6u1"
+ ;;
+ esac
+ ;;
+
+ fuchur-backports)
+ case "${VERSION}" in
+ *-*)
+ # non-native
+ VERSION="--dch-opt=-b -N ${VERSION}~progress6+u1"
+ ;;
+
+ *)
+ # native
+ VERSION="--dch-opt=-b -N ${VERSION}-0.0~progress6+u1"
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+fi
+
+if grep -qs "git.*.bfh.science" .git/config
+then
+ DIST="$(git config --get remote.origin.url | awk -F/ '{ print $(NF-1) }')"
+ DISTRIBUTION="--distribution=${DIST}"
+
+ case "${VERSION}" in
+ *bfh*)
+ VERSION=""
+ ;;
+
+ *)
+ case "${VERSION}" in
+ *-*)
+ # non-native
+ VERSION="--dch-opt=-b -N ${VERSION}~bfh10+u1"
+ ;;
+
+ *)
+ # native
+ VERSION="--dch-opt=-b -N ${VERSION}-0.0~bfh10+u1"
+ ;;
+ esac
+ ;;
+ esac
+fi
+
+if [ -n "${ID}" ]
+then
+ gbp dch --spawn-editor=never ${DISTRIBUTION} ${VERSION} --urgency ${URGENCY} --git-log="--no-show-signature" --debian-branch $(git branch --show-current) --git-author --release --since ${ID} ${CUSTOMIZATION} ${@}
+else
+ gbp dch --spawn-editor=never ${DISTRIBUTION} ${VERSION} --urgency ${URGENCY} --git-log="--no-show-signature" --auto --debian-branch $(git branch --show-current) --git-author --release ${CUSTOMIZATION} ${@}
+fi
+
+if [ -n "${DIST}" ]
+then
+ # derivatives
+ if ! grep -qs "Initial upload to ${DIST}" debian/changelog
+ then
+ sed -i -e "0,/^$/s//\n * Initial upload to ${DIST}./" debian/changelog
+ else
+ sed -i -e "0,/^$/s//\n * Uploading to ${DIST}, remaining changes:/" debian/changelog
+ fi
+else
+ # debian
+ DIST="$(dpkg-parsechangelog -S Distribution)"
+ sed -i -e "0,/^$/s//\n * Uploading to ${DIST}./" debian/changelog
+
+ if git log ${ID}..HEAD | grep -qs 'Merging upstream version '
+ then
+ VERSION_NEW="$(git log ${ID}..HEAD | awk '/Merging upstream version/ { print $4 }' | sed -e 's|.$||')"
+ VERSION_OLD="$(dpkg-parsechangelog -S Version)"
+
+ sed -i -e "s|^${SOURCE} (${VERSION_OLD}) ${DIST}; urgency=${URGENCY}|${SOURCE} (${VERSION_NEW}-1) ${DIST}; urgency=${URGENCY}|" debian/changelog
+ fi
+fi
+
+if [ -e "${TEMPFILE}" ]
+then
+ mv "${TEMPFILE}" debian/gbp.conf
+fi
+
+vi debian/changelog
diff --git a/bin/git-debian-check b/bin/git-debian-check
new file mode 100755
index 0000000..b4d5869
--- /dev/null
+++ b/bin/git-debian-check
@@ -0,0 +1,132 @@
+#!/bin/sh
+
+# source-tools - Manage Git repositories effectively and efficiently
+# Copyright (C) 2014-2017 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+FEATURE_BRANCH="progress-linux"
+MAINTAINER="Progress Linux Maintainers <maintainers@lists.progress-linux.org>"
+
+Main ()
+{
+ REPOSITORY="$(basename $(git config --get remote.origin.url) .git)"
+
+ echo "Checking ${REPOSITORY} repository:"
+
+ # repository checks
+ for CHECK in /usr/lib/git-tools/repository-check.d/repository_*
+ do
+ ./${CHECK}
+ done
+
+ ORIGINAL_BRANCH="$(git branch | awk '/^\* / { print $2 }')"
+
+ case "${ORIGINAL_BRANCH}" in
+ ${FEATURE_BRANCH})
+ ;;
+
+ *)
+ git checkout ${FEATURE_BRANCH}
+ ;;
+ esac
+
+ DISTRIBUTION="$(dpkg-parsechangelog | awk '/Distribution: / { print $2 }')"
+
+ case ${DISTRIBUTION} in
+ *-extras)
+ BRANCHES="upstream ${FEATURE_BRANCH}"
+ ;;
+
+ *)
+ BRANCHES="upstream debian ${FEATURE_BRANCH}"
+ ;;
+ esac
+
+ # repository checks
+ for CHECK in /usr/lib/git-tools/repository-check.d/branch_*
+ do
+ ./${CHECK}
+ done
+
+ BRANCHES="$(git branch | sed -e 's|^\* ||')"
+
+ for BRANCH in ${BRANCHES}
+ do
+ case "${BRANCH}" in
+ upstream)
+ Branch_has_initial_empty_commit
+ ;;
+ esac
+
+ # repository checks
+ for CHECK in /usr/lib/git-tools/repository-check.d/commit_*
+ do
+ ./${CHECK}
+ done
+
+ # repository checks
+ for CHECK in /usr/lib/git-tools/repository-check.d/tag_*
+ do
+ ./${CHECK}
+ done
+
+ # TODO:
+ # * git commits and tags have ever increasing commit date
+ done
+
+ RELEASE="$(echo ${DISTRIBUTION} | sed -e 's|-extras||' -e 's|-security||' -e 's|-updates||')"
+
+ VCS_BROWSER="https://sources.progress-linux.org/cgit/releases/${RELEASE}/packages"
+ VCS_GIT="git://sources.progress-linux.org/git/releases/${RELEASE}/packages"
+
+ case "${REPOSITORY}" in
+ apt|dpkg|debian-archive-keyring|debian-keyring|clzip|lunzip|lzd|lzip|lziprecover|lzlib|pdlzip|plzip|zutils)
+ COMPRESSION="xz"
+ ;;
+
+ *)
+ COMPRESSION="lzip"
+ ;;
+ esac
+
+ # repository checks
+ for CHECK in /usr/lib/git-tools/repository-check.d/packaging_*
+ do
+ ./${CHECK}
+ done
+
+ # TODO:
+ # * debian version
+ # * debian distribution
+ # * debian changelog entries
+ # * release tags only modify debian/changelog
+
+ CURRENT_BRANCH="$(git branch | awk '/^\* / { print $2 }')"
+
+ case "${CURRENT_BRANCH}" in
+ ${ORIGINAL_BRANCH})
+ ;;
+
+ *)
+ git checkout ${ORIGINAL_BRANCH}
+ ;;
+ esac
+
+ echo "done."
+}
+
+Main ${@}
diff --git a/bin/git-debian-check.d/branch_initial-empty-commit.sh b/bin/git-debian-check.d/branch_initial-empty-commit.sh
new file mode 100755
index 0000000..8efc8e4
--- /dev/null
+++ b/bin/git-debian-check.d/branch_initial-empty-commit.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * (\033[0;32m${BRANCH}\033[0m) branch has initial empty commit..."
+
+ID="$(git log --no-abbrev-commit ${BRANCH} -- | awk '/^commit / { print $2 }' | tail -n1)"
+MESSAGE="$(git show --no-patch --no-renames --pretty=format:%B ${ID} | head -n1)"
+
+if [ "${MESSAGE}" != "Initial commit." ]
+then
+ echo " \033[1;31mno\033[0m."
+else
+ echo " \033[1;32myes\033[0m."
+fi
diff --git a/bin/git-debian-check.d/comit_good-signatures.sh b/bin/git-debian-check.d/comit_good-signatures.sh
new file mode 100755
index 0000000..3501639
--- /dev/null
+++ b/bin/git-debian-check.d/comit_good-signatures.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * (\033[0;32m${BRANCH}\033[0m) commits have good signatures..."
+
+IDS="$(git log ${BRANCH} -- | grep -c ^commit)"
+SIGNATURES="$(git log --show-signature ${BRANCH} -- | grep -c '^gpg: Good signature from')"
+
+if [ "${IDS}" -ne "${SIGNATURES}" ]
+then
+ echo " \033[1;31mno\033[0m."
+ echo "E: some commits on branch ${BRANCH} have no good signatures."
+else
+ echo " \033[1;32myes\033[0m."
+fi
diff --git a/bin/git-debian-check.d/comit_signed-off-lines.sh b/bin/git-debian-check.d/comit_signed-off-lines.sh
new file mode 100755
index 0000000..0940eaa
--- /dev/null
+++ b/bin/git-debian-check.d/comit_signed-off-lines.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * (\033[0;32m${BRANCH}\033[0m) commits have Signed-off-by lines..."
+
+IDS="$(git log ${BRANCH} -- | grep -c ^commit)"
+SIGNED="$(git log ${BRANCH} -- | grep -c '^ Signed-off-by: ')"
+
+if [ "${IDS}" -ne "${SIGNED}" ]
+then
+ echo " \033[1;31mno\033[0m."
+ echo "E: some commits on branch ${BRANCH} have no Signed-off-by lines."
+else
+ echo " \033[1;32myes\033[0m."
+fi
diff --git a/bin/git-debian-check.d/commit_message-begin-with-capital-letter.sh b/bin/git-debian-check.d/commit_message-begin-with-capital-letter.sh
new file mode 100755
index 0000000..0cc981a
--- /dev/null
+++ b/bin/git-debian-check.d/commit_message-begin-with-capital-letter.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * (\033[0;32m${BRANCH}\033[0m) commit messages begin with capital letter..."
+
+COMMITS="$(git log --no-abbrev-commit ${BRANCH} -- | awk '/^commit / { print $2 }')"
+
+for COMMIT in ${COMMITS}
+do
+ MESSAGE="$(git show --no-patch --no-renames --pretty=format:%B ${COMMIT} | head -n1)"
+
+ if ! echo ${MESSAGE} | grep -qs '^[A-Z]'
+ then
+ echo " \033[1;31mno\033[0m."
+ echo "E: commit message ${COMMIT} does not begin with capital letter."
+ fi
+done
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-check.d/commit_message-end-with-full-stop.sh b/bin/git-debian-check.d/commit_message-end-with-full-stop.sh
new file mode 100755
index 0000000..4a97e42
--- /dev/null
+++ b/bin/git-debian-check.d/commit_message-end-with-full-stop.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * (\033[0;32m${BRANCH}\033[0m) commit messages end with full stop..."
+
+COMMITS="$(git log --no-abbrev-commit ${BRANCH} -- | awk '/^commit / { print $2 }')"
+
+for COMMIT in ${COMMITS}
+do
+ MESSAGE="$(git show --no-patch --no-renames --pretty=format:%B ${COMMIT} | head -n1)"
+
+ if ! echo ${MESSAGE} | grep -qs '.$'
+ then
+ echo " \033[1;31mno\033[0m."
+ echo "E: commit message ${COMMIT} does not end with full stop."
+ fi
+done
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-check.d/commit_release-commits-have-release-tags.sh b/bin/git-debian-check.d/commit_release-commits-have-release-tags.sh
new file mode 100755
index 0000000..cdc2d98
--- /dev/null
+++ b/bin/git-debian-check.d/commit_release-commits-have-release-tags.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * (\033[0;32m${BRANCH}\033[0m) release commits have release tags..."
+
+COMMITS="$(git log --no-abbrev-commit ${BRANCH} -- | grep -B4 -E "(Releasing|Adding) ${BRANCH} version [0-9].*.$" | awk '/^commit / { print $2 }')"
+
+for COMMIT in ${COMMITS}
+do
+ VERSION="$(git show --no-patch --no-renames --pretty=format:%B ${COMMIT} | head -n1 | awk -Fversion\ '{ print $2 }' | sed -e 's|.$||')"
+ TAG="$(echo ${VERSION} | sed -e 's|:|%|g' -e 's|~|_|g')"
+ ID="$(git show --no-abbrev-commit --no-patch --no-renames ${BRANCH}/${TAG} | awk '/^commit / { print $2 }')"
+
+ if [ "${ID}" != "${COMMIT}" ]
+ then
+ echo " \033[1;31mno\033[0m."
+ echo "E: commit ${COMMIT} has no release tag."
+ fi
+done
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-check.d/packaging_debian-maintainer-fields.sh b/bin/git-debian-check.d/packaging_debian-maintainer-fields.sh
new file mode 100755
index 0000000..65dfcfd
--- /dev/null
+++ b/bin/git-debian-check.d/packaging_debian-maintainer-fields.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * (\033[0;32m${FEATURE_BRANCH}\033[0m) debian maintainer field..."
+
+if ! grep -qs "^Maintainer: ${MAINTAINER}" debian/control
+then
+ echo " \033[1;31mno\033[0m."
+ echo "E: packaging has no maintainer field."
+fi
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-check.d/packaging_debian-source-compression.sh b/bin/git-debian-check.d/packaging_debian-source-compression.sh
new file mode 100755
index 0000000..dabbbb7
--- /dev/null
+++ b/bin/git-debian-check.d/packaging_debian-source-compression.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+COMPRESSION="${@}"
+
+echo -n " * (\033[0;32m${FEATURE_BRANCH}\033[0m) debian source compression..."
+
+case "${COMPRESSION}" in
+ lzip)
+ if grep -qs "^compression" debian/source/options
+ then
+ echo " \033[1;31mno\033[0m."
+ echo "E: wrong compression."
+ fi
+ ;;
+
+ xz)
+ if [ "$(awk -F= '/^compression/ { print $2 }' debian/source/options | sed -e 's| ||g' -e 's|"||g')" != "xz" ]
+ then
+ echo " \033[1;31mno\033[0m."
+ echo "E: wrong compression."
+ fi
+ ;;
+esac
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-check.d/packaging_debian-source-format.sh b/bin/git-debian-check.d/packaging_debian-source-format.sh
new file mode 100755
index 0000000..060aef6
--- /dev/null
+++ b/bin/git-debian-check.d/packaging_debian-source-format.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * (\033[0;32m${FEATURE_BRANCH}\033[0m) debian package source format..."
+
+FORMAT="$(cat debian/source/format)"
+
+if [ "${FORMAT}" != "3.0 (quilt)" ]
+then
+ echo " \033[1;31mno\033[0m."
+ echo "E: debian source format is not 3.0 (quilt)."
+fi
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-check.d/packaging_debian-source-local-options.sh b/bin/git-debian-check.d/packaging_debian-source-local-options.sh
new file mode 100755
index 0000000..a3a2bb6
--- /dev/null
+++ b/bin/git-debian-check.d/packaging_debian-source-local-options.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * (\033[0;32m${FEATURE_BRANCH}\033[0m) source local options..."
+
+if ! grep -qs ^abort-on-upstream-changes debian/source/local-options
+then
+ echo " \033[1;31mno\033[0m."
+ echo "E: packaging has no source local options."
+fi
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-check.d/packaging_debian-upload-urgency.sh b/bin/git-debian-check.d/packaging_debian-upload-urgency.sh
new file mode 100755
index 0000000..8ee731f
--- /dev/null
+++ b/bin/git-debian-check.d/packaging_debian-upload-urgency.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * (\033[0;32m${FEATURE_BRANCH}\033[0m) debian upload urgency..."
+
+DERIVATIVE_TAGS="$(git tag | grep "^${FEATURE_BRANCH}" | awk -F/ '{ print $2 }')"
+
+for DERIVATIVE_TAG in ${DERIVATIVE_TAGS}
+do
+ DERIVATIVE_URGENCY="$(git show ${FEATURE_BRANCH}/${DERIVATIVE_TAG}:debian/changelog | head -n1 | awk -Furgency= '{ print $2 }' | sed -e 's| ||g')"
+ DISTRIBUTION="$(git show ${FEATURE_BRANCH}/${DERIVATIVE_TAG}:debian/changelog | head -n1 | awk '{ print $3 }' | sed -e 's|;$||')"
+
+ case "${DISTRIBUTION}" in
+ *-extras)
+ URGENCY="low"
+ ;;
+
+ *)
+ TAG="$(echo ${DERIVATIVE_TAG} | sed -e 's|-0+cairon[0-9]$||' -e 's|-0_cairon[0-9]$||' -e 's|-0cairon[0-9]$||' -e 's|_cairon[0-9]$||' -e 's|cairon[0-9]$||')"
+ URGENCY="$(git show debian/${TAG}:debian/changelog | head -n1 | awk -Furgency= '{ print $2 }' | sed -e 's| ||g')"
+ ;;
+ esac
+
+ if [ "${DERIVATIVE_URGENCY}" != "${URGENCY}" ]
+ then
+ echo " \033[1;31mno\033[0m."
+ echo "E: wrong urgency of ${DERIVATIVE_TAG}, should be ${URGENCY} instead of ${DERIVATIVE_URGENCY}."
+ fi
+done
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-check.d/packaging_debian-vcs-fields.sh b/bin/git-debian-check.d/packaging_debian-vcs-fields.sh
new file mode 100755
index 0000000..476a947
--- /dev/null
+++ b/bin/git-debian-check.d/packaging_debian-vcs-fields.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * (\033[0;32m${FEATURE_BRANCH}\033[0m) debian vcs fields..."
+
+if ! grep -qs "^Vcs-Browser: ${VCS_BROWSER}/${REPOSITORY}.git" debian/control
+then
+ echo " \033[1;31mno\033[0m."
+ echo "E: packaging has no vcs-browser field."
+fi
+
+if ! grep -qs "Vcs-Git: ${VCS_GIT}/${REPOSITORY}.git" debian/control
+then
+ echo " \033[1;31mno\033[0m."
+ echo "E: packaging has no vcs-git field."
+fi
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-check.d/packaging_no-direct-upstream-changes.sh b/bin/git-debian-check.d/packaging_no-direct-upstream-changes.sh
new file mode 100755
index 0000000..2cf0372
--- /dev/null
+++ b/bin/git-debian-check.d/packaging_no-direct-upstream-changes.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * (\033[0;32m${FEATURE_BRANCH}\033[0m) no direct upstream changes..."
+
+CHANGES="$(git diff upstream..${FEATURE_BRANCH} | grep -E '^(---|\+\+\+) (a|b)/' | sed -e 's|--- a/||g' -e 's|+++ a/||g' -e 's|--- b/||g' -e 's|+++ b/||g' | grep -v ^debian\/ || true)"
+
+if [ -n "${CHANGES}" ]
+then
+ echo " \033[1;31mno\033[0m."
+ echo "E: packaging has direct upstream changes."
+fi
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-check.d/repository_branches-exist.sh b/bin/git-debian-check.d/repository_branches-exist.sh
new file mode 100755
index 0000000..dfbdd9e
--- /dev/null
+++ b/bin/git-debian-check.d/repository_branches-exist.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+BRANCHES="${@}"
+
+echo -n " * [\033[1;34m${REPOSITORY}\033[0m] branches \"${BRANCHES}\" exist..."
+
+for BRANCH in ${BRANCHES}
+do
+ if ! git branch | grep -qs " ${BRANCH}$"
+ then
+ echo " \033[1;31mno\033[0m."
+ echo "E: repository has no ${BRANCH} branch."
+ fi
+done
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-check.d/repository_branches-not-exist.sh b/bin/git-debian-check.d/repository_branches-not-exist.sh
new file mode 100755
index 0000000..69b3251
--- /dev/null
+++ b/bin/git-debian-check.d/repository_branches-not-exist.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+BRANCHES="${@}"
+
+echo -n " * [\033[1;34m${REPOSITORY}\033[0m] no other branches..."
+
+BRANCHES="$(echo ${@} | sed -e 's| |\||g')"
+BRANCH="$(echo $(git branch | grep -Ev " (${BRANCHES})$" || true) | sed -e 's| | |g')"
+
+if [ -n "${BRANCH}" ]
+then
+ echo " \033[1;31mno\033[0m."
+ echo "E: repository has other branches ${BRANCH}."
+fi
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-check.d/repository_clean-working-directory.sh b/bin/git-debian-check.d/repository_clean-working-directory.sh
new file mode 100755
index 0000000..72aa501
--- /dev/null
+++ b/bin/git-debian-check.d/repository_clean-working-directory.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * [\033[1;34m${REPOSITORY}\033[0m] repository working directory clean..."
+
+if ! git status 2>&1 | grep -qs "^nothing to commit, working directory clean$"
+then
+ echo " \033[1;31mno\033[0m."
+ echo "E: repository has unclean working directory."
+ exit 1
+fi
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-check.d/tag_all-tags-are-on-branch.sh b/bin/git-debian-check.d/tag_all-tags-are-on-branch.sh
new file mode 100755
index 0000000..7463758
--- /dev/null
+++ b/bin/git-debian-check.d/tag_all-tags-are-on-branch.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * (\033[0;32m${BRANCH}\033[0m) tags are on branch..."
+
+TAGS="$(git tag | grep ^${BRANCH}/ | sort -V)"
+
+for TAG in ${TAGS}
+do
+ ID="$(git show --no-abbrev-commit --no-patch --no-renames ${TAG} | awk '/^commit / { print $2 }')"
+
+ if ! git log --no-abbrev-commit ${BRANCH} -- | grep -Eqs "^commit ${ID}($| \()"
+ then
+ echo " \033[1;31mno\033[0m."
+ echo "E: tag ${TAG} is not on branch."
+ fi
+done
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-check.d/tag_messages-match-release-commit.sh b/bin/git-debian-check.d/tag_messages-match-release-commit.sh
new file mode 100755
index 0000000..e53a87a
--- /dev/null
+++ b/bin/git-debian-check.d/tag_messages-match-release-commit.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * (\033[0;32m${BRANCH}\033[0m) tag messages matches release commit..."
+
+TAGS="$(git tag | grep ^${BRANCH}/ | sort -V)"
+
+for TAG in ${TAGS}
+do
+ VERSION="$(echo ${TAG} | awk -F/ '{ print $2 }' | sed -e 's|%|:|g' -e 's|_|~|g')"
+
+ if ! git show --no-patch --no-renames ${TAG} | grep -Eqs "^ (Releasing|Adding) ${BRANCH} version $(echo ${VERSION} | sed -e 's|+|\\+|g').$"
+ then
+ echo " \033[1;31mno\033[0m."
+ echo "E: tag message ${TAG} does not match release commit."
+ fi
+done
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-check.d/tag_messages-match-version.sh b/bin/git-debian-check.d/tag_messages-match-version.sh
new file mode 100755
index 0000000..c4edef0
--- /dev/null
+++ b/bin/git-debian-check.d/tag_messages-match-version.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * (\033[0;32m${BRANCH}\033[0m) tag messages matches version..."
+
+TAGS="$(git tag | grep ^${BRANCH}/ | sort -V)"
+
+for TAG in ${TAGS}
+do
+ VERSION="$(echo ${TAG} | awk -F/ '{ print $2 }' | sed -e 's|%|:|g' -e 's|_|~|g')"
+
+ if ! git show --no-patch --no-renames ${TAG} | grep -qs "^Tagging ${BRANCH} version ${VERSION}.$"
+ then
+ echo " \033[1;31mno\033[0m."
+ echo "E: tag message ${TAG} does not match version ${VERSION}."
+ fi
+done
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-check.d/tag_signatures-with-gnupg.sh b/bin/git-debian-check.d/tag_signatures-with-gnupg.sh
new file mode 100755
index 0000000..d74055d
--- /dev/null
+++ b/bin/git-debian-check.d/tag_signatures-with-gnupg.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# source-tools - Git extra utilities
+# Copyright (C) 2014-2016 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+echo -n " * (\033[0;32m${BRANCH}\033[0m) tags signatures with gnupg..."
+
+TAGS="$(git tag | grep ^${BRANCH}/ | sort -V)"
+
+for TAG in ${TAGS}
+do
+ if ! git show --no-patch --no-renames ${TAG} | grep -qs '^Version: GnuPG v1$'
+ then
+ echo " \033[1;31mno\033[0m."
+ echo "E: tag ${TAG} has no signature with gnupg."
+ fi
+done
+
+echo " \033[1;32myes\033[0m."
diff --git a/bin/git-debian-import b/bin/git-debian-import
new file mode 100755
index 0000000..d94a943
--- /dev/null
+++ b/bin/git-debian-import
@@ -0,0 +1,72 @@
+#!/bin/sh
+
+set -e
+
+DSC="$1"
+
+TMPDIR="$(mktemp -d -p . dpkg-source.XXXX)"
+
+############ upstream
+
+git checkout upstream
+
+( find | grep -v '^./.git/.*' | grep -v './.git$' | xargs rm -rf ) || true
+
+dpkg-source -x --no-copy --skip-debianization ${DSC} ${TMPDIR}
+
+cd "${TMPDIR}"
+rm -rf .git
+mv $(find -mindepth 1 -maxdepth 1) ../
+cd "${OLDPWD}"
+
+rmdir ${TMPDIR}
+
+VERSION="$(awk '/^Version: / { print $2 }' ${DSC} | head -n1)"
+
+FILE_VERSION="$(echo ${VERSION} | awk -F: '{ print $2 }')"
+FILE_VERSION="${FILE_VERSION:-${VERSION}}"
+
+git-upstream-add ${VERSION}
+
+############## debian
+
+git checkout debian
+
+git cherry-pick -n upstream
+
+git commit -a -s -S -m "Merging upstream version ${VERSION}."
+
+rm -rf debian
+
+if [ -e $(dirname ${DSC})/$(basename ${DSC} .dsc).diff.gz ]
+then
+ zcat $(dirname ${DSC})/$(basename ${DSC} .dsc).diff.gz | patch -Np1
+fi
+
+if ls $(dirname ${DSC})/$(basename ${DSC} .dsc).debian.tar.* > /dev/null 2>&1
+then
+ tar xf $(dirname ${DSC})/$(basename ${DSC} .dsc).debian.tar.*
+fi
+
+git-debian-add
+
+################ progress-linux / bfh
+
+if git branch | grep -qs progress-linux
+then
+ BRANCH="progress-linux"
+elif git branch | grep -qs bfh
+then
+ BRANCH="bfh"
+fi
+
+git checkout ${BRANCH}
+
+git cherry-pick -n upstream
+git commit -a -s -S -m "Merging upstream version ${VERSION}."
+
+git cherry-pick -n debian
+
+DEBIAN_VERSION="$(dpkg-parsechangelog | awk '/^Version: / { print $2 }')"
+
+git commit -a -s -S -m "Merging debian version ${DEBIAN_VERSION}."
diff --git a/bin/git-debian-init b/bin/git-debian-init
new file mode 100755
index 0000000..37235d9
--- /dev/null
+++ b/bin/git-debian-init
@@ -0,0 +1,113 @@
+#!/bin/sh
+
+# source-tools - Manage Git repositories effectively and efficiently
+# Copyright (C) 2014-2017 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# 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/>.
+
+set -e
+
+MODE="$(basename ${0} | sed -e s'|^git-||' -e 's|-init$||')"
+
+DSCS="${@}"
+
+for DSC in ${DSCS}
+do
+ PACKAGE="$(basename ${DSC} .dsc | awk -F_ '{ print $1 }')"
+
+ dget --download-only "${DSC}"
+ dpkg-source -x --no-copy --skip-debianization $(basename ${DSC}) ${PACKAGE}
+
+ cd ${PACKAGE}
+ git init --shared
+ git commit -a -s -S -m "Initial commit." --allow-empty
+
+ VERSION="$(awk '/^Version: / { print $2 }' ../$(basename ${DSC}) | head -n1)"
+
+ FILE_VERSION="$(echo ${VERSION} | awk -F: '{ print $2 }')"
+ FILE_VERSION="${FILE_VERSION:-${VERSION}}"
+
+ if [ -e debian ]
+ then
+ mv debian ../debian.orig
+ fi
+
+ git-upstream-add ${VERSION}
+
+ git checkout -b debian
+
+ if [ -e ../debian.orig ]
+ then
+ mv ../debian.orig debian
+ fi
+
+ if [ -e ../${PACKAGE}_${FILE_VERSION}.diff.gz ]
+ then
+ zcat ../${PACKAGE}_${FILE_VERSION}.diff.gz | patch -Np1
+ fi
+
+ if ls ../${PACKAGE}_${FILE_VERSION}.debian.tar.* > /dev/null 2>&1
+ then
+ tar xf ../${PACKAGE}_${FILE_VERSION}.debian.tar.*
+ fi
+
+ git-debian-add
+
+ case "${MODE}" in
+ debian)
+ ;;
+
+ *)
+ git checkout -b ${MODE}
+ ;;
+ esac
+done
+
+exit 0
+
+ if [ "${MODE}" = "progress-linux" ]
+ then
+ if [ -e debian/control.in ]
+ then
+ CONTROL=debian/control.in
+ else
+ CONTROL=debian/control
+ fi
+
+ sed -i -e "s|^Maintainer: \(.*$\)|Maintainer: Progress Linux Maintainers <maintainers@lists.progress-linux.org>\nXSBC-Original-Maintainer: \1|" ${CONTROL}
+ git commit -a -s -S -m 'Updating maintainer field.'
+
+ if grep -qs "^Uploaders:" ${CONTROL}
+ then
+ sed -i -e "s|^Uploaders: \(.*$\)|XSBC-Uploaders: Daniel Baumann <daniel.baumann@progress-linux.org\nXSBC-Original-Uploaders: \1|" ${CONTROL}
+ else
+ sed -i -e "s|^\(Maintainer: .*$\)|\1\nXSBC-Uploaders: Daniel Baumann <daniel.baumann@progress-linux.org|" ${CONTROL}
+ fi
+
+ git commit -a -s -S -m "Updating uploaders field."
+
+ if grep -qs "^Bugs:" ${CONTROL}
+ then
+ sed -i -e "s|^Bugs: \(.*$\)|Bugs: mailto:bugs@lists.progress-linux.org\nXSBC-Original-Bugs: \1|" ${CONTROL}
+ else
+ sed -i -e "s|^\(Uploaders: .*$\)|\1\nBugs: mailto:bugs@lists.progress-linux.org|" ${CONTROL}
+ fi
+
+ git commit -a -s -S -m "Updating bugs field."
+
+
+
+
+ fi
+done
diff --git a/bin/git-debian-release b/bin/git-debian-release
new file mode 100755
index 0000000..9a7b4b7
--- /dev/null
+++ b/bin/git-debian-release
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+set -e
+
+GBP_CONF_FILES="/dev/null"
+export GBP_CONF_FILES
+
+if [ -n "$(git config --get user.signingKey)" ]
+then
+ GIT_OPTIONS="-S"
+fi
+
+if [ ! -e debian/changelog ]
+then
+ echo "E: debian/changelog - no such file" >&2
+ exit 1
+fi
+
+MODE="$(basename ${0} | sed -e 's|^git-||' -e 's|-release$||')"
+
+if [ -n "${1}" ]
+then
+ VERSION="${1}"
+else
+ VERSION="$(dpkg-parsechangelog | awk '/^Version: / { print $2 }')"
+fi
+
+HASH="${2}"
+
+git add -A
+
+git commit -a -s -m "Releasing ${MODE} version ${VERSION}." ${GIT_OPTIONS}
+git-${MODE}-tag ${VERSION} ${HASH}
diff --git a/bin/git-debian-tag b/bin/git-debian-tag
new file mode 100755
index 0000000..5afbc8c
--- /dev/null
+++ b/bin/git-debian-tag
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+set -e
+
+if [ -n "$(git config --get user.signingKey)" ]
+then
+ GIT_OPTIONS="-s"
+else
+ GIT_OPTIONS="-a"
+fi
+
+MODE="$(basename ${0} | sed -e 's|^git-||' -e 's|-tag$||')"
+
+VERSION="${1}"
+HASH="${2}"
+
+TAG="$(echo ${VERSION} | sed -e "s|^${MODE}/||" -e 's|:|%|g' -e 's|~|_|g')"
+
+git tag ${GIT_OPTIONS} -f -m "Tagging ${MODE} version ${VERSION}." ${MODE}/${TAG} ${HASH}
diff --git a/bin/git-dpkg-source b/bin/git-dpkg-source
new file mode 100755
index 0000000..cc06e3a
--- /dev/null
+++ b/bin/git-dpkg-source
@@ -0,0 +1,231 @@
+#!/bin/sh
+
+# source-tools - Manage Git repositories effectively and efficiently
+# Copyright (C) 2014-2017 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+
+set -e
+
+# FIXME: handle backports specific changelog entry.
+
+# Assumptions:
+#
+# * the repository is using pristine-tar for non-native packages.
+# * release commits, if any, are of the form 'Releasing debian version ...'.
+# * import commits, if any, are of the form 'Adding debian version ...'.
+# * the repository has at least either of a release or an import commit on the
+# target branch.
+# * and finally, the target branch is including upstream sources, not just
+# debianization. but that should be clear anyway.
+
+
+# Check depends
+for FILE in git git-dch dpkg-parsechangelog pristine-tar
+do
+ if [ ! -x "$(which ${FILE} 2>/dev/null)" ]
+ then
+ echo "${FILE} missing, aborting."
+ exit 1
+ fi
+done
+
+# Arguments
+if [ -z "${1}" ]
+then
+ echo "Usage: ${0} REPOSITORY [DISTRIBUTION] [BRANCH]"
+ exit 1
+fi
+
+REPOSITORY="${1}"
+DISTRIBUTION="${2:-UNRELEASED}"
+BRANCH="${3}"
+
+# Dynamic variables
+PACKAGE="$(basename ${REPOSITORY} .git)"
+
+# Static variables
+TEMPDIR="$(mktemp -d -t git-dpkg-source.XXXXXXXX)"
+CURDIR="${PWD}"
+
+################################################################################
+
+# Creating build directory
+mkdir -p "${TEMPDIR}"
+
+# Cloning sources
+cd "${TEMPDIR}"
+git clone ${REPOSITORY}
+
+# Checking out branch
+cd "${TEMPDIR}"/${PACKAGE}
+
+if [ -n "${BRANCH}" ] && [ ! "$(git branch | awk '/^\* / { print $2 }')" = "${BRANCH}" ] &&
+ [ -n "$(git branch -r | grep ${BRANCH}$ )" ]
+then
+ # user specified a branch because he wants to build what is not
+ # the default branch of his repository, also:
+ # we are not on that target branch, but the target branch exists,
+ # so we check it out and switch to it.
+ git checkout -b ${BRANCH} origin/${BRANCH} || true
+fi
+
+# Assemble version information
+VERSION="$(dpkg-parsechangelog | awk '/Version:/ { print $2 }' | sed -e 's|.*:||')"
+UPSTREAM_VERSION="$(echo ${VERSION} | sed -e 's|-.*||')"
+
+if echo $(dpkg-parsechangelog | awk '/Version:/ { print $2 }')| grep -q ":"
+then
+ EPOCHE="$(dpkg-parsechangelog | awk '/Version:/ { print $2 }' | awk -F: '{ print $1 }'):"
+else
+ EPOCHE=""
+fi
+
+# let's see if we have a newer upstream version checked in
+if git branch -r | grep -q pristine-tar
+then
+ TAR_VERSION="$(git show origin/pristine-tar | awk -F_ '/^\+\+\+(.*)tar.gz.id$/ { print $2 }' | sed -e 's|.orig.tar.gz.id||' -e 's|.tar.gz.id||')"
+fi
+
+DELIMETER=""
+
+if [ -n "${TAR_VERSION}" ] && [ "${UPSTREAM_VERSION}" != "${TAR_VERSION}" ]
+then
+ # there has been newer upstream version merged
+ # (means: head has newer upstream than last release commit)
+ VERSION="${TAR_VERSION}-"
+ UPSTREAM_VERSION="${TAR_VERSION}"
+ DELIMETER="~"
+else
+ VERSION="${VERSION}"
+fi
+
+# let's see if the last commit was a release or import commit.
+# FIXME: it's more generic to compare if the last commit matches any available tag.
+if [ -z "$(git log | grep -m1 Date -A2 | grep "Releasing debian version ")" ] && \
+ [ -z "$(git log | grep -m1 Date -A2 | grep "Adding debian version ")" ] && \
+ [ -z "$(git log | grep -m1 Date -A2 | grep "Releasing version ")"] && \
+ [ -z "$(git log | grep -m1 Date -A2 | grep "Adding version ")" ]
+then
+ # we are building a snapshot
+ if [ -z "${DELIMETER}" ]
+ then
+ DELIMETER="+"
+ fi
+
+ # building version string from date of last commit
+ REVISION="$(git log | grep -m1 Date | awk -FDate: '{ print $2 }' | awk '{ print $1 ",", $3, $2, $5, $4, $6 }')"
+ REVISION="${DELIMETER}$(date -d "${REVISION}" +%Y%m%d.%H%M%S)"
+else
+ # we are building a release
+ REVISION=""
+fi
+
+HASH="$(cd "${TEMPDIR}"/${PACKAGE} && git log | grep -m1 commit | awk '{ print $2 }')"
+
+# Renaming package directory (in case we are building native,
+# it would matter for cosemtics; if non-native it's ignored anyway)
+mv "${TEMPDIR}"/${PACKAGE} "${TEMPDIR}"/${PACKAGE}-${VERSION}${REVISION}
+
+# Creating changelog
+cd "${TEMPDIR}"/${PACKAGE}-${VERSION}${REVISION}
+
+if [ -z "${DEBFULLNAME}" ]
+then
+ if [ -n "$(git config --get user.name)" ]
+ then
+ # take name from git config
+ DEBFULLNAME="$(git config --get user.name)"
+ else
+ # or from last commit in the repository
+ DEBFULLNAME="$(git log | grep -m1 "^Author: " | sed -e 's|^Author: ||' -e 's| <.*>$||')"
+ fi
+fi
+
+if [ -z "${DEBEMAIL}" ]
+then
+ if [ -n "$(git config --get user.email)" ]
+ then
+ # take email from git config
+ DEBEMAIL="$(git config --get user.email)"
+ else
+ # or from last commit in the repository
+ DEBEMAIL="$(git log | grep -m1 "^Author: " | sed -e 's|^.*<||' -e 's|>$||')"
+ fi
+fi
+
+export DEBFULLNAME DEBEMAIL
+
+if [ -n "${REVISION}" ]
+then
+ # we are building a snapshot, let's get the hash of the last release
+ OLD_HASH="$(git log | grep -B4 -m1 'Releasing debian version ' | awk '/commit / { print $2 }')"
+ if [ -z "${OLD_HASH}" ]
+ then
+ # if there wasn't a release commit, maybe just have an import commit.
+ OLD_HASH="$(git log | grep -B4 -m1 'Adding debian version ' | awk '/commit / { print $2 }')"
+ fi
+
+ # Add git commit messages since the last release/import.
+ echo "Running git-dch..."
+ git-dch --debian-branch $(git branch | awk '/^\* / { print $2 }') --since ${OLD_HASH} --new-version ${EPOCHE}${VERSION}${REVISION}
+
+ # Create changelog top note.
+ HEADER="$(head -1 debian/changelog)"
+ sed -i -e '1 d' debian/changelog
+
+ mv debian/changelog debian/changelog.tmp
+
+#case "${DISTRIBUTION}" in
+# lenny-backports)
+#
+#cat > debian/changelog << EOF
+#${HEADER}
+#
+# * Rebuilding for Debian GNU/Linux 5.0 "lenny".
+#EOF
+#
+# ;;
+#
+# sid-snapshots)
+#
+cat > debian/changelog << EOF
+${HEADER}
+
+ * Unreleased snapshot from Git repository:
+ ${HASH}
+EOF
+
+# ;;
+#esac
+
+ cat debian/changelog.tmp >> debian/changelog
+ rm -f debian/changelog.tmp
+
+ dch --distribution ${DISTRIBUTION} --force-distribution --release ""
+# --append "Unreleased snapshot from Git repository: ${HASH}"
+else
+ # we are building a release
+
+ case "${DISTRIBUTION}" in
+ sid-snapshots)
+ dch --force-distribution --force-bad-version --newversion ${EPOCHE}${VERSION}${REVISION} --distribution ${DISTRIBUTION} "Rebuild release from Git repository: ${HASH}"
+ ;;
+ esac
+fi
+
+# Getting orig.tar.gz
+if [ -n "${TAR_VERSION}" ]
+then
+ # we have a non-native package
+ pristine-tar checkout ${PACKAGE}_${UPSTREAM_VERSION}.orig.tar.gz
+ mv ${PACKAGE}_${UPSTREAM_VERSION}.orig.tar.gz ../
+fi
+
+# Building package
+cd "${TEMPDIR}"/
+rm -rf ${PACKAGE}-${VERSION}${REVISION}/.git
+dpkg-source -b ${PACKAGE}-${VERSION}${REVISION}
+
+# Removing sources
+rm -rf ${PACKAGE}-${VERSION}${REVISION}
+mv * ${CURDIR}
+rm -rf "${TEMPDIR}"
diff --git a/bin/git-new.sh b/bin/git-new.sh
new file mode 100755
index 0000000..e5fe8ef
--- /dev/null
+++ b/bin/git-new.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+set -e
+
+if [ -z "${1}" ] || [ -z "${2}" ]
+then
+ echo "Usage: ${0} DISTRIBUTION PACKAGE"
+ exit 1
+fi
+
+CATEGORY="packages"
+
+DISTRIBUTION="${1}"
+shift 1
+
+PACKAGES="${@}"
+
+case "${DISTRIBUTION}" in
+ *-extras)
+ ORIGIN="progress-linux"
+ BRANCH="progress-linux"
+ ;;
+
+ *-backports)
+ ORIGIN="debian-backports"
+ BRANCH="progress-linux"
+ ;;
+
+ daniel*)
+ CATEGORY="users/daniel.baumann/debian/packages"
+ DISTRIBUTION=""
+ ORIGIN="debian"
+ BRANCH="debian"
+ ;;
+
+ *)
+ ORIGIN="debian"
+ BRANCH="progress-linux"
+ ;;
+esac
+
+for PACKAGE in ${PACKAGES}
+do
+ REPOSITORY="$(echo ${CATEGORY}/${DISTRIBUTION}/${PACKAGE} | sed -e 's|//|/|g')"
+
+ ssh git@git.progress-linux.org create ${REPOSITORY}
+ ssh git@git.progress-linux.org desc ${REPOSITORY} ${ORIGIN}: ${PACKAGE}
+ ssh git@git.progress-linux.org symbolic-ref ${REPOSITORY} HEAD refs/heads/${BRANCH}
+done
diff --git a/bin/git-progress-linux-add b/bin/git-progress-linux-add
new file mode 120000
index 0000000..eceef43
--- /dev/null
+++ b/bin/git-progress-linux-add
@@ -0,0 +1 @@
+git-debian-add \ No newline at end of file
diff --git a/bin/git-progress-linux-changelog b/bin/git-progress-linux-changelog
new file mode 120000
index 0000000..5153454
--- /dev/null
+++ b/bin/git-progress-linux-changelog
@@ -0,0 +1 @@
+git-debian-changelog \ No newline at end of file
diff --git a/bin/git-progress-linux-check b/bin/git-progress-linux-check
new file mode 120000
index 0000000..aa1c6f7
--- /dev/null
+++ b/bin/git-progress-linux-check
@@ -0,0 +1 @@
+git-debian-check \ No newline at end of file
diff --git a/bin/git-progress-linux-check.d b/bin/git-progress-linux-check.d
new file mode 120000
index 0000000..efb059c
--- /dev/null
+++ b/bin/git-progress-linux-check.d
@@ -0,0 +1 @@
+git-debian-check.d \ No newline at end of file
diff --git a/bin/git-progress-linux-init b/bin/git-progress-linux-init
new file mode 120000
index 0000000..dc32360
--- /dev/null
+++ b/bin/git-progress-linux-init
@@ -0,0 +1 @@
+git-debian-init \ No newline at end of file
diff --git a/bin/git-progress-linux-release b/bin/git-progress-linux-release
new file mode 120000
index 0000000..eda23ed
--- /dev/null
+++ b/bin/git-progress-linux-release
@@ -0,0 +1 @@
+git-debian-release \ No newline at end of file
diff --git a/bin/git-progress-linux-tag b/bin/git-progress-linux-tag
new file mode 120000
index 0000000..801085e
--- /dev/null
+++ b/bin/git-progress-linux-tag
@@ -0,0 +1 @@
+git-debian-tag \ No newline at end of file
diff --git a/bin/git-remove-origin-branches b/bin/git-remove-origin-branches
new file mode 100755
index 0000000..f65f037
--- /dev/null
+++ b/bin/git-remove-origin-branches
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+set -e
+
+BRANCHES="${@}"
+
+for BRANCH in ${BRANCHES}
+do
+ git push origin :${BRANCH}
+done
diff --git a/bin/git-remove-origin-tags b/bin/git-remove-origin-tags
new file mode 100755
index 0000000..8598409
--- /dev/null
+++ b/bin/git-remove-origin-tags
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+set -e
+
+TAGS="${@}"
+
+for TAG in ${TAGS}
+do
+ git push origin :refs/tags/${TAG}
+done
diff --git a/bin/git-repo-repack b/bin/git-repo-repack
new file mode 100755
index 0000000..9e733d2
--- /dev/null
+++ b/bin/git-repo-repack
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+set -e
+
+case "${1}" in
+ --quiet)
+ QUIET="true"
+ shift
+
+ GIT_REPACK_OPTIONS="-q"
+ GIT_GC_OPTIONS="--quiet"
+ ;;
+esac
+
+REPOSITORIES="${@}"
+
+if [ -z "${REPOSITORIES}" ]
+then
+ if [ ! -e HEAD ]
+ then
+ REPOSITORIES="*.git"
+ else
+ REPOSITORIES="$(pwd)"
+ fi
+fi
+
+for REPOSITORY in ${REPOSITORIES}
+do
+ [ "${QUIET}" ] || echo "--------------------------------------------------------------------------------"
+ [ "${QUIET}" ] || echo ${REPOSITORY}
+ [ "${QUIET}" ] || echo "--------------------------------------------------------------------------------"
+
+ cd "${REPOSITORY}"
+ git repack ${GIT_REPACK_OPTIONS} -a -b -d -f -F
+ git gc ${GIT_GC_OPTIONS} --aggressive --prune
+ cd "${OLDPWD}"
+
+ if [ "$(id -u)" -eq "0" ]
+ then
+ UID="$(stat -c %u ${REPOSITORY})"
+ GID="$(stat -c %g ${REPOSITORY})"
+
+ chown ${UID}:${GID} "${REPOSITORY}" -R
+ fi
+done
diff --git a/bin/git-upstream-add b/bin/git-upstream-add
new file mode 100755
index 0000000..b4a6a97
--- /dev/null
+++ b/bin/git-upstream-add
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+set -e
+
+if [ -n "$(git config --get user.signingKey)" ]
+then
+ GIT_OPTIONS="-S"
+fi
+
+VERSION="${1}"
+COMMIT="${2}"
+
+if [ -z "${VERSION}" ]
+then
+ echo "Usage: $(basename ${0}) VERSION"
+ exit 1
+fi
+
+if [ -d debian ]
+then
+ echo "'debian': directory exists, aborting."
+ exit 1
+fi
+
+if [ ! -d .git ]
+then
+ git init --shared
+fi
+
+git add -A -f
+git commit -a -s -m "Adding upstream version ${VERSION}." --allow-empty ${GIT_OPTIONS}
+git-upstream-tag ${VERSION} ${COMMIT}
+
+CURRENT_BRANCH="$(git branch --show-current)"
+
+if ! git branch | grep -qs upstream
+then
+ git branch -m ${CURRENT_BRANCH} upstream
+fi
diff --git a/bin/git-upstream-tag b/bin/git-upstream-tag
new file mode 100755
index 0000000..dd049d9
--- /dev/null
+++ b/bin/git-upstream-tag
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+set -e
+
+if [ -n "$(git config --get user.signingKey)" ]
+then
+ GIT_OPTIONS="-s"
+else
+ GIT_OPTIONS="-a"
+fi
+
+VERSION="${1}"
+COMMIT="${2}"
+
+TAG="$(echo ${VERSION} | sed -e 's|:|%|g' -e 's|~|_|g')"
+
+git tag ${GIT_OPTIONS} -f -m "Tagging upstream version ${VERSION}." upstream/${TAG} ${COMMIT}
diff --git a/bin/git-whoami b/bin/git-whoami
new file mode 100755
index 0000000..9cab9bc
--- /dev/null
+++ b/bin/git-whoami
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# git-whoami
+# Author: Peter Eisentraut <peter@eisentraut.org>
+# Created: 2011-10-27
+# License: WTFPL; see http://sam.zoy.org/wtfpl/
+
+# exact logic in ident.c in git source tree
+
+set -e
+
+get_email() {
+ git config user.email || ( [ -n "$EMAIL" ] && echo "$EMAIL" ) || echo "$(id -nu)@$(hostname --fqdn)"
+}
+
+get_name() {
+ git config user.name || getent passwd $(id -un) | cut -d : -f 5 | cut -d , -f 1
+}
+
+: ${GIT_AUTHOR_NAME=$(get_name)}
+: ${GIT_COMMITTER_NAME=$(get_name)}
+: ${GIT_AUTHOR_EMAIL=$(get_email)}
+: ${GIT_COMMITTER_EMAIL=$(get_email)}
+
+author="$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>"
+commit="$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
+
+if [ "$author" = "$commit" ]; then
+ echo "$author"
+else
+ echo "Author: $author"
+ echo "Commit: $commit"
+fi
diff --git a/bin/gpg-sig b/bin/gpg-sig
new file mode 100755
index 0000000..8aadca1
--- /dev/null
+++ b/bin/gpg-sig
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+set -e
+
+#KEY="4B2B2B9E" # Daniel Baumann (2004)
+KEY="55CF1BF986ABB9C7" # Daniel Baumann (2014)
+#KEY="E79FAE28" # Daniel Baumann (BFH)
+#KEY="2D9FA8F6" # Daniel Baumann (Open Infrastructure)
+KEY="F2B645DF11964018E7693B9F4613D5C794A6A9B2" # Daniel Baumann (Progress Linux)
+
+for FILE in $(find . -maxdepth 1 -mindepth 1 -type f -and -not -name "*.sha512" -and -not -name "*.gpg")
+do
+ if [ -e "${FILE}" ] && [ ! -e "${FILE}.gpg" ]
+ then
+ echo "${FILE}"
+ gpg --armor --default-key ${KEY} -b ${FILE}
+ mv "${FILE}.asc" "${FILE}.gpg"
+ touch -r "${FILE}" "${FILE}.gpg"
+ fi
+done
diff --git a/bin/gpg-sign b/bin/gpg-sign
new file mode 100755
index 0000000..561e654
--- /dev/null
+++ b/bin/gpg-sign
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+set -e
+
+for FILE in $(find . -maxdepth 1 -mindepth 1 -type f -and -not -name "*.sha512" -and -not -name "*.sig")
+do
+ if [ -e "${FILE}" ] && [ ! -e "${FILE}.sig" ]
+ then
+ echo "${FILE}"
+ gpg --armor -b "${FILE}"
+ mv "${FILE}".asc "${FILE}.sig"
+ touch -r "${FILE}" "${FILE}.sig"
+ fi
+done
diff --git a/bin/list-versions-engywuck-backports.sh b/bin/list-versions-engywuck-backports.sh
new file mode 100755
index 0000000..11db243
--- /dev/null
+++ b/bin/list-versions-engywuck-backports.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+DATE="20190706T233220Z"
+
+set -e
+
+if [ ! -e /tmp/list-versions_sources.buster ]
+then
+ for ARCHIVE_AREA in main contrib non-free
+ do
+ wget "http://snapshot.debian.org/archive/debian/${DATE}/dists/buster/${ARCHIVE_AREA}/source/Sources.xz" -O - | xz -c -d >> /tmp/list-versions_sources.buster
+ done
+fi
+
+if [ ! -e /tmp/list-versions_sources.sid ]
+then
+ for ARCHIVE_AREA in main contrib non-free
+ do
+ wget "http://debian.ethz.ch/debian/dists/sid/${ARCHIVE_AREA}/source/Sources.xz" -O - | xz -c -d >> /tmp/list-versions_sources.sid
+ done
+fi
+
+List ()
+{
+ PACKAGE="${@}"
+
+ BUSTER="$(sed -n "/^Package: ${PACKAGE}$/,/^Version:/p" /tmp/list-versions_sources.buster | awk '/^Version: / { print $2 }' | tail -n1)"
+ SID="$(sed -n "/^Package: ${PACKAGE}$/,/^Version:/p" /tmp/list-versions_sources.sid | awk '/^Version: / { print $2 }' | tail -n1)"
+
+ VERSIONS="$(wget -q http://snapshot.debian.org/package/${PACKAGE}/ -O - | grep '<li><a href=' | awk -F\> '{ print $3 }' | sed -e 's|<.*$||' | grep -v 'bpo' | grep -v 'deb[0-9]u')"
+ VERSIONS="$(echo ${VERSIONS} | sed -e "s|.*\(${SID}\)|\1|" -e "s|\(${BUSTER}\).*|\1|")"
+
+ clear
+ echo "Package: ${PACKAGE}"
+ echo
+ echo ${VERSIONS} | sed -e 's| |\n|g' | sort -V
+ echo
+ echo "# releases: $(echo ${VERSIONS} | sed -e 's| |\n|g' | wc -l)"
+ echo
+ echo "stable: ${BUSTER}"
+ echo "sid: ${SID}"
+ echo
+ echo
+}
+
+if [ -n "${1}" ]
+then
+ for DEB in ${@}
+ do
+ List ${DEB}
+ done
+else
+ while true
+ do
+ echo -n "Package: "
+ read DEB
+ echo
+
+ List ${DEB}
+
+ read input
+ done
+fi
diff --git a/bin/list-versions-engywuck.sh b/bin/list-versions-engywuck.sh
new file mode 100755
index 0000000..33bebc1
--- /dev/null
+++ b/bin/list-versions-engywuck.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+DATE="20190312T150955Z"
+
+set -e
+
+if [ ! -e /tmp/list-versions_sources.buster-freeze ]
+then
+ for ARCHIVE_AREA in main contrib non-free
+ do
+ wget "http://snapshot.debian.org/archive/debian/${DATE}/dists/buster/${ARCHIVE_AREA}/source/Sources.xz" -O - | xz -c -d >> /tmp/list-versions_sources.buster-freeze
+ done
+fi
+
+#if [ ! -e /tmp/list-versions_sources.buster-release ]
+#then
+# for ARCHIVE_AREA in main contrib non-free
+# do
+# wget "http://snapshot.debian.org/archive/debian/${DATE}/dists/buster/${ARCHIVE_AREA}/source/Sources.xz" -O - | xz -c -d >> /tmp/list-versions_sources.buster-release
+# done
+#fi
+
+if [ ! -e /tmp/list-versions_sources.buster-release ]
+then
+ for ARCHIVE_AREA in main contrib non-free
+ do
+ wget "http://debian.ethz.ch/debian/dists/sid/${ARCHIVE_AREA}/source/Sources.xz" -O - | xz -c -d >> /tmp/list-versions_sources.buster-release
+ done
+fi
+
+List ()
+{
+ PACKAGE="${@}"
+
+ FREEZE="$(sed -n "/^Package: ${PACKAGE}$/,/^Version:/p" /tmp/list-versions_sources.buster-freeze | awk '/^Version: / { print $2 }' | tail -n1)"
+ RELEASE="$(sed -n "/^Package: ${PACKAGE}$/,/^Version:/p" /tmp/list-versions_sources.buster-release | awk '/^Version: / { print $2 }' | tail -n1)"
+
+ VERSIONS="$(wget -q http://snapshot.debian.org/package/${PACKAGE}/ -O - | grep '<li><a href=' | awk -F\> '{ print $3 }' | sed -e 's|<.*$||' | grep -v 'bpo' | grep -v 'deb[0-9]u')"
+ VERSIONS="$(echo ${VERSIONS} | sed -e "s|.*\(${RELEASE}\)|\1|" -e "s|\(${FREEZE}\).*|\1|")"
+
+ clear
+ echo "Package: ${PACKAGE}"
+ echo
+ echo ${VERSIONS} | sed -e 's| |\n|g' | sort -V
+ echo
+ echo "# releases: $(echo ${VERSIONS} | sed -e 's| |\n|g' | wc -l)"
+ echo
+ echo "freeze: ${FREEZE}"
+ echo "release: ${RELEASE}"
+ echo
+ echo
+}
+
+if [ -n "${1}" ]
+then
+ for DEB in ${@}
+ do
+ List ${DEB}
+ done
+else
+ while true
+ do
+ echo -n "Package: "
+ read DEB
+ echo
+
+ List ${DEB}
+
+ read input
+ done
+fi
diff --git a/bin/list-versions_engywuck.sh b/bin/list-versions_engywuck.sh
new file mode 100755
index 0000000..1dafb41
--- /dev/null
+++ b/bin/list-versions_engywuck.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+DATE="20210206T105319Z" # 10.8 release
+
+set -e
+
+if [ ! -e /tmp/list-versions_sources.buster-freeze ]
+then
+ for ARCHIVE_AREA in main contrib non-free
+ do
+ wget "http://snapshot.debian.org/archive/debian/${DATE}/dists/buster/${ARCHIVE_AREA}/source/Sources.xz" -O - | xz -c -d >> /tmp/list-versions_sources.buster-freeze
+ done
+fi
+
+if [ ! -e /tmp/list-versions_sources.buster-release ]
+then
+ for ARCHIVE_AREA in main contrib non-free
+ do
+ wget "http://debian.ethz.ch/debian/dists/sid/${ARCHIVE_AREA}/source/Sources.xz" -O - | xz -c -d >> /tmp/list-versions_sources.buster-release
+ done
+fi
+
+List ()
+{
+ PACKAGE="${@}"
+
+ FREEZE="$(sed -n "/^Package: ${PACKAGE}$/,/^Version:/p" /tmp/list-versions_sources.buster-freeze | awk '/^Version: / { print $2 }' | tail -n1)"
+ RELEASE="$(sed -n "/^Package: ${PACKAGE}$/,/^Version:/p" /tmp/list-versions_sources.buster-release | awk '/^Version: / { print $2 }' | tail -n1)"
+
+ VERSIONS="$(wget -q http://snapshot.debian.org/package/${PACKAGE}/ -O - | grep '<li><a href=' | awk -F\> '{ print $3 }' | sed -e 's|<.*$||' | grep -v 'bpo' | grep -v 'deb[0-9]u')"
+ VERSIONS="$(echo ${VERSIONS} | sed -e "s|.*\(${RELEASE}\)|\1|" -e "s|\(${FREEZE}\).*|\1|")"
+
+ clear
+ echo "Package: ${PACKAGE}"
+ echo
+ echo ${VERSIONS} | sed -e 's| |\n|g' | sort -V
+ echo
+ echo "# releases: $(echo ${VERSIONS} | sed -e 's| |\n|g' | wc -l)"
+ echo
+ echo "freeze: ${FREEZE}"
+ echo "release: ${RELEASE}"
+ echo
+ echo
+}
+
+if [ -n "${1}" ]
+then
+ for DEB in ${@}
+ do
+ List ${DEB}
+ done
+else
+ while true
+ do
+ echo -n "Package: "
+ read DEB
+ echo
+
+ List ${DEB}
+
+ read input
+ done
+fi
diff --git a/bin/padd.sh b/bin/padd.sh
new file mode 100755
index 0000000..c561fc6
--- /dev/null
+++ b/bin/padd.sh
@@ -0,0 +1,160 @@
+#!/bin/sh
+
+set -e
+
+case "$(basename ${0})" in
+ p*)
+ MODE="progress-linux"
+ ;;
+
+ b*)
+ MODE="bfh"
+ ;;
+esac
+
+HOSTNAME="$(hostname -f)"
+
+RED="\033[1;33;31m"
+GREEN="\033[1;33;32m"
+YELLOW="\033[1;33;33m"
+BLUE="\033[1;33;34m"
+WHITE="\033[1;33;37m"
+NORMAL="\033[0m"
+PURPLE="\033[1;33;35m"
+
+case "${MODE}" in
+ progress-linux)
+ CHANNELS="progress-linux bfh-linux-systems"
+ ;;
+
+ bfh)
+ CHANNELS="bfh-linux-systems"
+ ;;
+esac
+
+Irk ()
+{
+ MESSAGE="${1}"
+
+ echo ${MESSAGE}
+
+ for CHANNEL in ${CHANNELS}
+ do
+ irk irc://irc.oftc.net:7000/${CHANNEL} ${MESSAGE}
+ done
+}
+
+ARCHITECTURES="arm64 armel armhf amd64 i386"
+
+case "$(basename ${PWD})" in
+ *_arm64)
+ _ARCH="arm64"
+ ;;
+
+ *_armel)
+ _ARCH="armel"
+ ;;
+
+ *_armhf)
+ _ARCH="armhf"
+ ;;
+
+ *_amd64)
+ _ARCH="amd64"
+ ;;
+
+ *_i386)
+ _ARCH="i386"
+ ;;
+
+ *_all)
+ _ARCH="all"
+ ;;
+
+ *_source)
+ _ARCH="source"
+ ;;
+esac
+
+#_DIST="$(cd ../../../ && echo $(basename ${PWD}))"
+
+case "${_ARCH}" in
+ source)
+ #_DIST="$(grep -m1 '^Distribution: ' *.dsc | awk '{ print $2 }')"
+ _DIST="$(pwd | awk -F/ '{ print $5 }')"
+ _PACKAGE="$(basename *.dsc .dsc | awk -F_ '{ print $1 }')"
+ ;;
+
+ *)
+ _DIST="$(grep -m1 '^Distribution: ' *.changes | awk '{ print $2 }')"
+ _PACKAGE="$(basename *.changes .changes | awk -F_ '{ print $1 }')"
+ ;;
+esac
+
+# HACK
+_POOL="/srv/${HOSTNAME}/packages"
+
+if ls *.dsc > /dev/null 2>&1
+then
+ echo "### Removing ${_PACKAGE} sources..."
+
+ # Remove source and binary upload
+ reprepro -b ${_POOL} removesrc ${_DIST} ${_PACKAGE} || true
+
+ # Include source upload
+ echo "### Including ${_PACKAGE} upload..."
+ reprepro -b ${_POOL} ${_REPREPRO_OPTIONS} includedsc ${_DIST} *.dsc
+else
+ #echo "### Removing ${_PACKAGE} binary..."
+ ## Remove binary upload
+ #reprepro -b ${_POOL} --architecture ${_ARCH} remove ${_DIST} ${_PACKAGE} || true
+
+ echo "### Including ${_PACKAGE} upload..."
+ reprepro -b ${_POOL} ${_REPREPRO_OPTIONS} include ${_DIST} *.changes
+fi
+
+if [ "${1}" != "quiet" ]
+then
+ case "${_ARCH}" in
+ source)
+ FILE="dsc"
+ ;;
+ *)
+ FILE="changes"
+ ;;
+ esac
+
+ _SOURCE="$(grep -m1 '^Source: ' *.${FILE} | awk '{ print $2 }')"
+ _VERSION="$(grep -m1 '^Version: ' *.${FILE} | awk '{ print $2 }')"
+ #_URGENCY="$(grep -m1 '^Urgency: ' *.${FILE} | awk '{ print $2 }')"
+ _URGENCY="$(grep -m1 '^Urgency: ' *.${FILE} | awk '{ print $2 }')"
+ #_DISTRIBUTION="$(grep -m1 '^Distribution: ' *.${FILE} | awk '{ print $2 }')"
+ _DISTRIBUTION="${_DIST}"
+ #_ARCHITECTURE="$(grep -m1 '^Architecture: ' *.${FILE} | awk '{ $1=""; print $0 }' | sed -e 's|^ ||')"
+ _ARCHITECTURE="${_ARCH}"
+
+ _UPLOADER="$(grep -m1 '^Changed-By: ' *.${FILE} | awk -F: '{ print $2 }' | sed -e 's|^ ||' -e 's|<.*||')"
+
+ case "${_ARCH}" in
+ source)
+ ;;
+
+ *)
+ if grep -qs '^Closes: ' *.changes
+ then
+ _BUGS="(Closes: ${PURPLE}$(grep -m1 '^Closes: ' *changes | sed -e 's|^Closes: |#|' -e "s| |\\\033\\[0m, \\\033\\[1;33;35m#|g")${NORMAL})"
+ fi
+ ;;
+ esac
+
+ case "${_ARCH}" in
+ source)
+ Irk "${GREEN}${_SOURCE}${NORMAL} ${_VERSION} [${_ARCHITECTURE}] uploaded to ${BLUE}${_DISTRIBUTION}${NORMAL}"
+ ;;
+
+ *)
+ Irk "${GREEN}${_SOURCE}${NORMAL} ${_VERSION} [${_ARCHITECTURE}] uploaded to ${BLUE}${_DISTRIBUTION}${NORMAL} with urgency ${RED}${_URGENCY}${NORMAL} by ${YELLOW}${_UPLOADER}${NORMAL}${_BUGS}"
+ ;;
+ esac
+ #twidge update "uploaded ${_SOURCE} ${_VERSION} to ${_DISTRIBUTION} #progress_linux"
+fi
diff --git a/bin/pbuild.sh b/bin/pbuild.sh
new file mode 100755
index 0000000..8dfd12e
--- /dev/null
+++ b/bin/pbuild.sh
@@ -0,0 +1,314 @@
+#!/bin/sh
+
+# Copyright (C) 2015 Daniel Baumann <mail@daniel-baumann.ch>
+#
+# 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/>.
+
+set -e
+
+case "$(basename ${0})" in
+ p*)
+ MODE="progress-linux"
+ ;;
+
+ b*)
+ MODE="bfh"
+ ;;
+esac
+
+PROGRAM="${0}"
+
+case "$(dpkg --print-architecture)" in
+# arm64)
+# CPUS="1"
+# export DEB_BUILD_OPTIONS=parallel=${CPUS}
+# ;;
+
+ *)
+ CPUS="$(nproc)"
+ export DEB_BUILD_OPTIONS=parallel=${CPUS}
+ ;;
+esac
+
+Parameters()
+{
+ LONG_OPTIONS="build:,distribution:,interactive,package:,tag:,"
+ OPTIONS="b:,d:,i,p:,t:,"
+
+ PARAMETERS="$(getopt --longoptions ${LONG_OPTIONS} --name=${PROGRAM} --options ${OPTIONS} --shell sh -- ${@})"
+
+ if [ "${?}" != "0" ]
+ then
+ echo "${PROGRAM}: getopt exit" >&2
+ exit 1
+ fi
+
+ eval set -- "${PARAMETERS}"
+
+ while true
+ do
+ case "${1}" in
+ -b|--build)
+ BUILD="${2}"
+ shift 2
+ ;;
+
+ -d|--distribution)
+ DISTRIBUTION="${2}"
+ shift 2
+ ;;
+
+ -i|--interactive)
+ INTERACTIVE="true"
+ shift 1
+ ;;
+
+ -p|--package)
+ PACKAGE="$(echo ${2} | sed -e 's|/$||g')"
+ shift 2
+ ;;
+
+ -t|--tag)
+ TAG="${2}"
+ shift 2
+ ;;
+
+ --)
+ shift
+ break
+ ;;
+
+ *)
+ echo "${PROGRAM}: getopt error" >&2
+ exit 1
+ ;;
+ esac
+ done
+}
+
+Parameters "${@}"
+
+if [ -z "${DISTRIBUTION}" ] || [ -z "${PACKAGE}" ]
+then
+ echo "Usage: ${PROGRAM} [-b|--build BUILD] -d|--distribution DISTRIBUTION -p|--package PACKAGE -t|--tag TAG" >&2
+ exit 1
+fi
+
+INTERACTIVE="${INTERACTIVE:=false}"
+
+if [ -e "${PACKAGE}" ]
+then
+ echo "${PACKAGE}: directory already exists"
+ exit 1
+fi
+
+if [ -z "${BUILD}" ]
+then
+ case "$(dpkg --print-architecture)" in
+ amd64) # FIXME
+ BUILD="source,binary-arch,binary-indep"
+ ;;
+
+ arm*|i386) # FIXME
+ BUILD="binary-arch"
+ ;;
+ esac
+fi
+
+TARGET="${PACKAGE}"
+
+case "${MODE}" in
+ progress-linux)
+ REPOSITORY="https://git.progress-linux.org/packages/${DISTRIBUTION}/${PACKAGE}"
+ BRANCH="progress-linux"
+ SERVER="https://apt.progress-linux.org"
+ ;;
+
+ bfh)
+ REPOSITORY="https://git.bfh.science/packages/${DISTRIBUTION}/${PACKAGE}"
+ BRANCH="bfh"
+ SERVER="https://apt.bfh.science"
+ ;;
+esac
+
+for BUILD in $(echo ${BUILD} | sed -e 's|,| |g')
+do
+ echo "################################################################################"
+ echo "Building ${BUILD} ($(dpkg --print-architecture)) package: ${PACKAGE} ${VERSION}"
+ echo "################################################################################"
+
+ case "${BUILD}" in
+ source)
+ if [ -n "${TAG}" ]
+ then
+ GIT_BRANCH="${TAG}"
+ git clone --branch ${GIT_BRANCH} "${REPOSITORY}" "${TARGET}"
+ else
+ GIT_BRANCH="${BRANCH}"
+ #git clone --depth 1 --no-single-branch --branch ${GIT_BRANCH} "${REPOSITORY}" "${TARGET}"
+ git clone --no-single-branch --branch ${GIT_BRANCH} "${REPOSITORY}" "${TARGET}"
+ fi
+
+ cd "${TARGET}"
+
+ VERSION="$(dpkg-parsechangelog | awk '/^Version: / { print $2 }')"
+
+ SOURCE_VERSION="$(echo ${VERSION} | awk -F: '{ print $2 }')"
+ SOURCE_VERSION="${SOURCE_VERSION:-${VERSION}}"
+
+ UPSTREAM_VERSION="$(echo ${SOURCE_VERSION} | awk -F- '{ $NF=""; print $0 }' | sed -e 's| |-|g' -e 's|-$||')"
+
+ if [ -z "${UPSTREAM_VERSION}" ] && echo "${SOURCE_VERSION}" | grep -qs '+progress[0-9]*'
+ then
+ UPSTREAM_VERSION="$(echo ${SOURCE_VERSION} | awk -F\\+progress '{ print $1 }')"
+ fi
+
+ if [ -z "${UPSTREAM_VERSION}" ] && echo "${SOURCE_VERSION}" | grep -qs '+bfh[0-9]*'
+ then
+ UPSTREAM_VERSION="$(echo ${SOURCE_VERSION} | awk -F\\+bfh '{ print $1 }')"
+ fi
+
+ rm -rf .git
+ mv debian ../
+ cd "${OLDPWD}"
+
+ mv "${TARGET}" "${TARGET}-${UPSTREAM_VERSION}"
+
+ for DISTRIBUTION in engywuck fuchur
+ do
+ if [ ! -e "${TARGET}_${UPSTREAM_VERSION}.orig.tar.xz" ]
+ then
+ wget ${SERVER}/archive/$(echo ${DISTRIBUTION} | cut -d- -f 1)/${PACKAGE}/orig/${TARGET}_${UPSTREAM_VERSION}.orig.tar.xz || true
+ if [ ! -e ${TARGET}_${UPSTREAM_VERSION}.orig.tar.xz ]
+ then
+ wget ${SERVER}/archive/$(echo ${DISTRIBUTION} | cut -d- -f 1)-backports/${PACKAGE}/orig/${TARGET}_${UPSTREAM_VERSION}.orig.tar.xz || true
+ if [ ! -e ${TARGET}_${UPSTREAM_VERSION}.orig.tar.xz ]
+ then
+ wget ${SERVER}/archive/$(echo ${DISTRIBUTION} | cut -d- -f 1)-extras/${PACKAGE}/orig/${TARGET}_${UPSTREAM_VERSION}.orig.tar.xz || true
+ if [ ! -e ${TARGET}_${UPSTREAM_VERSION}.orig.tar.xz ]
+ then
+ wget ${SERVER}/archive/$(echo ${DISTRIBUTION} | cut -d- -f 1)-backports-extras/${PACKAGE}/orig/${TARGET}_${UPSTREAM_VERSION}.orig.tar.xz || true
+ fi
+ fi
+ fi
+ fi
+ done
+
+ if [ ! -e "${TARGET}_${UPSTREAM_VERSION}.orig.tar.xz" ]
+ then
+ echo "Creating ${TARGET}_${UPSTREAM_VERSION}.orig.tar.xz ..."
+ tar cfJ "${TARGET}_${UPSTREAM_VERSION}.orig.tar.xz" "${TARGET}-${UPSTREAM_VERSION}"
+ else
+ echo "Using existing ${TARGET}_${UPSTREAM_VERSION}.orig.tar.xz ..."
+ fi
+
+ mv debian "${TARGET}-${UPSTREAM_VERSION}"
+ dpkg-source -b "${TARGET}-${UPSTREAM_VERSION}"
+
+ rm -rf "${TARGET}-${UPSTREAM_VERSION}"
+ ;;
+
+ binary*)
+ rm -f /tmp/control
+ CONTROL="${REPOSITORY}/plain/debian/control"
+ wget -q ${CONTROL} -O /tmp/control
+
+ case "${BUILD}" in
+ binary-arch)
+ if ! grep -qs "^Architecture:.* any" /tmp/control && \
+ ! grep -qs "^Architecture:.* linux-any" /tmp/control && \
+ ! grep -qs "^Architecture:.* $(dpkg --print-architecture)" /tmp/control
+ then
+ echo "NO BINARY_ARCH, skipping."
+ continue
+ fi
+ ;;
+
+ binary-indep)
+ if ! grep -qs '^Architecture:.*all' /tmp/control
+ then
+ echo "NO BINARY_INDEP, skipping."
+ continue
+ fi
+ ;;
+ esac
+
+ if [ -n "${TAG}" ]
+ then
+ GIT_BRANCH="${TAG}"
+ git clone --branch ${GIT_BRANCH} "${REPOSITORY}" "${TARGET}"
+ else
+ GIT_BRANCH="${BRANCH}"
+ #git clone --depth 1 --no-single-branch --branch ${GIT_BRANCH} "${REPOSITORY}" "${TARGET}"
+ git clone --no-single-branch --branch ${GIT_BRANCH} "${REPOSITORY}" "${TARGET}"
+ fi
+
+ cd "${TARGET}"
+
+ rm -rf .git
+
+ VERSION="$(dpkg-parsechangelog | awk '/^Version: / { print $2 }')"
+
+ SOURCE_VERSION="$(echo ${VERSION} | awk -F: '{ print $2 }')"
+ SOURCE_VERSION="${SOURCE_VERSION:-${VERSION}}"
+
+ UPSTREAM_VERSION="$(echo ${SOURCE_VERSION} | awk -F- '{ $NF=""; print $0 }' | sed -e 's| |-|g' -e 's|-$||')"
+
+ SOURCE="${TARGET}-$(echo ${SOURCE_VERSION} | sed -e 's|~|_|g' -e 's|+|.|g')"
+
+ cd ..
+ mv "${TARGET}" "${SOURCE}"
+ cd "${SOURCE}"
+
+ # disable tests
+ for TARGET in dh_auto_test dh_auto_test-arch dh_auto_test-indep \
+ override_dh_auto_test override_dh_auto_test-arch override_dh_auto_test-indep \
+ execute_before_dh_auto_test execute_before_dh_auto_test-arch execute_before_dh_auto_test-indep \
+ execute_after_dh_auto_test execute_after_dh_auto_test-arch execute_after_dh_auto_test-indep
+ do
+ if grep -qs "^${TARGET}:" debian/rules
+ then
+ sed -i -e "s|^${TARGET}:|disabled_${TARGET}:|" debian/rules
+ else
+ echo "${TARGET}:" >> debian/rules
+ fi
+ done
+
+ case "${INTERACTIVE}" in
+ true)
+ echo "${PROGRAM}: WAITING... "
+ read waiting
+ ;;
+ esac
+
+ case "${BUILD}" in
+ binary-any)
+ dpkg-buildpackage -sa -us -uc
+ ;;
+
+ binary-arch)
+ dpkg-buildpackage -B -us -uc
+ ;;
+
+ binary-indep)
+ dpkg-buildpackage -A -us -uc
+ ;;
+ esac
+
+ cd "${OLDPWD}"
+
+ rm -rf "${SOURCE}"
+ ;;
+ esac
+done
diff --git a/bin/pget.sh b/bin/pget.sh
new file mode 100755
index 0000000..d94a12d
--- /dev/null
+++ b/bin/pget.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+
+set -e
+
+case "$(basename ${0})" in
+ p*)
+ MODE="progress-linux"
+ ;;
+
+ b*)
+ MODE="bfh"
+ ;;
+esac
+
+CURDIR="${PWD}"
+
+DSCS="${@}"
+
+for DSC in ${DSCS}
+do
+ URL="$(echo ${DSC} | sed -e 's|%2B|+|g' -e 's|%7E|~|g')"
+
+ PACKAGE="$(basename ${URL} .dsc | awk -F_ '{ print $1 }')"
+
+ if [ "$(basename ${PWD})" != "${PACKAGE}" ]
+ then
+ mkdir -p "${PACKAGE}"
+ cd "${PACKAGE}"
+ fi
+
+ VERSION="$(wget -q ${URL} -O - | grep -m1 '^Version: ' | awk '{ print $2 }')"
+
+ SOURCE_VERSION="$(echo ${VERSION} | awk -F: '{ print $2 }')"
+ SOURCE_VERSION="${SOURCE_VERSION:-${VERSION}}"
+
+ UPSTREAM_VERSION="$(echo ${SOURCE_VERSION} | awk -F- '{ $NF=""; print $0 }' | sed -e 's| |-|g' -e 's|-$||')"
+
+ mkdir "${VERSION}"
+
+ cd "${VERSION}"
+
+ for ORIG in $(ls ../orig/${PACKAGE}_${UPSTREAM_VERSION}.orig.tar.* ../orig/${PACKAGE}_${UPSTREAM_VERSION}.orig-*.tar.* 2>/dev/null)
+ do
+ if [ -e "${ORIG}" ]
+ then
+ ln -s "${ORIG}" ./
+ fi
+ done
+
+ /usr/bin/dget --download-only "${URL}"
+
+ for ORIG in $(ls ${PACKAGE}_${UPSTREAM_VERSION}.orig.tar.* ${PACKAGE}_${UPSTREAM_VERSION}.orig-*.tar.* 2>/dev/null)
+ do
+ if [ -e "${ORIG}" ] && [ ! -h "${ORIG}" ]
+ then
+ mkdir -p ../orig
+ mv "${ORIG}" ../orig
+
+ ln -s ../orig/"${ORIG}" .
+ fi
+ done
+
+ cd ..
+ rm -f current
+ ln -s "${VERSION}" current
+
+ cd "${CURDIR}"
+done
diff --git a/bin/pimport.sh b/bin/pimport.sh
new file mode 100755
index 0000000..27b74cb
--- /dev/null
+++ b/bin/pimport.sh
@@ -0,0 +1,534 @@
+#!/bin/sh
+
+set -e
+
+case "$(basename ${0})" in
+ p*)
+ MODE="progress-linux"
+ ;;
+
+ b*)
+ MODE="bfh"
+ ;;
+esac
+
+case "${MODE}" in
+ progress-linux)
+ MAINTAINER="Progress Linux Maintainers <maintainers@lists.progress-linux.org>"
+ UPLOADERS="Daniel Baumann <daniel.baumann@progress-linux.org>"
+ BUGS="mailto:maintainers@lists.progress-linux.org"
+
+ if echo ${PWD} | grep -qs engywuck-backports
+ then
+ VCS_BROWSER="https://git.progress-linux.org/packages/engywuck-backports"
+ VCS_GIT="https://git.progress-linux.org/packages/engywuck-backports"
+ elif echo ${PWD} | grep -qs fuchur-backports
+ then
+ VCS_BROWSER="https://git.progress-linux.org/packages/fuchur-backports"
+ VCS_GIT="https://git.progress-linux.org/packages/fuchur-backports"
+ elif echo ${PWD} | grep -qs engywuck
+ then
+ VCS_BROWSER="https://git.progress-linux.org/packages/engywuck"
+ VCS_GIT="https://git.progress-linux.org/packages/engywuck"
+ elif echo ${PWD} | grep -qs fuchur
+ then
+ VCS_BROWSER="https://git.progress-linux.org/packages/fuchur"
+ VCS_GIT="https://git.progress-linux.org/packages/fuchur"
+ else
+ VCS_BROWSER="https://git.progress-linux.org/packages/engywuck-backports"
+ VCS_GIT="https://git.progress-linux.org/packages/engywuck-backports"
+ fi
+
+ DOWNSTREAM_BRANCH="progress-linux"
+ ;;
+
+ bfh)
+ MAINTAINER="Team Linux \& Infrastructure Services <bfh-linux-sysadmin@lists.bfh.science>"
+ UPLOADERS="Daniel Baumann <daniel.baumann@bfh.ch>"
+ BUGS="mailto:bfh-linux-users@lists.bfh.science"
+
+ VCS_BROWSER="https://git.bfh.science/packages/buster-backports"
+ VCS_GIT="https://git.bfh.science/packages/buster-backports"
+
+ DOWNSTREAM_BRANCH="bfh"
+ ;;
+esac
+
+RED="\033[1;33;31m"
+GREEN="\033[1;33;32m"
+YELLOW="\033[1;33;33m"
+BLUE="\033[1;33;34m"
+WHITE="\033[1;33;37m"
+NORMAL="\033[0m"
+PURPLE="\033[1;33;35m"
+
+DSC="${1}"
+
+case "${DSC}" in
+ *.dsc)
+ ;;
+
+ *)
+ echo "Usage: ${0} DSC"
+ exit 1
+ ;;
+esac
+
+case "${DSC}" in
+ http*)
+ DSC_TEMPDIR="$(mktemp -d)"
+
+ cd "${DSC_TEMPDIR}"
+ dget -d "${DSC}"
+ cd "${OLDPWD}"
+
+ DSC="${DSC_TEMPDIR}/$(basename ${DSC})"
+ ;;
+esac
+
+PACKAGE="$(basename ${DSC} | awk -F_ '{ print $1 }')"
+DEB_VERSION="$(awk '/^Version: / { print $2 }' ${DSC})"
+
+case "${DEB_VERSION}" in
+ *-*)
+ DEB_UPSTREAM_VERSION="$(echo ${DEB_VERSION} | awk -F- '{ $NF=""; print $0 }' | sed -e 's| |-|g' -e 's|-$||g')"
+ ;;
+
+ *)
+ DEB_UPSTREAM_VERSION="${DEB_VERSION}"
+ ;;
+esac
+
+Add_initial_commit ()
+{
+ if [ ! -e .git ]
+ then
+ git init --shared
+ fi
+
+ if ! git log > /dev/null 2>&1
+ then
+ echo
+ echo "################################################################################"
+ echo "git: adding initial commit"
+ echo "################################################################################"
+
+ git commit -a -s -S -m "Initial commit." --allow-empty
+ fi
+}
+
+Create_upstream_branch ()
+{
+ CURRENT_BRANCH="$(git branch --show-current)"
+
+ case "${CURRENT_BRANCH}" in
+ master|main)
+ if ! git branch | grep -qs upstream
+ then
+ echo
+ echo "################################################################################"
+ echo "git: adding upstream branch"
+ echo "################################################################################"
+
+ git branch -m ${CURRENT_BRANCH} upstream
+ fi
+ ;;
+ esac
+}
+
+Switch_upstream_branch ()
+{
+ CURRENT_BRANCH="$(git branch --show-current)"
+
+ if [ "${CURRENT_BRANCH}" != "upstream" ] && git branch | grep -qs upstream
+ then
+ echo
+ echo "################################################################################"
+ echo "git: switching to upstream branch"
+ echo "################################################################################"
+
+ git checkout upstream
+ fi
+}
+
+Remove_everything ()
+{
+ echo
+ echo "################################################################################"
+ echo "git: removing all files"
+ echo "################################################################################"
+
+ echo -n "Removing files for new import..."
+
+ find . -maxdepth 1 -mindepth 1 -and -not -name .git -print0 | xargs -0 -I '{}' rm -rf '{}'
+
+ echo " done."
+}
+
+Unpack_upstream ()
+{
+ echo
+ echo "################################################################################"
+ echo "dpkg: unpacking upstream files"
+ echo "################################################################################"
+
+ TEMPDIR="$(mktemp -d -p . -u)"
+
+ dpkg-source -x --no-copy --skip-debianization ${DSC} "${TEMPDIR}"
+ rm -rf "${TEMPDIR}/debian"
+ find "${TEMPDIR}" -type d -name ".git" -exec rm -rf {} \; || true
+
+ DEBIAN_TAR="$(dirname $(readlink -f ${DSC}))/$(awk '/debian.tar.*$/ { print $3 }' ${DSC} | head -n1)"
+
+ case "${DEBIAN_TAR}" in
+ *.debian.tar.*)
+ if [ -e "${DEBIAN_TAR}" ]
+ then
+ # this includes upstream additions outside debian/ into the upstream branch
+ cd "${TEMPDIR}"
+ tar xf "${DEBIAN_TAR}"
+ rm -rf debian
+ rm -rf .git
+ cd "${OLDPWD}"
+ fi
+ ;;
+ esac
+
+ find "${TEMPDIR}" -maxdepth 1 -mindepth 1 -print0 | xargs -0 -I '{}' mv '{}' .
+ rmdir "${TEMPDIR}"
+}
+
+Add_upstream_version ()
+{
+ echo
+ echo "################################################################################"
+ echo "git: adding upstream version"
+ echo "################################################################################"
+
+ # FIXME
+ git-upstream-add ${DEB_UPSTREAM_VERSION}
+}
+
+Create_debian_branch ()
+{
+ echo
+ echo "################################################################################"
+ echo "git: creating debian branch"
+ echo "################################################################################"
+
+ CURRENT_BRANCH="$(git branch --show-current)"
+
+ if [ "${CURRENT_BRANCH}" = "upstream" ] && ! git branch | grep -qs debian
+ then
+ git branch debian
+ fi
+}
+
+Switch_debian_branch ()
+{
+ CURRENT_BRANCH="$(git branch --show-current)"
+
+ if [ "${CURRENT_BRANCH}" != "debian" ] && git branch | grep -qs debian
+ then
+ echo
+ echo "################################################################################"
+ echo "git: switching to debian branch"
+ echo "################################################################################"
+
+ git checkout debian
+ fi
+}
+
+Unpack_debian ()
+{
+ echo
+ echo "################################################################################"
+ echo "dpkg: unpacking debian files"
+ echo "################################################################################"
+
+ TEMPDIR="$(mktemp -d -p . -u)"
+
+ dpkg-source -x --no-copy --skip-patches ${DSC} ${TEMPDIR}
+ find "${TEMPDIR}" -type d -name ".git" -exec rm -rf {} \; || true
+
+ find "${TEMPDIR}" -maxdepth 1 -mindepth 1 -print0 | xargs -0 -I '{}' mv '{}' .
+
+ rmdir ${TEMPDIR}
+}
+
+Add_debian_version ()
+{
+ echo
+ echo "################################################################################"
+ echo "git: adding debian version"
+ echo "################################################################################"
+
+ # FIXME
+ git-debian-add
+}
+
+Create_downstream_branch ()
+{
+ echo
+ echo "################################################################################"
+ echo "git: create ${DOWNSTREAM_BRANCH} branch"
+ echo "################################################################################"
+
+ CURRENT_BRANCH="$(git branch --show-current)"
+
+ if [ "${CURRENT_BRANCH}" = "debian" ] && ! git branch | grep -qs ${DOWNSTREAM_BRANCH}
+ then
+ git checkout -b ${DOWNSTREAM_BRANCH}
+ fi
+}
+
+Update_maintainer_field ()
+{
+ if [ -e debian/templates/control.source.in ]
+ then
+ CONTROL="debian/templates/control.source.in"
+ elif [ -e debian/control.in ]
+ then
+ CONTROL="debian/control.in"
+ else
+ CONTROL="debian/control"
+ fi
+
+ if ! grep -qs "^XSBC-Original-Maintainer: ${MAINTAINER}$" "${CONTROL}"
+ then
+ echo
+ echo "################################################################################"
+ echo "git: updating maintainer field"
+ echo "################################################################################"
+
+ if grep -qs "^Uploaders:" "${CONTROL}"
+ then
+ # sorting maintainer and uploaders fields
+ ORIGINAL_MAINTAINER="$(grep '^Maintainer:' ${CONTROL})"
+
+ # remove original maintainer field
+ TEMPFILE="$(mktemp -p .)"
+ grep -v "^Maintainer:" "${CONTROL}" > "${TEMPFILE}"
+ rm -f "${CONTROL}"
+ mv "${TEMPFILE}" "${CONTROL}"
+
+ # readd original maintainer field
+ sed -i -e "s|^\(Uploaders.*\)$|${ORIGINAL_MAINTAINER}\n\1|" \
+ "${CONTROL}"
+ fi
+
+ sed -i -e "s|^Maintainer:|Maintainer: ${MAINTAINER}\nXSBC-Original-Maintainer:|" "${CONTROL}"
+
+ git commit -a -s -S -m "Updating maintainer field."
+ fi
+
+ if [ -n "$(grep -s -r "^Maintainer:" debian | grep -v ^debian\/control)" ]
+ then
+ echo "WARNING: additional 'Maintainer:' fields outside debian/control{,.in} found!"
+ fi
+}
+
+Update_uploaders_field ()
+{
+ if [ -e debian/templates/control.source.in ]
+ then
+ CONTROL="debian/templates/control.source.in"
+ elif [ -e debian/control.in ]
+ then
+ CONTROL="debian/control.in"
+ else
+ CONTROL="debian/control"
+ fi
+
+ # FIXME: single uploader on one line, no multi-line
+ if ! grep -qs "^XSBC-Uploaders: ${UPLOADERS}$" "${CONTROL}"
+ then
+ echo
+ echo "################################################################################"
+ echo "git: updating uploaders field"
+ echo "################################################################################"
+
+ sed -i -e "s|^\(Maintainer:.*$\)|\1\nXSBC-Uploaders: ${UPLOADERS}|" \
+ -e "s|^Uploaders:|XSBC-Original-Uploaders:|" \
+ "${CONTROL}"
+
+ git commit -a -s -S -m "Updating uploaders field."
+ fi
+
+ if [ -n "$(grep -s -r "^Uploaders:" debian | grep -v ^debian\/control)" ]
+ then
+ echo "WARNING: additional 'Uploaders:' fields outside debian/control{,.in} found!"
+ fi
+}
+
+Update_bugs_field ()
+{
+ if [ -e debian/templates/control.source.in ]
+ then
+ CONTROL="debian/templates/control.source.in"
+ elif [ -e debian/control.in ]
+ then
+ CONTROL="debian/control.in"
+ else
+ CONTROL="debian/control"
+ fi
+
+ if ! grep -qs "^Bugs: ${BUGS}$" "${CONTROL}"
+ then
+ echo
+ echo "################################################################################"
+ echo "git: updating bugs field"
+ echo "################################################################################"
+
+ # remove original bugs fields
+ TEMPFILE="$(mktemp -p .)"
+ grep -v "^Bugs:" "${CONTROL}" > "${TEMPFILE}"
+ rm -f "${CONTROL}"
+ mv "${TEMPFILE}" "${CONTROL}"
+
+ # add new bugs field
+ if grep -qs "^XSBC-Original-Uploaders:" "${CONTROL}"
+ then
+ NEXT_FIELD_AFTER_UPLOADERS="$(grep -v '^ ' ${CONTROL} | grep -v '^ ' | grep -A1 -m1 '^XSBC-Original-Uploaders:' | tail -n1 | awk -F: '{ print $1 }')"
+ else
+ NEXT_FIELD_AFTER_UPLOADERS="$(grep -v '^ ' ${CONTROL} | grep -v '^ ' | grep -A1 -m1 '^XSBC-Original-Maintainer:' | tail -n1 | awk -F: '{ print $1 }')"
+ fi
+
+ case "${NEXT_FIELD_AFTER_UPLOADERS}" in
+ Package:*)
+ LAST_LINE_OF_SOURCE_BLOCK="$(grep -B2 -m1 '^Package:' ${CONTROL} | head -n1)"
+
+ sed -i -e "s|\(^${LAST_LINE_OF_SOURCE_BLOCK}$\)|\1\nBugs: ${BUGS}|" \
+ "${CONTROL}"
+ ;;
+
+ *)
+ sed -i -e "s|^\(${NEXT_FIELD_AFTER_UPLOADERS}\)|Bugs: ${BUGS}\n\1|" \
+ "${CONTROL}"
+ ;;
+ esac
+
+ git commit -a -s -S -m "Updating bugs field."
+ fi
+}
+
+Update_vcs_fields ()
+{
+ if [ -e debian/templates/control.source.in ]
+ then
+ CONTROL="debian/templates/control.source.in"
+ elif [ -e debian/control.in ]
+ then
+ CONTROL="debian/control.in"
+ else
+ CONTROL="debian/control"
+ fi
+
+ if ! grep -qs "^Vcs-Browser: ${VCS_BROWSER}/${PACKAGE}$" "${CONTROL}" && \
+ ! grep -qs "^Vcs-Git: ${VCS_BROWSER}/${PACKAGE}$" "${CONTROL}"
+ then
+ echo
+ echo "################################################################################"
+ echo "git: updating vcs fields"
+ echo "################################################################################"
+
+ sed -i -e 's|^Vcs-browser|Vcs-Browser|' \
+ -e 's|^Vcs-git|Vcs-Git|' \
+ "${CONTROL}"
+
+ # replace original vcs fields
+ sed -i -e 's|^Vcs-|XSBC-Original-Vcs-|g' \
+ "${CONTROL}"
+
+ if ! grep -qs "^XSBC-Original-Vcs-" "${CONTROL}"
+ then
+ # no vcs in original file
+ LAST_LINE_OF_SOURCE_BLOCK="$(grep -B2 -m1 '^Package:' ${CONTROL} | head -n1)"
+
+ sed -i -e "s|\(^${LAST_LINE_OF_SOURCE_BLOCK}.*$\)|\1\nVcs-Browser: ${VCS_BROWSER}/${PACKAGE}\nVcs-Git: ${VCS_GIT}/${PACKAGE}|" \
+ "${CONTROL}"
+ else
+ # vcs fields in original file
+ ORIGINAL_VCS_BROWSER="$(grep '^XSBC-Original-Vcs-Browser' ${CONTROL})"
+
+ TEMPFILE="$(mktemp -p . -u)"
+ grep -v "^XSBC-Original-Vcs-Browser" "${CONTROL}" > "${TEMPFILE}"
+ rm -f "${CONTROL}"
+ mv "${TEMPFILE}" "${CONTROL}"
+
+ # FIXME: handle cases where only Vcs-Browser is there, but no Vcs-Git
+ ORIGINAL_VCS_OTHER="$(grep '^XSBC-Original-Vcs' ${CONTROL})"
+ sed -i -e "s|^\(XSBC-Original-Vcs-.*\)$|Vcs-Browser: ${VCS_BROWSER}/${PACKAGE}\nVcs-Git: ${VCS_GIT}/${PACKAGE}\n${ORIGINAL_VCS_BROWSER}\n\1|" \
+ "${CONTROL}"
+ fi
+ fi
+
+ if [ -n "$(git status --porcelain)" ]
+ then
+ git commit -a -s -S -m "Updating vcs fields."
+ fi
+}
+
+Update_source_format ()
+{
+ if ! grep -qs '^3.0 (quilt)' debian/source/format
+ then
+ echo
+ echo "################################################################################"
+ echo "git: updating source format"
+ echo "################################################################################"
+
+ mkdir -p debian/source
+ echo "3.0 (quilt)" > debian/source/format
+
+ git add .
+ git commit -a -s -S -m "Updating source format."
+ fi
+}
+
+echo "################################################################################"
+echo "git: importing ${DSC}"
+echo "################################################################################"
+
+Add_initial_commit
+
+Create_upstream_branch
+Switch_upstream_branch
+Remove_everything
+Unpack_upstream
+Add_upstream_version
+
+Create_debian_branch
+Switch_debian_branch
+Remove_everything
+Unpack_debian
+Add_debian_version
+
+if [ -n "${DSC_TEMPDIR}" ]
+then
+ rm -rf "${DSC_TEMPDIR}"
+fi
+
+Create_downstream_branch
+
+Update_maintainer_field
+Update_uploaders_field
+Update_bugs_field
+Update_vcs_fields
+Update_source_format
+
+if [ -e debian/control.in ] || [ -e debian/templates/control.source.in ] || [ -e debian/control.md5sum ]
+then
+ echo "################################################################################"
+ echo "${RED}WARNING:${NORMAL} debian/control.in exists,"
+ echo "likely the debian files need to be regenerated (manually)."
+ echo "################################################################################"
+fi
+
+if [ "$(grep -rs '^Maintainer:' debian | wc -l )" -gt 1 ]
+then
+ echo "################################################################################"
+ echo "${RED}WARNING:${NORMAL} more than one Maintainer field exists,"
+ echo "likely further debian files need to be changed (manually)."
+ echo "################################################################################"
+fi
diff --git a/bin/pmove.sh b/bin/pmove.sh
new file mode 100755
index 0000000..a3e18c5
--- /dev/null
+++ b/bin/pmove.sh
@@ -0,0 +1,144 @@
+#!/bin/sh
+
+set -e
+
+case "$(basename ${0})" in
+ p*)
+ MODE="progress-linux"
+ ;;
+
+ b*)
+ MODE="bfh"
+ ;;
+esac
+
+CURDIR="${PWD}"
+
+HOST="$(hostname -f)"
+UPLOAD="/srv/${HOST}/upload"
+
+for ARCHITECTURE in amd64 arm64 armel armhf i386 all
+do
+ if ! ls ${UPLOAD}/*_${ARCHITECTURE}.changes > /dev/null 2>&1
+ then
+ continue
+ fi
+
+ CHANGES="$(ls ${UPLOAD}/*_${ARCHITECTURE}.changes)"
+
+ PACKAGE="$(basename ${CHANGES} .changes | awk -F_ '{ print $1 }')"
+
+ if [ "$(basename ${PWD})" != "${PACKAGE}" ]
+ then
+ mkdir -p "${PACKAGE}"
+ cd "${PACKAGE}"
+ fi
+
+ VERSION="$(grep -m1 '^Version: ' ${CHANGES} | awk '{ print $2 }')"
+
+ SOURCE_VERSION="$(echo ${VERSION} | awk -F: '{ print $2 }')"
+ SOURCE_VERSION="${SOURCE_VERSION:-${VERSION}}"
+
+ UPSTREAM_VERSION="$(echo ${SOURCE_VERSION} | awk -F- '{ $NF=""; print $0 }' | sed -e 's| |-|g' -e 's|-$||')"
+
+ mkdir "${VERSION}_${ARCHITECTURE}"
+
+ cd "${VERSION}_${ARCHITECTURE}"
+
+ if ls ${UPLOAD}/*_${ARCHITECTURE}.deb > /dev/null 2>&1
+ then
+ mv ${UPLOAD}/*_${ARCHITECTURE}.deb .
+ fi
+ if ls ${UPLOAD}/*_${ARCHITECTURE}.udeb > /dev/null 2>&1
+ then
+ mv ${UPLOAD}/*_${ARCHITECTURE}.udeb .
+ fi
+ if ls ${UPLOAD}/*_${ARCHITECTURE}.buildinfo > /dev/null 2>&1
+ then
+ mv ${UPLOAD}/*_${ARCHITECTURE}.buildinfo .
+
+ # FIXING buildinfo file
+ sed -i -e '/^ DEB_BUILD_OPTIONS="/d' \
+ -e 's|^ LANG="en_US.UTF-8"| LANG="C.UTF-8"|' \
+ *_${ARCHITECTURE}.buildinfo
+ fi
+ mv ${UPLOAD}/*_${ARCHITECTURE}.changes .
+ reprepro_fix-changes.sh *_${ARCHITECTURE}.changes
+
+ case "${MODE}" in
+ progress-linux)
+ psign.sh
+ ;;
+
+ bfh)
+ bsign.sh
+ ;;
+ esac
+
+ cd ..
+ rm -f current_${ARCHITECTURE}
+ ln -s "${VERSION}_${ARCHITECTURE}" current_${ARCHITECTURE}
+
+ cd "${CURDIR}"
+done
+
+for DSC in ${UPLOAD}/*.dsc
+do
+ if [ ! -e "${DSC}" ]
+ then
+ break
+ fi
+
+ PACKAGE="$(basename ${DSC} .dsc | awk -F_ '{ print $1 }')"
+
+ if [ "$(basename ${PWD})" != "${PACKAGE}" ]
+ then
+ mkdir -p "${PACKAGE}"
+ cd "${PACKAGE}"
+ fi
+
+ VERSION="$(grep -m1 '^Version: ' ${DSC} | awk '{ print $2 }')"
+
+ SOURCE_VERSION="$(echo ${VERSION} | awk -F: '{ print $2 }')"
+ SOURCE_VERSION="${SOURCE_VERSION:-${VERSION}}"
+
+ UPSTREAM_VERSION="$(echo ${SOURCE_VERSION} | awk -F- '{ $NF=""; print $0 }' | sed -e 's| |-|g' -e 's|-$||')"
+
+ mkdir "${VERSION}_source"
+
+ cd "${VERSION}_source"
+
+ if ls ../orig/${PACKAGE}_${UPSTREAM_VERSION}.orig.tar.xz > /dev/null 2>&1
+ then
+ ln -s ../orig/${PACKAGE}_${UPSTREAM_VERSION}.orig.tar.xz ./
+ fi
+
+ mv ${UPLOAD}/*.dsc .
+ mv ${UPLOAD}/*.orig.tar.xz .
+ mv ${UPLOAD}/*.debian.tar.xz .
+
+ case "${MODE}" in
+ progress-linux)
+ psign.sh
+ ;;
+
+ bfh)
+ bsign.sh
+ ;;
+ esac
+
+ if ls ${PACKAGE}_${UPSTREAM_VERSION}.orig.tar.xz > /dev/null 2>&1 && \
+ [ ! -h "${PACKAGE}_${UPSTREAM_VERSION}.orig.tar.xz" ]
+ then
+ mkdir -p ../orig
+
+ mv "$(ls ${PACKAGE}_${UPSTREAM_VERSION}.orig.tar.*)" ../orig
+ ln -s $(ls ../orig/${PACKAGE}_${UPSTREAM_VERSION}.orig.tar.*) ./
+ fi
+
+ cd ..
+ rm -f current_source
+ ln -s "${VERSION}_source" current_source
+
+ cd "${CURDIR}"
+done
diff --git a/bin/psign.sh b/bin/psign.sh
new file mode 100755
index 0000000..7762087
--- /dev/null
+++ b/bin/psign.sh
@@ -0,0 +1,108 @@
+#!/bin/sh
+
+set -e
+
+case "$(basename ${0})" in
+ p*)
+ MODE="progress-linux"
+ ;;
+
+ b*)
+ MODE="bfh"
+ ;;
+esac
+
+for CHANGES in *.changes
+do
+ if [ ! -e "${CHANGES}" ]
+ then
+ continue
+ fi
+
+ DISTRIBUTION="$(grep -s -m1 '^Distribution: ' ${CHANGES} | awk '{ print $2 }')"
+
+ case "${MODE}" in
+ progress-linux)
+ case "${DISTRIBUTION}" in
+ engywuck*)
+ DESCRIPTION="Progress Linux 5 (engywuck) Archive Key"
+ KEY="0x03CED5154316222A"
+ ;;
+
+ fuchur*)
+ DESCRIPTION="Progress Linux 6 (fuchur) Archive Key"
+ KEY="0x753373FBB95C4EA6"
+ ;;
+
+ graograman*)
+ DESCRIPTION="Progress Linux 7 (graograman) Archive Key"
+ KEY=""
+ ;;
+
+ *)
+ # Debian
+ DESCRIPTION="Daniel Baumann (2014) Key"
+ KEY="55CF1BF986ABB9C7"
+ ;;
+ esac
+ ;;
+
+ bfh)
+ DESCRIPTION="BFH (2018) Key"
+ KEY="0xBFEEA48634831878"
+ ;;
+ esac
+
+ echo "Signing ${CHANGES} with: ${DESCRIPTION}"
+ debsign -k${KEY} --re-sign ${CHANGES}
+done
+
+for DSC in *.dsc
+do
+ if [ ! -e "${DSC}" ]
+ then
+ continue
+ fi
+
+ #DISTRIBUTION="$(grep -s -m1 '^Distribution: ' $(echo $PWD | sed -e 's|_source|_all|')/*.changes | awk '{ print $2 }')"
+ #DISTRIBUTION="${DISTRIBUTION:-$(grep -s -m1 '^Distribution: ' $(echo $PWD | sed -e 's|_source|_amd64|')/*.changes | awk '{ print $2 }')}"
+ #DISTRIBUTION="${DISTRIBUTION:-$(grep -s -m1 '^Distribution: ' $(echo $PWD | sed -e 's|_source|_i386|')/*.changes | awk '{ print $2 }')}"
+ #DISTRIBUTION="$(echo ${DISTRIBUTION} | awk '{ print $1 }')"
+
+ DISTRIBUTION="$(awk '/^Vcs-Git:/ { print $2 }' *dsc | awk -F/ '{ print $5 }')"
+
+ case "${MODE}" in
+ progress-linux)
+ case "${DISTRIBUTION}" in
+ engywuck*)
+ DESCRIPTION="Progress Linux 5 (engywuck) Archive Key"
+ KEY="0x03CED5154316222A"
+ ;;
+
+ fuchur*)
+ DESCRIPTION="Progress Linux 6 (fuchur) Archive Key"
+ KEY="0x753373FBB95C4EA6"
+ ;;
+
+ graograman*)
+ DESCRIPTION="Progress Linux 7 (graograman) Archive Key"
+ KEY=""
+ ;;
+
+ *)
+ # Debian
+ DESCRIPTION="Daniel Baumann (2014) Key"
+ KEY="55CF1BF986ABB9C7"
+ ;;
+ esac
+ ;;
+
+ bfh)
+ DESCRIPTION="BFH (2018) Key"
+ KEY="0xBFEEA48634831878"
+ ;;
+ esac
+
+ echo "Signing ${DSC} with: ${DESCRIPTION}"
+ debsign -k${KEY} --re-sign ${DSC}
+done
diff --git a/bin/pupdate.sh b/bin/pupdate.sh
new file mode 100755
index 0000000..463b5af
--- /dev/null
+++ b/bin/pupdate.sh
@@ -0,0 +1,265 @@
+#!/bin/sh
+
+set -e
+
+case "$(basename ${0})" in
+ p*)
+ MODE="progress-linux"
+ ;;
+
+ b*)
+ MODE="bfh"
+ ;;
+esac
+
+case "${MODE}" in
+ progress-linux)
+ DOWNSTREAM_BRANCH="progress-linux"
+ ;;
+
+ bfh)
+ DOWNSTREAM_BRANCH="bfh"
+ ;;
+esac
+
+RED="\033[1;33;31m"
+GREEN="\033[1;33;32m"
+YELLOW="\033[1;33;33m"
+BLUE="\033[1;33;34m"
+WHITE="\033[1;33;37m"
+NORMAL="\033[0m"
+PURPLE="\033[1;33;35m"
+
+DSC="${1}"
+
+case "${DSC}" in
+ *.dsc)
+ ;;
+
+ *)
+ echo "Usage: ${0} DSC"
+ exit 1
+ ;;
+esac
+
+case "${DSC}" in
+ http*)
+ DSC_TEMPDIR="$(mktemp -d)"
+
+ cd "${DSC_TEMPDIR}"
+ dget -d "${DSC}"
+ cd "${OLDPWD}"
+
+ DSC="${DSC_TEMPDIR}/$(basename ${DSC})"
+ ;;
+esac
+
+PACKAGE="$(basename ${DSC} | awk -F_ '{ print $1 }')"
+DEB_VERSION="$(awk '/^Version: / { print $2 }' ${DSC})"
+
+case "${DEB_VERSION}" in
+ *-*)
+ DEB_UPSTREAM_VERSION="$(echo ${DEB_VERSION} | awk -F- '{ $NF=""; print $0 }' | sed -e 's| |-|g' -e 's|-$||g')"
+ ;;
+
+ *)
+ DEB_UPSTREAM_VERSION="${DEB_VERSION}"
+ ;;
+esac
+
+Switch_upstream_branch ()
+{
+ CURRENT_BRANCH="$(git branch --show-current)"
+
+ if [ "${CURRENT_BRANCH}" != "upstream" ] && git branch | grep -qs upstream
+ then
+ echo
+ echo "################################################################################"
+ echo "git: switching to upstream branch"
+ echo "################################################################################"
+
+ git checkout upstream
+ fi
+}
+
+Remove_everything ()
+{
+ echo
+ echo "################################################################################"
+ echo "git: removing all files"
+ echo "################################################################################"
+
+ echo -n "Removing files for new import..."
+
+ find . -maxdepth 1 -mindepth 1 -and -not -name .git -print0 | xargs -0 -I '{}' rm -rf '{}'
+
+ echo " done."
+}
+
+Unpack_upstream ()
+{
+ echo
+ echo "################################################################################"
+ echo "dpkg: unpacking upstream files"
+ echo "################################################################################"
+
+ TEMPDIR="$(mktemp -d -p . -u)"
+
+ dpkg-source -x --no-copy --skip-debianization ${DSC} "${TEMPDIR}"
+ rm -rf "${TEMPDIR}/debian"
+ find "${TEMPDIR}" -type d -name ".git" -exec rm -rf {} \; || true
+
+ DEBIAN_TAR="$(dirname $(readlink -f ${DSC}))/$(awk '/debian.tar.*$/ { print $3 }' ${DSC} | head -n1)"
+
+ case "${DEBIAN_TAR}" in
+ *.debian.tar.*)
+ if [ -e "${DEBIAN_TAR}" ]
+ then
+ # this includes upstream additions outside debian/ into the upstream branch
+ cd "${TEMPDIR}"
+ tar xf "${DEBIAN_TAR}"
+ rm -rf debian
+ rm -rf .git
+ cd "${OLDPWD}"
+ fi
+ ;;
+ esac
+
+ find "${TEMPDIR}" -maxdepth 1 -mindepth 1 -print0 | xargs -0 -I '{}' mv '{}' .
+ rmdir "${TEMPDIR}"
+}
+
+Add_upstream_version ()
+{
+ echo
+ echo "################################################################################"
+ echo "git: adding upstream version"
+ echo "################################################################################"
+
+ # FIXME
+ git-upstream-add ${DEB_UPSTREAM_VERSION}
+}
+
+Switch_debian_branch ()
+{
+ CURRENT_BRANCH="$(git branch --show-current)"
+
+ if [ "${CURRENT_BRANCH}" != "debian" ] && git branch | grep -qs debian
+ then
+ echo
+ echo "################################################################################"
+ echo "git: switching to debian branch"
+ echo "################################################################################"
+
+ git checkout debian
+ fi
+}
+
+Unpack_debian ()
+{
+ echo
+ echo "################################################################################"
+ echo "dpkg: unpacking debian files"
+ echo "################################################################################"
+
+ TEMPDIR="$(mktemp -d -p . -u)"
+
+ dpkg-source -x --no-copy --skip-patches ${DSC} ${TEMPDIR}
+ find "${TEMPDIR}" -type d -name ".git" -exec rm -rf {} \; || true
+
+ find "${TEMPDIR}" -maxdepth 1 -mindepth 1 -print0 | xargs -0 -I '{}' mv '{}' .
+
+ rmdir ${TEMPDIR}
+}
+
+Add_debian_version ()
+{
+ echo
+ echo "################################################################################"
+ echo "git: adding debian version"
+ echo "################################################################################"
+
+ # FIXME
+ git-debian-add
+}
+
+Switch_downstream_branch ()
+{
+ CURRENT_BRANCH="$(git branch --show-current)"
+
+ if [ "${CURRENT_BRANCH}" != "${DOWNSTREAM_BRANCH}" ] && git branch | grep -qs ${DOWNSTREAM_BRANCH}
+ then
+ echo
+ echo "################################################################################"
+ echo "git: switching to downstream branch"
+ echo "################################################################################"
+
+ git checkout ${DOWNSTREAM_BRANCH}
+ fi
+}
+
+Merge_upstream_version ()
+{
+ git cherry-pick -n upstream
+ git commit -a -s -S -m "Merging upstream version ${DEB_UPSTREAM_VERSION}."
+}
+
+Merge_debian_version ()
+{
+ git cherry-pick -n debian
+ git commit -a -s -S -m "Merging debian version ${DEB_VERSION}."
+}
+
+echo "################################################################################"
+echo "git: importing ${DSC}"
+echo "################################################################################"
+
+GIT_UPSTREAM_VERSION="$(git tag | awk -F/ '/^upstream\// { print $2 }' | sort -rV | head -n1 | sed -e 's|%|:|g' -e 's|_|~|g')"
+
+if [ "${DEB_UPSTREAM_VERSION}" != "${GIT_UPSTREAM_VERSION}" ]
+then
+ Switch_upstream_branch
+
+ Remove_everything
+ Unpack_upstream
+ Add_upstream_version
+
+ MERGE_UPSTREAM="true"
+fi
+
+GIT_DEBIAN_VERSION="$(git tag | awk -F/ '/^debian\// { print $2 }' | sort -rV | head -n1 | sed -e 's|%|:|g' -e 's|_|~|g')"
+
+if [ "${DEB_VERSION}" != "${GIT_DEBIAN_VERSION}" ]
+then
+ Switch_debian_branch
+
+ case "${MERGE_UPSTREAM}" in
+ true)
+ Merge_upstream_version
+ ;;
+ esac
+
+ Remove_everything
+ Unpack_debian
+ Add_debian_version
+
+ MERGE_DEBIAN="true"
+fi
+
+if [ -n "${DSC_TEMPDIR}" ]
+then
+ rm -rf "${DSC_TEMPDIR}"
+fi
+
+if [ "${MERGE_DEBIAN}" = "true" ]
+then
+ Switch_downstream_branch
+
+ case "${MERGE_UPSTREAM}" in
+ true)
+ Merge_upstream_version
+ ;;
+ esac
+
+ Merge_debian_version
+fi
diff --git a/bin/pupload.sh b/bin/pupload.sh
new file mode 100755
index 0000000..f0b872c
--- /dev/null
+++ b/bin/pupload.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+set -e
+
+case "$(basename ${0})" in
+ p*)
+ MODE="progress-linux"
+ ;;
+
+ b*)
+ MODE="bfh"
+ ;;
+esac
+
+if [ -z "${@}" ]
+then
+ echo "Usage: ${0} PACKAGE|\"PACKAGES\""
+ exit 1
+fi
+
+if [ -n "${QUIET}" ]
+then
+ QUIET="--quiet"
+fi
+
+PACKAGES="$(echo ${@} | sed -e 's|/||g')"
+
+for PACKAGE in ${PACKAGES}
+do
+ cd "${PACKAGE}"
+
+ for ARCHITECTURE in source amd64 i386 arm64 armel armhf all
+ do
+ if [ -e "current_${ARCHITECTURE}" ]
+ then
+ cd "current_${ARCHITECTURE}"
+
+ case "${MODE}" in
+ progress-linux)
+ padd.sh ${QUIET}
+ ;;
+
+ bfh)
+ badd.sh ${QUIET}
+ ;;
+ esac
+
+ cd ..
+ fi
+ done
+
+ cd ..
+done
diff --git a/bin/reprepro_add.sh b/bin/reprepro_add.sh
new file mode 100755
index 0000000..2fe3c89
--- /dev/null
+++ b/bin/reprepro_add.sh
@@ -0,0 +1,76 @@
+#!/bin/sh
+
+set -e
+
+HOSTNAME="$(hostname -f)"
+
+Irk ()
+{
+ MESSAGE="${1}"
+
+ for CHANNEL in progress-linux bfh-linux-systems
+ do
+ irk irc://irc.oftc.net:7000/${CHANNEL} ${MESSAGE}
+ done
+}
+
+case "$(basename ${PWD})" in
+ *_arm64)
+ _ARCH="arm64"
+ ;;
+
+ *_armel)
+ _ARCH="armel"
+ ;;
+
+ *_armhf)
+ _ARCH="armhf"
+ ;;
+
+ *_amd64)
+ _ARCH="amd64"
+ ;;
+
+ *_i386)
+ _ARCH="i386"
+ ;;
+
+ *_all)
+ _ARCH="all"
+ ;;
+esac
+
+#_DIST="$(cd ../../../ && echo $(basename ${PWD}))"
+_DIST="$(grep -m1 '^Distribution: ' *.changes | awk '{ print $2 }')"
+
+_PACKAGE="$(basename *.changes .changes | awk -F_ '{ print $1 }')"
+
+# HACK
+_POOL="/srv/${HOSTNAME}/packages"
+
+if ls *.dsc > /dev/null 2>&1
+then
+ echo "### Removing ${_PACKAGE} sources..."
+
+ # Remove source and binary upload
+ reprepro -b ${_POOL} removesrc ${_DIST} $(basename *.changes .changes | awk -F_ '{ print $1 }') || true
+else
+ echo "### Removing ${_PACKAGE} binary..."
+
+ # Remove binary upload
+ reprepro -b ${_POOL} --architecture ${_ARCH} remove ${_DIST} $(basename *.changes .changes | awk -F_ '{ print $1 }') || true
+fi
+
+echo "### Including ${_PACKAGE} upload..."
+reprepro -b ${_POOL} ${_REPREPRO_OPTIONS} include ${_DIST} *.changes
+
+if [ "${1}" != "quiet" ]
+then
+ _SOURCE="$(grep -m1 '^Source: ' *.changes | awk '{ print $2 }')"
+ _VERSION="$(grep -m1 '^Version: ' *.changes | awk '{ print $2 }')"
+ _URGENCY="$(grep -m1 '^Urgency: ' *.changes | awk '{ print $2 }')"
+ _DISTRIBUTION="$(grep -m1 '^Distribution: ' *.changes | awk '{ print $2 }')"
+ _ARCHITECTURE="$(grep -m1 '^Architecture: ' *.changes | awk '{ $1=""; print $0 }' | sed -e 's|^ ||')"
+
+ Irk "\x0300archive-master:\x03 \x0303${_SOURCE}\x03 \x0310${_VERSION}\x03 uploaded with urgency \x0307${_URGENCY}\x03 to \x0312${_DISTRIBUTION}\x03 (${_ARCHITECTURE}) \x0305http://sources.progress-linux.org/gitweb/?p=releases/${_DISTRIBUTION}/packages/${_SOURCE}.git\x03"
+fi
diff --git a/bin/reprepro_check-buildinfo.sh b/bin/reprepro_check-buildinfo.sh
new file mode 100755
index 0000000..14b8223
--- /dev/null
+++ b/bin/reprepro_check-buildinfo.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+set -e
+
+echo -n "Checking "
+
+for BUILDINFO in */*/*.buildinfo
+do
+ if grep 'TERM=' "${BUILDINFO}"
+ then
+ echo
+ echo "${BUILDINFO}: fix TERM="
+ fi
+
+ if ! grep '^Build-Date: .* +0000$' "${BUILDINFO}"
+ then
+ echo
+ echo "${BUILDINFO}: fix Build-Date"
+ fi
+
+ if ! grep -qs "^Build-Path: .*progress[0-9]u[0-9]$" "${BUILDINFO}" && \
+ ! grep -qs "^Build-Path: .*progress[0-9]+u[0-9]$" "${BUILDINFO}"
+ then
+ echo
+ echo "${BUILDINFO}: fix Build-Path"
+ fi
+
+ if grep -qs '^ DEB_BUILD_OPTIONS=' "${BUILDINFO}"
+ then
+ echo
+ echo "${BUILDINFO}: fix DEB_BUILD_OPTIONS"
+ fi
+
+ if ! grep -qs '^ LANG="C.UTF-8"' "${BUILDINFO}"
+ then
+ echo
+ echo "${BUILDINFO}: missing LANG"
+ fi
+
+ if ! grep -qs '^ LC_ALL="C.UTF-8"' "${BUILDINFO}"
+ then
+ echo
+ echo "${BUILDINFO}: missing LC_ALL"
+ fi
+
+ echo -n "."
+done
+
+echo " done."
diff --git a/bin/reprepro_fix-changes.sh b/bin/reprepro_fix-changes.sh
new file mode 100755
index 0000000..ae35550
--- /dev/null
+++ b/bin/reprepro_fix-changes.sh
@@ -0,0 +1,139 @@
+#!/bin/sh
+
+set -e
+
+CHANGELOGS="${@:-*/packages/*/*/*.changes}"
+
+echo -n "Fixing "
+
+Fix_size ()
+{
+ CHANGES="${1}"
+ BUILDINFO="${2}"
+
+ OLD_SIZE="$(grep " [0-9]* $(basename ${BUILDINFO})$" ${CHANGES} | head -n1 | awk '{ print $2 }')"
+ NEW_SIZE="$(ls -l ${BUILDINFO} | awk '{ print $5 }')"
+
+ if [ -n "${OLD_SIZE}" ] && [ -n "${NEW_SIZE}" ] && grep -qs " ${OLD_SIZE} " "${CHANGES}"
+ then
+ sed -i -e "s| ${OLD_SIZE} | ${NEW_SIZE} |g" "${CHANGES}"
+
+ cd "$(dirname ${CHANGES})"
+ echo "Signing ${CHANGES}"
+
+ if grep -qs progress-linux.org ${CHANGES}
+ then
+ psign.sh > /dev/null 2>&1
+ elif grep -qs bfh.ch ${CHANGES}
+ then
+ bsign.sh > /dev/null 2>&1
+ fi
+ cd "${OLDPWD}"
+ fi
+}
+
+Fix_hashsums ()
+{
+ CHANGES="${1}"
+ BUILDINFO="${2}"
+ SIZE="${3}"
+
+ for HASHSUM in $(grep " ${SIZE} " "${CHANGES}")
+ do
+ OLD_HASH="$(echo ${HASHSUM} | awk '{ print $1 }')"
+ NEW_HASH=""
+
+ case $(echo ${OLD_HASH} | wc -c) in
+ 41)
+ NEW_HASH="$(sha1sum ${BUILDINFO} | awk '{ print $1 }')"
+ ;;
+
+ 65)
+ NEW_HASH="$(sha256sum ${BUILDINFO} | awk '{ print $1 }')"
+ ;;
+
+ 33)
+ NEW_HASH="$(md5sum ${BUILDINFO} | awk '{ print $1 }')"
+ ;;
+ esac
+
+ if [ -n "${NEW_HASH}" ] && ! grep -qs "^ ${NEW_HASH} ${SIZE} " "${CHANGES}"
+ then
+ sed -i -e "s|^ ${OLD_HASH} ${SIZE}| ${NEW_HASH} ${SIZE}|" "${CHANGES}"
+
+ cd "$(dirname ${CHANGES})"
+ echo "Signing ${CHANGES}"
+ psign.sh > /dev/null 2>&1
+ cd "${OLDPWD}"
+ fi
+ done
+}
+
+for CHANGES in ${CHANGELOGS}
+do
+ BUILDINFO="$(echo ${CHANGES} | sed -e 's|.changes$|.buildinfo|')"
+
+ if grep -qs usr-local-has-programs "${BUILDINFO}" && grep -qs merged-usr-via-symlinks "${BUILDINFO}"
+ then
+ grep -v usr-local-has-programs "${BUILDINFO}" > "${BUILDINFO}".tmp
+ rm -f "${BUILDINFO}"
+ mv "${BUILDINFO}".tmp "${BUILDINFO}"
+ else
+ if grep -qs usr-local-has-programs "${BUILDINFO}" && ! grep -qs merged-usr-via-symlinks "${BUILDINFO}"
+ then
+ sed -i -e 's|usr-local-has-programs|merged-usr-via-symlinks|' "${BUILDINFO}"
+ fi
+ fi
+
+ if grep -qs DEB_BUILD_OPTIONS= "${BUILDINFO}"
+ then
+ grep -v DEB_BUILD_OPTIONS= "${BUILDINFO}" > "${BUILDINFO}".tmp
+ rm -f "${BUILDINFO}"
+ mv "${BUILDINFO}".tmp "${BUILDINFO}"
+ fi
+
+ if [ ! -e "${BUILDINFO}" ]
+ then
+ continue
+ fi
+
+ SIZE="$(ls -l ${BUILDINFO} | awk '{ print $5 }')"
+
+ if [ $(grep -c ".* ${SIZE} .*$(basename ${BUILDINFO})" ${CHANGES}) -ne 3 ]
+ then
+ echo
+ echo "${CHANGES}: fix buildinfo size"
+ Fix_size ${CHANGES} ${BUILDINFO}
+ fi
+
+ SHA1SUM="$(sha1sum ${BUILDINFO} | awk '{ print $1 }')"
+
+ if ! grep -qs "^ ${SHA1SUM} ${SIZE} $(basename ${BUILDINFO})$" "${CHANGES}"
+ then
+ echo
+ echo "${CHANGES}: fix buildinfo sha1"
+ Fix_hashsums ${CHANGES} ${BUILDINFO} ${SIZE}
+ fi
+
+ SHA256SUM="$(sha256sum ${BUILDINFO} | awk '{ print $1 }')"
+
+ if ! grep -qs "^ ${SHA256SUM} ${SIZE} $(basename ${BUILDINFO})$" "${CHANGES}"
+ then
+ echo
+ echo "${CHANGES}: fix buildinfo sha256"
+ Fix_hashsums ${CHANGES} ${BUILDINFO} ${SIZE}
+ fi
+
+ MD5SUM="$(md5sum ${BUILDINFO} | awk '{ print $1 }')"
+
+ if ! grep -qs "^ ${MD5SUM} ${SIZE} .*$(basename ${BUILDINFO})$" "${CHANGES}"
+ then
+ echo
+ echo "${CHANGES}: fix buildinfo md5"
+ Fix_hashsums ${CHANGES} ${BUILDINFO} ${SIZE}
+ fi
+
+ echo -n "."
+done
+
+echo " done."
diff --git a/bin/reprepro_foreign.sh b/bin/reprepro_foreign.sh
new file mode 100755
index 0000000..006c54b
--- /dev/null
+++ b/bin/reprepro_foreign.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+set -e
+
+ARCHITECTURES="${@}"
+
+if [ -z "${ARCHITECTURES}" ]
+then
+ ARCHITECTURES="arm64 armel armhf"
+fi
+
+for ARCHITECTURE in ${ARCHITECTURES}
+do
+ for DIRECTORY in */*_amd64
+ do
+ DIRECTORY="$(echo ${DIRECTORY} | sed -e "s|amd64|${ARCHITECTURE}|")"
+
+ if [ ! -e "${DIRECTORY}" ]
+ then
+ echo "${DIRECTORY}"
+ fi
+ done | grep -Ev '(current_|firefox|libreoffice|thunderbird)'
+done
diff --git a/bin/reprepro_html.sh b/bin/reprepro_html.sh
new file mode 100755
index 0000000..a5e56ba
--- /dev/null
+++ b/bin/reprepro_html.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+set -e
+
+DISTRIBUTIONS="engywuck engywuck-backports"
+
+for DISTRIBUTION in ${DISTRIBUTIONS}
+do
+ OUTPUT="/srv/git/progress-linux.org/packages/${DISTRIBUTION}.html"
+
+ if [ ! -e "$(dirname ${OUTPUT})" ]
+ then
+ echo "$(dirname ${OUTPUT}) - no such directory"
+ exit 1
+ fi
+
+cat > "${OUTPUT}" << EOF
+<html>
+<body>
+
+<h1>${DISTRIBUTION}</h1>
+
+<ul>
+ <li><a href="https://git.progress-linux.org/packages/${DISTRIBUTION}/">Git</a></li>
+</ul>
+
+<table>
+
+EOF
+
+ PACKAGES="$(wget -q https://git.progress-linux.org/packages/${DISTRIBUTION}/ -O - | grep sublevel-repo | sed -e 's|.*sublevel-repo||' -e "s|.*title='packages/||" -e "s|'.*||")"
+
+ for PACKAGE in ${PACKAGES}
+ do
+
+cat >> "${OUTPUT}" << EOF
+
+<tr>
+ <td><b>${PACKAGE}:</b></td>
+ <td><a href="https://packages.qa.debian.org/${PACKAGE}">PTS</a></td>
+ <td>|</td>
+ <td><a href="https://git.progress-linux.org/packages/${DISTRIBUTION}/${PACKAGE}/log/?h=debian">Git</a></td>
+ <td>|</td>
+ <td><a href="http://snapshot.debian.org/package/${PACKAGE}/">snap</a></td>
+</tr>
+EOF
+
+ done
+
+cat >> "${OUTPUT}" << EOF
+
+</table>
+
+</body>
+</html>
+EOF
+
+done
diff --git a/bin/reprepro_init.sh b/bin/reprepro_init.sh
new file mode 100755
index 0000000..1dc48b5
--- /dev/null
+++ b/bin/reprepro_init.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+set -e
+
+REPOSITORY="/srv/$(hostname -f)/packages"
+VENDOR="$(hostname -d | awk -F. '{ print $1 }')"
+
+if [ ! -e "${REPOSITORY}/conf" ]
+then
+ mkdir -p "${REPOSITORY}"
+
+# git clone reprepro "${REPOSITORY}/conf"
+fi
+
+cd "${REPOSITORY}"
+
+for FILE in conf/distributions conf/uploaders
+do
+ if [ -e "${FILE}" ] || [ ! -e "${FILE}.${VENDOR}" ]
+ then
+ continue
+ fi
+
+ cp "${FILE}.${VENDOR}" "${FILE}"
+done
+
+reprepro -b "${REPOSITORY}" --delete createsymlinks
+
+for DIRECTORY in db conf
+do
+ if [ ! -e "${DIRECTORY}" ]
+ then
+ continue
+ fi
+
+ chmod 0700 "${DIRECTORY}"
+done
diff --git a/bin/reprepro_mirror.sh b/bin/reprepro_mirror.sh
new file mode 100755
index 0000000..b45a978
--- /dev/null
+++ b/bin/reprepro_mirror.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+set -e
+
+MODULES="${1:-packages images}"
+
+HOSTNAME="$(hostname -f)"
+DOMAIN="$(hostname -d)"
+
+Rsync ()
+{
+ SERVER="${1}"
+ MODULE="${2}"
+ DIRECTORY="${3}"
+
+ mkdir -p "${DIRECTORY}"
+ touch "${DIRECTORY}/Archive-Update-in-Progress-${HOSTNAME}"
+
+ rsync -aPHv --progress --no-motd \
+ ${SERVER}::${MODULE} \
+ --exclude dists --exclude project/trace \
+ "${DIRECTORY}"
+
+ rsync -aPHv --progress --no-motd --delete \
+ ${SERVER}::${MODULE} \
+ "${DIRECTORY}"
+
+ mkdir -p "${DIRECTORY}/project/trace"
+ echo "$(date -R)" > "${DIRECTORY}/project/trace/${HOSTNAME}"
+}
+
+for MODULE in ${MODULES}
+do
+ Rsync apt.${DOMAIN} ${MODULE} "/srv/${HOSTNAME}/${MODULE}"
+done
diff --git a/bin/reprepro_pull.sh b/bin/reprepro_pull.sh
new file mode 100755
index 0000000..f9e42f1
--- /dev/null
+++ b/bin/reprepro_pull.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+set -e
+
+HOSTNAME="$(hostname -f)"
+
+_ARCHITECTURE="${1:-amd64}"
+
+if ! ls /mnt/${_ARCHITECTURE}/*.changes > /dev/null 2>&1
+then
+ echo "E: no changes found in /mnt/${_ARCHITECTURE}"
+ exit 1
+fi
+
+for _CHANGES in /mnt/${_ARCHITECTURE}/*.changes
+do
+ if [ -z "${_CHANGES}" ]
+ then
+ exit 0
+ fi
+
+ _SOURCE="$(grep -m1 '^Source: ' ${_CHANGES} | awk '{ print $2 }')"
+ _VERSION="$(grep -m1 '^Version: ' ${_CHANGES} | awk '{ print $2 }')"
+ _DISTRIBUTION="$(grep -m1 '^Distribution: ' ${_CHANGES} | awk '{ print $2 }')"
+ _RELEASE="$(echo ${_DISTRIBUTION} | sed -e 's|-security||' -e 's|-updates||' -e 's|-extras||')"
+
+ if [ -e "/srv/${HOSTNAME}/files/releases/${_RELEASE}/packages/${_SOURCE}/${_VERSION}_${_ARCHITECTURE}" ]
+ then
+ echo "E: /srv/${HOSTNAME}/files/releases/${_RELEASE}/packages/${_SOURCE}/${_VERSION}_${_ARCHITECTURE} - already exists"
+ exit 1
+ fi
+
+ mkdir -p "/srv/${HOSTNAME}/files/releases/${_RELEASE}/packages/${_SOURCE}/${_VERSION}_${_ARCHITECTURE}"
+
+ echo "Moving files "
+
+ for _FILE in $(awk '{ print $3 }' ${_CHANGES} | grep -E '(\.dsc$|\.deb$|\.udeb$|\.tar.*$)' | sort -u)
+ do
+ echo -n "."
+ mv /mnt/${_ARCHITECTURE}/${_FILE} "/srv/${HOSTNAME}/files/releases/${_RELEASE}/packages/${_SOURCE}/${_VERSION}_${_ARCHITECTURE}"
+ done
+
+ echo " done."
+
+ mv ${_CHANGES} "/srv/${HOSTNAME}/files/releases/${_RELEASE}/packages/${_SOURCE}/${_VERSION}_${_ARCHITECTURE}"
+
+ cd "/srv/${HOSTNAME}/files/releases/${_RELEASE}/packages/${_SOURCE}/${_VERSION}_${_ARCHITECTURE}"
+ debsign.sh
+done
diff --git a/bin/reprepro_re-import.sh b/bin/reprepro_re-import.sh
new file mode 100755
index 0000000..8bb8a67
--- /dev/null
+++ b/bin/reprepro_re-import.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+set -e
+
+DISTRIBUTIONS=" \
+ engywuck/packages \
+ engywuck-extras/packages \
+ engywuck-backports/packages \
+ engywuck-backports-extras/packages \
+"
+
+QUIET="true"
+
+for DISTRIBUTION in ${DISTRIBUTIONS}
+do
+ if [ ! -e "${DISTRIBUTION}" ]
+ then
+ continue
+ fi
+
+ cd "${DISTRIBUTION}"
+
+ export PACKAGES="$(ls)"
+
+ for PACKAGE in ${PACKAGES}
+ do
+ for DIRECTORY in current_source current_all current_amd64 current_i386
+ do
+ if [ -e "${PACKAGE}/${DIRECTORY}" ]
+ then
+ cd "${PACKAGE}/${DIRECTORY}"
+
+ if [ -n "${QUIET}" ]
+ then
+ OPTIONS="quiet"
+ else
+ OPTIONS=""
+ fi
+
+cat << EOF
+################################################################################
+# re-importing: ${DISTRIBUTION} ${PACKAGE} ${DIRECTORY}
+################################################################################
+
+EOF
+
+ padd.sh ${OPTIONS}
+
+ cd ../../
+ fi
+ done
+ done
+
+ cd ../../
+done
diff --git a/bin/reprepro_reset.sh b/bin/reprepro_reset.sh
new file mode 100755
index 0000000..7ce6a79
--- /dev/null
+++ b/bin/reprepro_reset.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+set -e
+
+REPOSITORY="/srv/$(hostname -f)/packages"
+
+cd "${REPOSITORY}"
+
+if [ ! -e conf ]
+then
+ exit 0
+fi
+
+rm -rf db dists pool project
diff --git a/bin/reprepro_sync.sh b/bin/reprepro_sync.sh
new file mode 100755
index 0000000..04af242
--- /dev/null
+++ b/bin/reprepro_sync.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+set -e
+
+ARCHIVE="/srv/$(hostname -f)/archive"
+REPOSITORY="/srv/$(hostname -f)/packages"
+VENDOR="$(hostname -d | awk -F. '{ print $1 }')"
+
+cd "${REPOSITORY}"
+
+if [ ! -e conf ]
+then
+ exit 0
+fi
+
+DISTRIBUTIONS="$(awk '/^Codename: / { print $2 }' conf/distributions)"
+
+for DISTRIBUTION in ${DISTRIBUTIONS}
+do
+ reprepro -b "${REPOSITORY}" export ${DISTRIBUTION}
+ reprepro -b "${REPOSITORY}" check ${DISTRIBUTION}
+done
+
+rm -rf project
+mkdir project
+
+for ITEM in other/pgp other/ssh other/tls
+do
+ if [ ! -e "${ARCHIVE}/${ITEM}" ]
+ then
+ continue
+ fi
+
+ cp -aL "${ARCHIVE}/${ITEM}" project
+done
+
+mkdir -p project/trace
+echo "$(date -R)" > "project/trace/$(hostname -f)"
diff --git a/bin/reverse b/bin/reverse
new file mode 100755
index 0000000..1821221
--- /dev/null
+++ b/bin/reverse
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+if [ "${#}" = "0" ]
+then
+ awk '{ a[NR]=$0 } END { for(i=NR; i; --i) print a[i] } '
+else
+ for FILE in ${@}
+ do
+ awk '{ a[NR]=$0 } END { for(i=NR; i; --i) print a[i] } ' ${FILE} > ${FILE}.tmp
+ mv ${FILE}.tmp ${FILE}
+ done
+fi
diff --git a/bin/sha512sums b/bin/sha512sums
new file mode 100755
index 0000000..228a8d9
--- /dev/null
+++ b/bin/sha512sums
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+set -e
+
+for FILE in $(find . -maxdepth 1 -mindepth 1 -type f -and -not -name "*.sha512" -and -not -name "*.sig")
+do
+ if [ -e "${FILE}" ] && [ ! -e "${FILE}.sha512" ]
+ then
+ echo "${FILE}"
+ sha512sum "${FILE}" > "${FILE}.sha512"
+ touch -r "${FILE}" "${FILE}.sha512"
+ fi
+done
diff --git a/bin/ssh-keygen-new-host.sh b/bin/ssh-keygen-new-host.sh
new file mode 100755
index 0000000..4340368
--- /dev/null
+++ b/bin/ssh-keygen-new-host.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+set -e
+
+if [ -z "${@}" ]
+then
+ echo -n "Hostnames [FQDN,HOSTNAME]:"
+ read _HOSTNAMES
+else
+ _HOSTNAMES="${@}"
+fi
+
+_FQDN="$(echo ${_HOSTNAMES} | awk -F, '{ print $1 }')"
+_HOSTNAME="$(echo ${_HOSTNAMES} | awk -F, '{ print $2 }')"
+
+echo -n "Date [365d]: "
+read _DATE
+
+_DATE="${_DATE:-365d}"
+
+_CA="../ca/$(basename ../ca/*.pub .pub)"
+
+ssh-keygen -N "" -t rsa -b 4096 -f ${_FQDN} -C sysadmin@${_FQDN} 2>&1 | tee ${_FQDN}.txt
+
+ssh-keygen -s ${_CA} -I $(basename ${_CA}) -h -n ${_HOSTNAMES} -V +${_DATE} ${_FQDN}