more stuff useful when developing for Debian
authorThorsten Glaser <tg@mirbsd.org>
Wed, 9 Mar 2011 14:31:28 +0000 (15:31 +0100)
committerThorsten Glaser <tg@mirbsd.org>
Wed, 9 Mar 2011 14:31:28 +0000 (15:31 +0100)
mksh/debian-dev/BuildDSC.sh [new file with mode: 0644]
mksh/debian-dev/mkdebidx.sh [new file with mode: 0644]
mksh/debian-dev/quinn-ls.sh [new file with mode: 0644]

diff --git a/mksh/debian-dev/BuildDSC.sh b/mksh/debian-dev/BuildDSC.sh
new file mode 100644 (file)
index 0000000..d867afe
--- /dev/null
@@ -0,0 +1,139 @@
+#!/bin/mksh
+# $MirOS: contrib/hosted/tg/deb/BuildDSC.sh,v 1.10 2010/08/17 07:47:49 tg Exp $
+#-
+# Copyright (c) 2010
+#      Thorsten Glaser <t.glaser@tarent.de>
+#
+# Provided that these terms and disclaimer and all copyright notices
+# are retained or reproduced in an accompanying document, permission
+# is granted to deal in this work without restriction, including un-
+# limited rights to use, publicly perform, distribute, sell, modify,
+# merge, give away, or sublicence.
+#
+# This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
+# the utmost extent permitted by applicable law, neither express nor
+# implied; without malicious intent or gross negligence. In no event
+# may a licensor, author or contributor be held liable for indirect,
+# direct, other damage, loss, or other issues arising in any way out
+# of dealing in the work, even if advised of the possibility of such
+# damage or existence of a defect, except proven that it results out
+# of said person's immediate fault when using the work as intended.
+#-
+# The current working directory, or else the directory in which this
+# script resides, must be the root directory of a (extracted) Debian
+# source package. It will then be renamed to the proper dirname, and
+# a source package (*.dsc + others) will be created, then it will be
+# renamed back.
+# -s arg: make a snapshot with "arg" being the version number suffix
+# -S: build a snapshot with snapshot.YYYYMMDD.HHMMSS (UTC) as suffix
+# Any further arguments will be passed to debian/rules via MAKEFLAGS
+
+unset LANGUAGE
+export LC_ALL=C
+
+# preload
+sync
+date >/dev/null
+stime_rfc=$(date +"%a, %d %b %Y %H:%M:%S %z")
+stime_vsn=$(date -u +"%Y%m%d.%H%M%S")
+
+snap=0
+ssuf=
+while getopts "Ss:" ch; do
+       case $ch {
+       (S)     snap=1
+               ssuf=snapshot.$stime_vsn
+               ;;
+       (s)     snap=1
+               ssuf=$OPTARG
+               ;;
+       (*)     print -u2 Syntax error.
+               exit 1
+               ;;
+       }
+done
+shift $((OPTIND - 1))
+export MAKEFLAGS="$*"
+
+if (( snap )) && [[ -z $DEBEMAIL ]]; then
+       print -u2 'Please set $DEBEMAIL to "First M. Last <email@domain.com>"'
+       exit 1
+fi
+
+rmc=0
+while :; do
+       echo >&2 "=== trying . = $(pwd)"
+       dh_testdir >/dev/null 2>&1 && break
+       if [[ -s debian/control.in && -s debian/rules && \
+           -x debian/rules && ! -e debian/control ]]; then
+               rmc=1
+               debian/rules debian/control
+       fi
+       dh_testdir >/dev/null 2>&1 && break
+       (( rmc )) && debian/rules remove/control
+       rmc=0
+       cd "$(dirname "$0")"
+       print -u2 "=== trying basedir = $(pwd)"
+       dh_testdir >/dev/null 2>&1 && break
+       if [[ -s debian/control.in && -s debian/rules && \
+           -x debian/rules && ! -e debian/control ]]; then
+               rmc=1
+               debian/rules debian/control
+       fi
+       dh_testdir >/dev/null 2>&1 && break
+       (( rmc )) && debian/rules remove/control
+       print -u2 "FAILED! Please change to the correct directory."
+       exit 1
+done
+mydir=$(pwd)
+pkgstem=$(dpkg-parsechangelog -n1 | sed -n '/^Source: /s///p')
+version=$(dpkg-parsechangelog -n1 | sed -n '/^Version: /s///p')
+if (( snap )); then
+       updir=$(cd ..; pwd)
+       if ! T=$(mktemp "$updir/BuildDSC.tmp.XXXXXXXXXX"); then
+               (( rmc )) && debian/rules remove/control
+               print -u2 Could not create temporary file.
+               exit 1
+       fi
+       cat debian/changelog >"$T"
+       touch -r debian/changelog "$T"
+       dist=$(dpkg-parsechangelog -n1 | sed -n '/^Distribution: /s///p')
+       if [[ $dist = @(xunstable|UNRELEASED) ]]; then
+               # we’re at “current” already, reduce
+               version=$version'~'$ssuf
+       else
+               # we’re at an uploaded version, raise
+               version=$version'+'$ssuf
+       fi
+       print "$pkgstem ($version) UNRELEASED; urgency=low\n\n  *" \
+           "Automatically built snapshot package.\n\n --" \
+           "$DEBEMAIL  $stime_rfc\n" >debian/changelog
+       cat "$T" >>debian/changelog
+       touch -r "$T" debian/changelog
+       if (( rmc )); then
+               rm -f debian/control
+               debian/rules debian/control
+       fi
+fi
+upstreamversion=${version%%-*([!-])}
+upstreamversion=${upstreamversion#+([0-9]):}
+cd ..
+curname=${mydir##*/}
+newname=$pkgstem-$upstreamversion
+[[ $newname = $curname ]] || mv "$curname" "$newname"
+cd "$newname"
+dpkg-buildpackage -rfakeroot -S -I
+rv=$?
+fakeroot debian/rules clean
+cd ..
+[[ $newname = $curname ]] || mv "$newname" "$curname"
+
+cd "$curname"
+if (( snap )); then
+       cat "$T" >debian/changelog
+       touch -r "$T" debian/changelog
+       rm -f "$T"
+fi
+(( rmc )) && debian/rules remove/control
+
+exit $rv
diff --git a/mksh/debian-dev/mkdebidx.sh b/mksh/debian-dev/mkdebidx.sh
new file mode 100644 (file)
index 0000000..ba3466a
--- /dev/null
@@ -0,0 +1,594 @@
+#!/bin/mksh
+rcsid='$MirOS: contrib/hosted/tg/deb/mkdebidx.sh,v 1.46 2011/03/04 14:24:32 tg Exp $'
+#-
+# Copyright (c) 2008, 2009, 2010, 2011
+#      Thorsten Glaser <tg@mirbsd.org>
+#
+# Provided that these terms and disclaimer and all copyright notices
+# are retained or reproduced in an accompanying document, permission
+# is granted to deal in this work without restriction, including un-
+# limited rights to use, publicly perform, distribute, sell, modify,
+# merge, give away, or sublicence.
+#
+# This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
+# the utmost extent permitted by applicable law, neither express nor
+# implied; without malicious intent or gross negligence. In no event
+# may a licensor, author or contributor be held liable for indirect,
+# direct, other damage, loss, or other issues arising in any way out
+# of dealing in the work, even if advised of the possibility of such
+# damage or existence of a defect, except proven that it results out
+# of said person's immediate fault when using the work as intended.
+
+set -A normarchs -- i386
+repo_keyid=0x405422DD
+# either '' (locally) or 'remsign user@host.domain.com' (remote ssh)
+gpg_remote=
+repo_origin='The MirOS Project'
+repo_label=wtf
+repo_title='MirDebian “WTF” Repository'
+function repo_description {
+       typeset suite_nick=$1
+
+       print -nr -- "WTF ${suite_nick} Repository"
+}
+
+
+set -A dpkgarchs -- alpha amd64 arm armeb armel armhf avr32 hppa \
+    i386 ia64 kfreebsd-amd64 kfreebsd-i386 lpia m32r m68k mips mipsel \
+    powerpc powerpcspe ppc64 s390 s390x sh3 sh3eb sh4 sh4eb sparc
+
+function remsign {
+       target=$1; shift
+       master=remsign.ctl$$
+       tmpfnm=remsign.tmp$$
+       ssh -fNM -o ControlPath=$tmpfnm "$target"
+       ssh -o ControlPath=$tmpfnm "$target" cat \>$tmpfnm
+       ssh -o ControlPath=$tmpfnm -t "$target" "$* $tmpfnm" 0<&2 1>&2
+       rv=$?
+       ssh -o ControlPath=$tmpfnm "$target" "cat $tmpfnm.sig; rm -f $tmpfnm $tmpfnm.sig"
+       ssh -o ControlPath=$tmpfnm "$target" -O exit
+       return $rv
+}
+
+function putfile {
+       tee $1 | gzip -n9 >$1.gz
+}
+
+function sortlist {
+       typeset x u=$1
+
+       if [[ $u = -u ]]; then
+               shift
+       else
+               u=
+       fi
+
+       for x in "$@"; do
+               print -r -- "$x"
+       done | sort $u
+}
+
+# DJB cdb hash (not via stdio, for speed)
+typeset -Z11 -Uui16 Lcdbhash_result
+function Lcdbhash_add {
+       typeset s="$*"
+       typeset -i i=0 n=${#s}
+
+       while (( i < n )); do
+               ((# Lcdbhash_result = (Lcdbhash_result * 33) ^ 1#${s:(i++):1} ))
+       done
+}
+
+set +U
+export LC_ALL=C
+unset LANGUAGE
+saveIFS=$IFS
+cd "$(dirname "$0")"
+rm -f dpkg_578162_workaround
+
+IFS=:
+dpkgarchl=:all:"${dpkgarchs[*]}":
+IFS=$saveIFS
+
+suites=:
+for suite in "$@"; do
+       suites=:dists/$suite$suites
+done
+
+allsuites=
+for suite in dists/*; do
+       allsuites="$allsuites${allsuites:+ }${suite##*/}"
+       [[ $suites = : || $suites = *:"$suite":* ]] || continue
+       archs=
+       . $suite/distinfo.sh
+       suitearchs=${archs:-${normarchs[*]}}
+       components=Components:
+       for dist in $suite/*; do
+               [[ -d $dist/. ]] || continue
+               rm -rf $dist/binary-* $dist/source
+               ovf= oef= osf=
+               [[ -s $dist/override.file ]] && ovf=$dist/override.file
+               [[ -s $dist/override.extra ]] && oef="-e $dist/override.extra"
+               [[ -s $dist/override.src ]] && osf="-s $dist/override.src"
+               components="$components ${dist##*/}"
+               archs=
+               [[ -s $dist/distinfo.sh ]] && . $dist/distinfo.sh
+               set -A distarchs -- $(sortlist -u all ${archs:-$suitearchs})
+               IFS=:; distarchl=:"${distarchs[*]}":; IFS=$saveIFS
+               for arch in $(sortlist -u ${distarchs[*]} ${dpkgarchs[*]}); do
+                       if [[ $dpkgarchl != *:"$arch":* ]]; then
+                               print -u2 "Invalid arch '$arch' in $dist"
+                               exit 1
+                       elif [[ $distarchl != *:"$arch":* ]]; then
+                               print "\n===> Linking all =>" \
+                                   "${dist#dists/}/$arch/Packages"
+                               ln -s binary-all $dist/binary-$arch
+                       else
+                               print "\n===> Creating" \
+                                   "${dist#dists/}/$arch/Packages\n"
+                               mkdir -p $dist/binary-$arch
+                               dpkg-scanpackages $oef -m -a $arch \
+                                   $dist $ovf | \
+                                   putfile $dist/binary-$arch/Packages
+                       fi
+               done
+               print "\n===> Creating ${dist#dists/}/Sources"
+               mkdir -p $dist/source
+               [[ -e dpkg_578162_workaround ]] || (dpkg-scansources $oef $osf \
+                   $dist $ovf || touch dpkg_578162_workaround) | \
+                   putfile $dist/source/Sources
+               [[ -e dpkg_578162_workaround ]] && dpkg-scansources $osf \
+                   $dist $ovf | \
+                   putfile $dist/source/Sources
+               print done.
+       done
+       print "\n===> Creating ${suite#dists/}/Release.gpg"
+       rm -f $suite/Release*
+       (cat <<-EOF
+               Origin: ${repo_origin}
+               Label: ${repo_label}
+               Suite: ${suite##*/}
+               Codename: ${suite##*/}
+               Date: $(date -u)
+               Architectures: all ${dpkgarchs[*]} source
+               $components
+               Description: $(repo_description "$nick")
+               MD5Sum:
+       EOF
+       cd $suite
+       set -A cache_fn
+       set -A cache_md5
+       set -A cache_size
+       for n in Contents-* */{binary-*,source}/{Packag,Sourc}es*; do
+               [[ -f $n ]] || continue
+               # realpath-ise $n and cache the checksum
+               nn=$(realpath "$n")
+               #XXX once mksh can, use associative arrays instead
+               Lcdbhash_result=5381
+               Lcdbhash_add "$nn"
+               # simple hash collision solver by increment
+               nc=${cache_fn[Lcdbhash_result]}
+               while [[ -n $nc && $nc != "$nn" ]]; do
+                       nc=${cache_fn[++Lcdbhash_result]}
+               done
+               if [[ $nc = "$nn" ]]; then
+                       nm=${cache_md5[Lcdbhash_result]}
+                       ns=${cache_size[Lcdbhash_result]}
+               else
+                       set -A x -- $(md5sum "$nn")
+                       nm=${x[0]}
+                       ns=$(stat -c '%s' "$nn")
+                       cache_md5[Lcdbhash_result]=$nm
+                       cache_size[Lcdbhash_result]=$ns
+                       cache_fn[Lcdbhash_result]=$nn
+               fi
+               print " $nm $ns $n"
+       done) >$suite/Release
+       $gpg_remote gpg -u $repo_keyid -sb <$suite/Release >$suite/Release.gpg
+done
+
+print "\n===> Creating debidx.htm\n"
+
+set -A preplsrc
+set -A prepldst
+integer nsrc=0 nbin=0 nrpl=0
+br='<br />'
+
+# syntax:      ${suitename}/${distname}/${pN}/${pp} <suite>
+# example:     sid/wtf/openntpd/i386 lenny
+if [[ -s mkdebidx.lnk ]]; then
+       while read pn pd; do
+               [[ $pn = '#'* ]] && continue
+               if [[ $pn != +([a-z0-9_])/+([a-z0-9_-])/+([!/])/@(%|=|+([a-z0-9])) || \
+                   $pd != +([a-z0-9_]) ]]; then
+                       print -u2 "Invalid lnk line '$pn' '$pd'"
+                       continue
+               fi
+               preplsrc[nrpl]=$pn
+               prepldst[nrpl++]=$pd
+       done <mkdebidx.lnk
+fi
+
+for suite in dists/*; do
+       for dist in $suite/*; do
+               [[ -d $dist/. ]] || continue
+               suitename=${suite##*/}
+               if [[ $suitename != +([a-z0-9_]) ]]; then
+                       print -u2 "Invalid suite name '$suitename'"
+                       continue 2
+               fi
+               distname=${dist##*/}
+               if [[ $distname != +([a-z0-9_-]) ]]; then
+                       print -u2 "Invalid dist name '$distname'"
+                       continue
+               fi
+
+               pn=; pv=; pd=; pp=; pN=; pf=
+
+               gzip -dc $dist/source/Sources.gz |&
+               while IFS= read -pr line; do
+                       case $line {
+                       ("Package: "*)
+                               pn=${line##Package:*([   ])}
+                               ;;
+                       ("Version: "*)
+                               pv=${line##Version:*([   ])}
+                               ;;
+                       ("Binary: "*)
+                               pd=${line##Binary:*([    ])}
+                               ;;
+                       ("Directory: "*)
+                               pp=${line##Directory:*([         ])}
+                               ;;
+                       (?*)    # anything else
+                               ;;
+                       (*)     # empty line
+                               if [[ -n $pn && -n $pv && -n $pd && -n $pp ]]; then
+                                       i=0
+                                       while (( i < nsrc )); do
+                                               [[ ${sp_name[i]} = "$pn" && \
+                                                   ${sp_dist[i]} = "$distname" ]] && break
+                                               let i++
+                                       done
+                                       if (( i == nsrc )); then
+                                               let nsrc++
+                                               pvo=
+                                               ppo=
+                                       else
+                                               eval pvo=\$\{sp_ver_${suitename}[i]\}
+                                               eval ppo=\$\{sp_dir_${suitename}[i]\}
+                                       fi
+                                       sp_name[i]=$pn
+                                       sp_dist[i]=$distname
+                                       #sp_suites[i]="${sp_suites[i]} $suitename"
+                                       if (( nrpl )); then
+                                               x=${suitename}/${distname}/${pn}/source
+                                               j=0
+                                               while (( j < nrpl )); do
+                                                       [[ ${preplsrc[j]} = "$x" ]] && break
+                                                       let j++
+                                               done
+                                               (( j < nrpl )) && pv="${pv}\1afrom ${prepldst[j]}"
+                                       fi
+                                       eval sp_ver_${suitename}[i]='${pvo:+$pvo,}$pv'
+                                       eval sp_dir_${suitename}[i]='${ppo:+$ppo,}$pp/'
+                                       sp_desc[i]=${sp_desc[i]},$pd
+                               fi
+                               pn=; pv=; pd=; pp=
+                               ;;
+                       }
+               done
+
+               gzip -dc $(for f in $dist/binary-*/Packages.gz; do
+                       [[ -e $f ]] || continue
+                       realpath "$f"
+               done | sort -u) |&
+               while IFS= read -pr line; do
+                       case $line {
+                       ("Package: "*)
+                               pN=${line##Package:*([   ])}
+                               ;;
+                       ("Source: "*)
+                               pn=${line##Source:*([    ])}
+                               pn=${pn%% *}
+                               ;;
+                       ("Version: "*)
+                               pv=${line##Version:*([   ])}
+                               ;;
+                       ("Description: "*)
+                               pd=${line##Description:*([       ])}
+                               ;;
+                       ("Architecture: "*)
+                               pp=${line##Architecture:*([      ])}
+                               ;;
+                       ("Filename: "*)
+                               pf=${line##Filename:*([  ])}
+                               ;;
+                       (?*)    # anything else
+                               ;;
+                       (*)     # empty line
+                               if [[ $pf = *:* || $pf = *'%'* ]]; then
+                                       print -u2 Illegal character in $dist \
+                                           packages $pp "'Filename: $pf'"
+                                       exit 1
+                               fi
+                               [[ -n $pn ]] || pn=$pN
+                               if [[ -n $pn && -n $pv && -n $pd && -n $pp ]]; then
+                                       i=0
+                                       while (( i < nbin )); do
+                                               [[ ${bp_disp[i]} = "$pN" && ${bp_desc[i]} = "$pd" && \
+                                                   ${bp_dist[i]} = "$distname" ]] && break
+                                               let i++
+                                       done
+                                       (( i == nbin )) && let nbin++
+                                       bp_name[i]=$pn
+                                       bp_disp[i]=$pN
+                                       bp_dist[i]=$distname
+                                       #bp_suites[i]="${bp_suites[i]} $suitename"
+                                       if (( nrpl )); then
+                                               x=${suitename}/${distname}/${pN}/${pp}
+                                               j=0
+                                               while (( j < nrpl )); do
+                                                       [[ ${preplsrc[j]} = "$x" ]] && break
+                                                       let j++
+                                               done
+                                               (( j < nrpl )) && pv="from ${prepldst[j]}"
+                                       fi
+                                       [[ -n $pf ]] && pv="<a href=\"$pf\">$pv</a>"
+                                       pv="$pp: $pv"
+                                       eval x=\${bp_ver_${suitename}[i]}
+                                       [[ $br$x$br = *"$br$pv$br"* ]] || x=$x${x:+$br}$pv
+                                       eval bp_ver_${suitename}[i]=\$x
+                                       bp_desc[i]=$pd
+                               fi
+                               pn=; pv=; pd=; pp=; pN=
+                               ;;
+                       }
+               done
+       done
+done
+
+(cat <<'EOF'
+<?xml version="1.0"?>\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+ <meta name="MSSmartTagsPreventParsing" content="TRUE" />
+EOF
+print -r -- " <title>${repo_title} Index</title>"
+cat <<'EOF'
+ <meta name="generator" content="$MirOS: contrib/hosted/tg/deb/mkdebidx.sh,v 1.46 2011/03/04 14:24:32 tg Exp $" />
+ <style type="text/css">
+  table {
+   border: 1px solid black;
+   border-collapse: collapse;
+   text-align: left;
+   vertical-align: top;
+  }
+  tr {
+   border: 1px solid black;
+   text-align: left;
+   vertical-align: top;
+  }
+  td {
+   border: 1px solid black;
+   text-align: left;
+   vertical-align: top;
+  }
+  th {
+   background-color: #000000;
+   color: #FFFFFF;
+  }
+  .tableheadcell {
+   border: 1px solid #999999;
+   padding: 3px;
+   white-space: nowrap;
+  }
+  .srcpkgline {
+   background-color: #CCCCCC;
+  }
+  .srcpkgdist {
+   background-color: #666666;
+   color: #FFFFFF;
+   font-weight: bold;
+  }
+  .binpkgdist {
+   background-color: #999999;
+   color: #FFFFFF;
+   font-weight: bold;
+  }
+ </style>
+</head><body>
+EOF
+print -r -- "<h1>${repo_title}</h1>"
+cat <<'EOF'
+<p><a href="dists/">Browse</a> the repository or read about how to amend <a
+ href="sources.txt">/etc/apt/sources.list</a> in order to use it.
+EOF
+[[ -s 0-NOTE.txt ]] && print ' Also read my <a href="0-NOTE.txt">notes</a>.'
+cat <<EOF
+ This repository uses <a
+  href="http://pgpkeys.pca.dfn.de/pks/lookup?search=${repo_keyid}&amp;op=vindex">${repo_keyid}</a>
+ as signing key.
+</p>
+<h2>Suites</h2>
+<ul>
+EOF
+
+allsuites=$(for suitename in $allsuites; do
+       print $suitename
+done | sort -u)
+
+for suitename in $allsuites; do
+       suite=dists/$suitename
+       . $suite/distinfo.sh
+       print -n " <li>${suite##*/}: <a href=\"$suite/\">$desc</a> (dists:"
+       for dist in $suite/*; do
+               [[ -d $dist/. ]] || continue
+               distname=${dist##*/}
+               print -n " <a href=\"$suite/$distname/\">$distname</a>"
+       done
+       print ")</li>"
+done
+print "</ul>"
+print "<h2>Packages</h2>"
+print "<table width=\"100%\"><thead>"
+print "<tr class=\"tablehead\">"
+print " <th class=\"tableheadcell\">dist</th>"
+print " <th class=\"tableheadcell\" rowspan=\"2\">Binary / Description</th>"
+for suitename in $allsuites; do
+       print " <th class=\"tableheadcell\" rowspan=\"2\">$suitename</th>"
+done
+print "</tr><tr class=\"tablehead\">"
+print " <th class=\"tableheadcell\">package name</th>"
+print "</tr></thead><tbody>"
+
+set -A bp_sort
+i=0
+while (( i < nbin )); do
+       print $i ${bp_disp[i++]} #${bp_suites[i]}
+done | sort -k2 |&
+while read -p num rest; do
+       bp_sort[${#bp_sort[*]}]=$num
+done
+
+i=0
+while (( i < nsrc )); do
+       print $i ${sp_name[i++]}
+done | sort -k2 |&
+while read -p num rest; do
+       print "\n<!-- sp #$num = ${sp_name[num]} -->"
+       print "<tr class=\"srcpkgline\">"
+       print " <td class=\"srcpkgdist\">${sp_dist[num]}</td>"
+       pd=
+       for x in $(tr ', ' '\n' <<<"${sp_desc[num]}" | sort -u); do
+               [[ -n $x ]] && pd="$pd, $x"
+       done
+       print " <td rowspan=\"2\" class=\"srcpkgdesc\">${pd#, }</td>"
+       for suitename in $allsuites; do
+               eval pvo=\${sp_ver_${suitename}[num]}
+               eval ppo=\${sp_dir_${suitename}[num]}
+               IFS=,
+               set -A pva -- $pvo
+               set -A ppa -- $ppo
+               IFS=$saveIFS
+               (( ${#pva[*]} )) || pva[0]=
+               y=
+               i=0
+               while (( i < ${#pva[*]} )); do
+                       pv=${pva[i]}
+                       pp=${ppa[i]}
+                       if [[ $pv = *"\1a"* ]]; then
+                               pvdsc=${pv%%"\1a"*}
+                               pv=${pv##*"\1a"}
+                       else
+                               pvdsc=$pv
+                       fi
+                       if [[ -z $pv ]]; then
+                               pv=-
+                               if (( nrpl )); then
+                                       x=${suitename}/${sp_dist[num]}/${sp_name[num]}/%
+                                       j=0
+                                       while (( j < nrpl )); do
+                                               [[ ${preplsrc[j]} = "$x" ]] && break
+                                               let j++
+                                       done
+                                       (( j < nrpl )) && pv=${prepldst[j]}
+                               fi
+                       elif [[ $pp != ?(/) ]]; then
+                               pv="<a href=\"$pp${sp_name[num]}_${pvdsc##+([0-9]):}.dsc\">$pv</a>"
+                       fi
+                       [[ $pp != ?(/) ]] && pv="<a href=\"$pp\">[dir]</a> $pv"
+                       y=${y:+"$y<br />"}$pv
+                       let i++
+               done
+               print " <td rowspan=\"2\" class=\"srcpkgitem\">$y</td>"
+       done
+       print "</tr><tr class=\"srcpkgline\">"
+       print " <td class=\"srcpkgname\">${sp_name[num]}</td>"
+       print "</tr>"
+       k=0
+       while (( k < nbin )); do
+               (( (i = bp_sort[k++]) < 0 )) && continue
+               [[ ${bp_name[i]} = "${sp_name[num]}" && \
+                   ${bp_dist[i]} = "${sp_dist[num]}" ]] || continue
+               bp_sort[k - 1]=-1
+               #print "<!-- bp #$i for${bp_suites[i]} -->"
+               print "<!-- bp #$i -->"
+               print "<tr class=\"binpkgline\">"
+               print " <td class=\"binpkgname\">${bp_disp[i]}</td>"
+               print " <td class=\"binpkgdesc\">${bp_desc[i]}</td>"
+               for suitename in $allsuites; do
+                       eval pv=\${bp_ver_${suitename}[i]}
+                       if [[ -z $pv ]]; then
+                               pv=-
+                               if (( nrpl )); then
+                                       x=${suitename}/${sp_dist[num]}/${sp_name[num]}/%
+                                       j=0
+                                       while (( j < nrpl )); do
+                                               [[ ${preplsrc[j]} = "$x" ]] && break
+                                               let j++
+                                       done
+                                       (( j < nrpl )) && pv=${prepldst[j]}
+                               fi
+                       fi
+                       print " <td class=\"binpkgitem\">$pv</td>"
+               done
+               print "</tr>"
+       done
+done
+
+num=0
+for i in ${bp_sort[*]}; do
+       (( i < 0 )) && continue
+       if (( !num )); then
+               print "\n<!-- sp ENOENT -->"
+               print "<tr class=\"srcpkgline\">"
+               print " <td class=\"srcpkgname\">~ENOENT~</td>"
+               print " <td class=\"srcpkgdesc\">binary" \
+                   "packages without a matching source package</td>"
+               for suitename in $allsuites; do
+                       print " <td class=\"srcpkgitem\">-</td>"
+               done
+               print "</tr>"
+               num=1
+       fi
+       #print "<!-- bp #$i for${bp_suites[i]} -->"
+       print "<!-- bp #$i -->"
+       print "<tr class=\"binpkgline\">"
+       print " <td class=\"binpkgdist\">${bp_dist[i]}</td>"
+       print " <td rowspan=\"2\" class=\"binpkgdesc\">${bp_desc[i]}</td>"
+       for suitename in $allsuites; do
+               eval pv=\${bp_ver_${suitename}[i]}
+               if [[ -z $pv ]]; then
+                       pv=-
+                       if (( nrpl )); then
+                               x=${suitename}/${bp_dist[num]}/${bp_disp[num]}/=
+                               j=0
+                               while (( j < nrpl )); do
+                                       [[ ${preplsrc[j]} = "$x" ]] && break
+                                       let j++
+                               done
+                               (( j < nrpl )) && pv=${prepldst[j]}
+                       fi
+               fi
+               print " <td rowspan=\"2\" class=\"binpkgitem\">$pv</td>"
+       done
+       print "</tr><tr class=\"binpkgline\">"
+       print " <td class=\"binpkgname\">${bp_disp[i]}</td>"
+       print "</tr>"
+done
+
+cat <<EOF
+
+</tbody></table>
+
+<p>• <a href="http://validator.w3.org/check/referer">Valid XHTML/1.1!</a>
+ • <small>Generated on $(date -u +'%F %T') by <tt
+ style="white-space:pre;">$rcsid</tt></small> •</p>
+</body></html>
+EOF
+
+:) >debidx.htm
+print done.
diff --git a/mksh/debian-dev/quinn-ls.sh b/mksh/debian-dev/quinn-ls.sh
new file mode 100644 (file)
index 0000000..b6b1dde
--- /dev/null
@@ -0,0 +1,126 @@
+#!/bin/mksh
+rcsid='$MirOS: contrib/hosted/tg/deb/quinn-ls.sh,v 1.1 2011/02/18 18:52:01 tg Exp $'
+#-
+# Copyright (c) 2011
+#      Thorsten Glaser <tg@debian.org>
+#
+# Provided that these terms and disclaimer and all copyright notices
+# are retained or reproduced in an accompanying document, permission
+# is granted to deal in this work without restriction, including un-
+# limited rights to use, publicly perform, distribute, sell, modify,
+# merge, give away, or sublicence.
+#
+# This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
+# the utmost extent permitted by applicable law, neither express nor
+# implied; without malicious intent or gross negligence. In no event
+# may a licensor, author or contributor be held liable for indirect,
+# direct, other damage, loss, or other issues arising in any way out
+# of dealing in the work, even if advised of the possibility of such
+# damage or existence of a defect, except proven that it results out
+# of said person's immediate fault when using the work as intended.
+
+find . -name \*.changes -o -name \*.dsc |&
+set -A pkgs
+set -A lver
+set -A uver
+i=0
+while IFS= read -pr name; do
+       Source=
+       Version=
+       eval $(sed -n \
+           -e '/^\(Source\): \([^ ]*\)\( .*\)*$/s//\1='\''\2'\''/p' \
+           -e '/^\(Version\): \([^ ]*\)$/s//\1='\''\2'\''/p' \
+           "$name")
+       if [[ -z $Source || -z $Version ]]; then
+               print -ru2 "skipping invalid file $name"
+               continue
+       fi
+       j=-1
+       while (( ++j < i )); do
+               [[ ${pkgs[j]} = "$Source" ]] && break
+       done
+       if (( j == i )); then
+               print -u2 "local $Source $Version"
+               pkgs[i]=$Source
+               lver[i++]=$Version
+               continue
+       fi
+       for x in ${lver[j]}; do
+               # skip dups (from .changes = .dsc probably) silently
+               [[ $x = "$Version" ]] && continue 2
+       done
+       # put the newest local version leftmost
+       set -A xa -- ${lver[j]}
+       if dpkg --compare-versions "$Version" gt "${xa[0]}"; then
+               print -u2 "newer $Source $Version"
+               lver[j]="$Version ${lver[j]}"
+       else
+               print -u2 "older $Source $Version"
+               lver[j]="${lver[j]} $Version"
+       fi
+done
+
+print -u2 '\nrunning rmadison...'
+rmadison -s sid "${pkgs[@]}" |&
+while read -pr pkg pipe vsn pipe sid pipe arches; do
+       #print -u2 "D: pkg<$pkg> vsn<$vsn> sid<$sid> arches<$arches>"
+       arches=${arches//,/ }
+       [[ " $arches " = *' source '* ]] || continue
+       j=-1
+       while (( ++j < i )); do
+               [[ ${pkgs[j]} = "$pkg" ]] && break
+       done
+       if (( j == i )); then
+               print -u2 "bogus $pkg $vsn ignored"
+               continue
+       fi
+       x=${uver[j]}
+       if [[ -z $x ]]; then
+               print -u2 "found $pkg $vsn"
+               uver[j]=$vsn
+       elif [[ $x = "$vsn" ]]; then
+               print -u2 "equal $pkg $vsn ignored"
+       elif dpkg --compare-versions "$x" lt "$vsn"; then
+               print -u2 "newer $pkg $vsn (dropping $x)"
+               uver[j]=$vsn
+       else
+               print -u2 "older $pkg $vsn ignored"
+       fi
+done
+
+c0=$'\033[0m'
+c1=$'\033[1;31m'
+c2=$'\033[1;32m'
+c3=$'\033[1;33m'
+c4=$'\033[1;34m'
+print -ru2 "$c0"
+print -u2
+
+j=-1
+while (( ++j < i )); do
+       pkg=${pkgs[j]}
+       lvs=${lver[j]}
+       lv=${lvs%% *}
+       uv=${uver[j]}
+
+       if [[ -z $uv ]]; then
+               uv=0~RM
+               lc=$c1
+               uc=$c1
+       elif [[ $lv = "$uv"?('+b'+([0-9])) ]]; then
+               lc=$c2
+               uc=$c2
+       elif dpkg --compare-versions "$lv" lt "$uv"; then
+               lc=$c1
+               uc=$c3
+       else
+               lc=$c3
+               uc=$c4
+       fi
+       print -r -- "$c0$pkg $lc$lv$c0 $uc$uv$c0"
+       [[ $lvs = $lv ]] && continue
+       for lv in ${lvs#* }; do
+               [[ $lv = "$uv"?('+b'+([0-9])) ]] && continue
+               print -r -- "$c0$pkg $c4$lv$c0 -"
+       done
+done | sort | column -t