2 rcsid='$MirOS: contrib/hosted/tg/deb/mkdebidx.sh,v 1.51 2011/05/13 20:53:29 tg Exp $'
5 # Copyright (c) 2008, 2009, 2010, 2011
6 # Thorsten Glaser <tg@mirbsd.org>
8 # Provided that these terms and disclaimer and all copyright notices
9 # are retained or reproduced in an accompanying document, permission
10 # is granted to deal in this work without restriction, including un-
11 # limited rights to use, publicly perform, distribute, sell, modify,
12 # merge, give away, or sublicence.
14 # This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
15 # the utmost extent permitted by applicable law, neither express nor
16 # implied; without malicious intent or gross negligence. In no event
17 # may a licensor, author or contributor be held liable for indirect,
18 # direct, other damage, loss, or other issues arising in any way out
19 # of dealing in the work, even if advised of the possibility of such
20 # damage or existence of a defect, except proven that it results out
21 # of said person's immediate fault when using the work as intended.
23 set -A normarchs -- i386
24 export GNUPGHOME=/var/lib/gforge/chroot/home/groups/fusionforge/.gnupg
26 # either '' (locally) or 'remsign user@host.domain.com' (remote ssh)
28 repo_origin='The FusionForge Project'
30 repo_title='FusionForge 3rd-party DEB Repository'
31 function repo_description {
34 print -nr -- "FusionForge 3rd-party Repository for ${suite_nick}"
38 set -A dpkgarchs -- alpha amd64 arm armeb armel armhf avr32 hppa \
39 i386 ia64 kfreebsd-amd64 kfreebsd-i386 lpia m32r m68k mips mipsel \
40 powerpc powerpcspe ppc64 s390 s390x sh3 sh3eb sh4 sh4eb sparc
46 ssh -fNM -o ControlPath=$tmpfnm "$target"
47 ssh -o ControlPath=$tmpfnm "$target" cat \>$tmpfnm
48 ssh -o ControlPath=$tmpfnm -t "$target" "$* $tmpfnm" 0<&2 1>&2
50 ssh -o ControlPath=$tmpfnm "$target" "cat $tmpfnm.sig; rm -f $tmpfnm $tmpfnm.sig"
51 ssh -o ControlPath=$tmpfnm "$target" -O exit
56 tee $1 | gzip -n9 >$1.gz
62 if [[ $u = -u ]]; then
73 # DJB cdb hash (not via stdio, for speed)
74 typeset -Z11 -Uui16 Lcdbhash_result
75 function Lcdbhash_add {
77 typeset -i i=0 n=${#s}
80 ((# Lcdbhash_result = (Lcdbhash_result * 33) ^ 1#${s:(i++):1} ))
89 rm -f dpkg_578162_workaround
92 dpkgarchl=:all:"${dpkgarchs[*]}":
97 suites=:dists/$suite$suites
101 for suite in dists/*; do
102 allsuites="$allsuites${allsuites:+ }${suite##*/}"
103 [[ $suites = : || $suites = *:"$suite":* ]] || continue
107 suitearchs=${archs:-${normarchs[*]}}
108 components=Components:
109 for dist in $suite/*; do
110 [[ -d $dist/. ]] || continue
111 rm -rf $dist/binary-* $dist/source
113 [[ -s $dist/override.file ]] && ovf=$dist/override.file
114 [[ -s $dist/override.extra ]] && oef="-e $dist/override.extra"
115 [[ -s $dist/override.src ]] && osf="-s $dist/override.src"
116 components="$components ${dist##*/}"
118 [[ -s $dist/distinfo.sh ]] && . $dist/distinfo.sh
119 set -A distarchs -- $(sortlist -u all ${archs:-$suitearchs})
120 IFS=:; distarchl=:"${distarchs[*]}":; IFS=$saveIFS
121 for arch in $(sortlist -u ${distarchs[*]} ${dpkgarchs[*]}) /; do
123 [[ $arch = all ]] && continue
124 [[ $arch = / ]] && arch=all
126 if [[ $dpkgarchl != *:"$arch":* ]]; then
127 print -u2 "Invalid arch '$arch' in $dist"
129 elif [[ $distarchl != *:"$arch":* ]]; then
130 print "\n===> Linking all =>" \
131 "${dist#dists/}/$arch/Packages"
132 ln -s binary-all $dist/binary-$arch
134 print "\n===> Creating" \
135 "${dist#dists/}/$arch/Packages\n"
136 mkdir -p $dist/binary-$arch
137 dpkg-scanpackages $oef -m -a $arch \
139 putfile $dist/binary-$arch/Packages
142 print "\n===> Creating ${dist#dists/}/Sources"
143 mkdir -p $dist/source
144 [[ -e dpkg_578162_workaround ]] || (dpkg-scansources $oef $osf \
145 $dist $ovf || touch dpkg_578162_workaround) | \
146 putfile $dist/source/Sources
147 [[ -e dpkg_578162_workaround ]] && dpkg-scansources $osf \
149 putfile $dist/source/Sources
152 print "\n===> Creating ${suite#dists/}/Release.gpg"
153 rm -f $suite/Release*
155 Origin: ${repo_origin}
157 Suite: ${distribution:-${suite##*/}}
158 Codename: ${suite##*/}
160 Architectures: all ${dpkgarchs[*]} source
162 Description: $(repo_description "$nick")
165 exec 4>$suite/Release-sha1
166 exec 5>$suite/Release-sha2
175 for n in Contents-* */{binary-*,source}/{Packag,Sourc}es*; do
176 [[ -f $n ]] || continue
177 # realpath-ise $n and cache the checksum
179 #XXX once mksh can, use associative arrays instead
182 # simple hash collision solver by increment
183 nc=${cache_fn[Lcdbhash_result]}
184 while [[ -n $nc && $nc != "$nn" ]]; do
185 nc=${cache_fn[++Lcdbhash_result]}
187 if [[ $nc = "$nn" ]]; then
188 nm=${cache_md5[Lcdbhash_result]}
189 ns=${cache_size[Lcdbhash_result]}
190 nsha1=${cache_sha1[Lcdbhash_result]}
191 nsha2=${cache_sha2[Lcdbhash_result]}
193 # GNU *sum tools are horridly inefficient
194 set -A x -- $(md5sum "$nn")
196 set -A x -- $(sha1sum "$nn")
198 set -A x -- $(sha256sum "$nn")
200 ns=$(stat -c '%s' "$nn")
201 cache_md5[Lcdbhash_result]=$nm
202 cache_size[Lcdbhash_result]=$ns
203 cache_fn[Lcdbhash_result]=$nn
204 cache_sha1[Lcdbhash_result]=$nsha1
205 cache_sha2[Lcdbhash_result]=$nsha2
208 print -u4 " $nsha1 $ns $n"
209 print -u5 " $nsha2 $ns $n"
210 done) >$suite/Release
211 cat $suite/Release-sha1 $suite/Release-sha2 >>$suite/Release
212 rm $suite/Release-sha1 $suite/Release-sha2
213 $gpg_remote gpg --passphrase-file=$GNUPGHOME/seckey.pass \
214 --no-permission-warning --batch \
215 -u $repo_keyid -sb <$suite/Release >$suite/Release.gpg
218 print "\n===> Creating debidx.htm\n"
222 integer nsrc=0 nbin=0 nrpl=0
225 # syntax: ${suitename}/${distname}/${pN}/${pp} <suite>
226 # example: sid/wtf/openntpd/i386 lenny
227 if [[ -s mkdebidx.lnk ]]; then
229 [[ $pn = '#'* ]] && continue
230 if [[ $pn != +([a-z0-9_])/+([a-z0-9_-])/+([!/])/@(%|=|+([a-z0-9])) || \
231 $pd != +([a-z0-9_]) ]]; then
232 print -u2 "Invalid lnk line '$pn' '$pd'"
240 for suite in dists/*; do
241 for dist in $suite/*; do
242 [[ -d $dist/. ]] || continue
243 suitename=${suite##*/}
244 if [[ $suitename != +([a-z0-9_]) ]]; then
245 print -u2 "Invalid suite name '$suitename'"
249 if [[ $distname != +([a-z0-9_-]) ]]; then
250 print -u2 "Invalid dist name '$distname'"
254 gzip -dc $dist/source/Sources.gz |&
255 pn=; pv=; pd=; pp=; Lf=
256 while IFS= read -pr line; do
259 if [[ -n $Lf ]]; then
266 pn=${line##Package:*([ ])}
270 pv=${line##Version:*([ ])}
274 pd=${line##Binary:*([ ])}
278 pp=${line##Directory:*([ ])}
285 if [[ -n $pn && -n $pv && -n $pd && -n $pp ]]; then
287 while (( i < nsrc )); do
288 [[ ${sp_name[i]} = "$pn" && \
289 ${sp_dist[i]} = "$distname" ]] && break
292 if (( i == nsrc )); then
297 eval pvo=\$\{sp_ver_${suitename}[i]\}
298 eval ppo=\$\{sp_dir_${suitename}[i]\}
302 #sp_suites[i]="${sp_suites[i]} $suitename"
304 x=${suitename}/${distname}/${pn}/source
306 while (( j < nrpl )); do
307 [[ ${preplsrc[j]} = "$x" ]] && break
310 (( j < nrpl )) && pv="${pv}
\1afrom ${prepldst[j]}"
312 eval sp_ver_${suitename}[i]='${pvo:+$pvo,}$pv'
313 eval sp_dir_${suitename}[i]='${ppo:+$ppo,}$pp/'
314 sp_desc[i]=${sp_desc[i]},$pd
316 pn=; pv=; pd=; pp=; Lf=
321 gzip -dc $(for f in $dist/binary-*/Packages.gz; do
322 [[ -e $f ]] || continue
325 pn=; pv=; pd=; pp=; pN=; pf=; Lf=
326 while IFS= read -pr line; do
329 if [[ -n $Lf ]]; then
336 pN=${line##Package:*([ ])}
340 pn=${line##Source:*([ ])}
345 pv=${line##Version:*([ ])}
349 pd=${line##Description:*([ ])}
352 pp=${line##Architecture:*([ ])}
356 pf=${line##Filename:*([ ])}
363 if [[ $pf = *:* || $pf = *'%'* ]]; then
364 print -u2 Illegal character in $dist \
365 packages $pp "'Filename: $pf'"
368 [[ -n $pn ]] || pn=$pN
369 if [[ -n $pn && -n $pv && -n $pd && -n $pp ]]; then
371 while (( i < nbin )); do
372 [[ ${bp_disp[i]} = "$pN" && ${bp_desc[i]} = "$pd" && \
373 ${bp_dist[i]} = "$distname" ]] && break
376 (( i == nbin )) && let nbin++
380 #bp_suites[i]="${bp_suites[i]} $suitename"
382 x=${suitename}/${distname}/${pN}/${pp}
384 while (( j < nrpl )); do
385 [[ ${preplsrc[j]} = "$x" ]] && break
388 (( j < nrpl )) && pv="from ${prepldst[j]}"
390 [[ -n $pf ]] && pv="<a href=\"$pf\">$pv</a>"
392 eval x=\${bp_ver_${suitename}[i]}
393 [[ $br$x$br = *"$br$pv$br"* ]] || x=$x${x:+$br}$pv
394 eval bp_ver_${suitename}[i]=\$x
397 pn=; pv=; pd=; pp=; pN=; pf=; Lf=
407 <?xml version="1.0"?>
\r
408 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
409 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
410 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head>
411 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
412 <meta name="MSSmartTagsPreventParsing" content="TRUE" />
414 print -r -- " <title>${repo_title} Index</title>"
416 <meta name="generator" content="$MirOS: contrib/hosted/tg/deb/mkdebidx.sh,v 1.51 2011/05/13 20:53:29 tg Exp $" />
417 <style type="text/css">
419 border: 1px solid black;
420 border-collapse: collapse;
425 border: 1px solid black;
430 border: 1px solid black;
435 background-color: #000000;
439 border: 1px solid #999999;
444 background-color: #CCCCCC;
447 background-color: #666666;
452 background-color: #999999;
459 print -r -- "<h1>${repo_title}</h1>"
461 <p><a href="dists/">Browse</a> the repository or read about how to amend <a
462 href="sources.txt">/etc/apt/sources.list</a> in order to use it.
464 [[ -s 0-NOTE.txt ]] && print ' Also read my <a href="0-NOTE.txt">notes</a>.'
466 This repository uses <a
467 href="http://pgp.uni-mainz.de:11371/pks/lookup?search=${repo_keyid}&op=vindex">${repo_keyid}</a>
474 allsuites=$(for suitename in $allsuites; do
478 for suitename in $allsuites; do
479 suite=dists/$suitename
481 print -n " <li>${suite##*/}: <a href=\"$suite/\">$desc</a> (dists:"
482 for dist in $suite/*; do
483 [[ -d $dist/. ]] || continue
485 print -n " <a href=\"$suite/$distname/\">$distname</a>"
490 print "<h2>Packages</h2>"
491 print "<table width=\"100%\"><thead>"
492 print "<tr class=\"tablehead\">"
493 print " <th class=\"tableheadcell\">dist</th>"
494 print " <th class=\"tableheadcell\" rowspan=\"2\">Binary / Description</th>"
495 for suitename in $allsuites; do
496 print " <th class=\"tableheadcell\" rowspan=\"2\">$suitename</th>"
498 print "</tr><tr class=\"tablehead\">"
499 print " <th class=\"tableheadcell\">package name</th>"
500 print "</tr></thead><tbody>"
504 while (( i < nbin )); do
505 print $i ${bp_disp[i++]} #${bp_suites[i]}
507 while read -p num rest; do
508 bp_sort[${#bp_sort[*]}]=$num
512 while (( i < nsrc )); do
513 print $i ${sp_name[i++]}
515 while read -p num rest; do
516 print "\n<!-- sp #$num = ${sp_name[num]} -->"
517 print "<tr class=\"srcpkgline\">"
518 print " <td class=\"srcpkgdist\">${sp_dist[num]}</td>"
520 for x in $(tr ', ' '\n' <<<"${sp_desc[num]}" | sort -u); do
521 [[ -n $x ]] && pd="$pd, $x"
523 print " <td rowspan=\"2\" class=\"srcpkgdesc\">${pd#, }</td>"
524 for suitename in $allsuites; do
525 eval pvo=\${sp_ver_${suitename}[num]}
526 eval ppo=\${sp_dir_${suitename}[num]}
531 (( ${#pva[*]} )) || pva[0]=
534 while (( i < ${#pva[*]} )); do
537 if [[ $pv = *"
\1a"* ]]; then
543 if [[ -z $pv ]]; then
546 x=${suitename}/${sp_dist[num]}/${sp_name[num]}/%
548 while (( j < nrpl )); do
549 [[ ${preplsrc[j]} = "$x" ]] && break
552 (( j < nrpl )) && pv=${prepldst[j]}
554 elif [[ $pp != ?(/) ]]; then
555 pv="<a href=\"$pp${sp_name[num]}_${pvdsc##+([0-9]):}.dsc\">$pv</a>"
557 [[ $pp != ?(/) ]] && pv="<a href=\"$pp\">[dir]</a> $pv"
558 y=${y:+"$y<br />"}$pv
561 print " <td rowspan=\"2\" class=\"srcpkgitem\">$y</td>"
563 print "</tr><tr class=\"srcpkgline\">"
564 print " <td class=\"srcpkgname\">${sp_name[num]}</td>"
567 while (( k < nbin )); do
568 (( (i = bp_sort[k++]) < 0 )) && continue
569 [[ ${bp_name[i]} = "${sp_name[num]}" && \
570 ${bp_dist[i]} = "${sp_dist[num]}" ]] || continue
572 #print "<!-- bp #$i for${bp_suites[i]} -->"
573 print "<!-- bp #$i -->"
574 print "<tr class=\"binpkgline\">"
575 print " <td class=\"binpkgname\">${bp_disp[i]}</td>"
576 print " <td class=\"binpkgdesc\">${bp_desc[i]}</td>"
577 for suitename in $allsuites; do
578 eval pv=\${bp_ver_${suitename}[i]}
579 if [[ -z $pv ]]; then
582 x=${suitename}/${sp_dist[num]}/${sp_name[num]}/%
584 while (( j < nrpl )); do
585 [[ ${preplsrc[j]} = "$x" ]] && break
588 (( j < nrpl )) && pv=${prepldst[j]}
591 print " <td class=\"binpkgitem\">$pv</td>"
598 for i in ${bp_sort[*]}; do
599 (( i < 0 )) && continue
601 print "\n<!-- sp ENOENT -->"
602 print "<tr class=\"srcpkgline\">"
603 print " <td class=\"srcpkgname\">~ENOENT~</td>"
604 print " <td class=\"srcpkgdesc\">binary" \
605 "packages without a matching source package</td>"
606 for suitename in $allsuites; do
607 print " <td class=\"srcpkgitem\">-</td>"
612 #print "<!-- bp #$i for${bp_suites[i]} -->"
613 print "<!-- bp #$i -->"
614 print "<tr class=\"binpkgline\">"
615 print " <td class=\"binpkgdist\">${bp_dist[i]}</td>"
616 print " <td rowspan=\"2\" class=\"binpkgdesc\">${bp_desc[i]}</td>"
617 for suitename in $allsuites; do
618 eval pv=\${bp_ver_${suitename}[i]}
619 if [[ -z $pv ]]; then
622 x=${suitename}/${bp_dist[num]}/${bp_disp[num]}/=
624 while (( j < nrpl )); do
625 [[ ${preplsrc[j]} = "$x" ]] && break
628 (( j < nrpl )) && pv=${prepldst[j]}
631 print " <td rowspan=\"2\" class=\"binpkgitem\">$pv</td>"
633 print "</tr><tr class=\"binpkgline\">"
634 print " <td class=\"binpkgname\">${bp_disp[i]}</td>"
642 <p>• <a href="http://validator.w3.org/check/referer">Valid XHTML/1.1!</a>
643 • <small>Generated on $(date -u +'%F %T') by <tt
644 style="white-space:pre;">$rcsid</tt></small> •</p>