update from their respective sources
[shellsnippets/shellsnippets.git] / mksh / debian-dev / mkdebidx.sh
1 #!/bin/mksh
2 rcsid='$MirOS: contrib/hosted/tg/deb/mkdebidx.sh,v 1.51 2011/05/13 20:53:29 tg Exp $'
3 #-
4 # Copyright (c) 2008, 2009, 2010, 2011
5 #       Thorsten Glaser <tg@mirbsd.org>
6 #
7 # Provided that these terms and disclaimer and all copyright notices
8 # are retained or reproduced in an accompanying document, permission
9 # is granted to deal in this work without restriction, including un-
10 # limited rights to use, publicly perform, distribute, sell, modify,
11 # merge, give away, or sublicence.
12 #
13 # This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
14 # the utmost extent permitted by applicable law, neither express nor
15 # implied; without malicious intent or gross negligence. In no event
16 # may a licensor, author or contributor be held liable for indirect,
17 # direct, other damage, loss, or other issues arising in any way out
18 # of dealing in the work, even if advised of the possibility of such
19 # damage or existence of a defect, except proven that it results out
20 # of said person's immediate fault when using the work as intended.
21
22 set -A normarchs -- i386
23 repo_keyid=0x405422DD
24 # either '' (locally) or 'remsign user@host.domain.com' (remote ssh)
25 gpg_remote=
26 repo_origin='The MirOS Project'
27 repo_label=wtf
28 repo_title='MirDebian “WTF” Repository'
29 function repo_description {
30         typeset suite_nick=$1
31
32         print -nr -- "WTF ${suite_nick} Repository"
33 }
34
35
36 set -A dpkgarchs -- alpha amd64 arm armeb armel armhf avr32 hppa \
37     i386 ia64 kfreebsd-amd64 kfreebsd-i386 lpia m32r m68k mips mipsel \
38     powerpc powerpcspe ppc64 s390 s390x sh3 sh3eb sh4 sh4eb sparc
39
40 function remsign {
41         target=$1; shift
42         master=remsign.ctl$$
43         tmpfnm=remsign.tmp$$
44         ssh -fNM -o ControlPath=$tmpfnm "$target"
45         ssh -o ControlPath=$tmpfnm "$target" cat \>$tmpfnm
46         ssh -o ControlPath=$tmpfnm -t "$target" "$* $tmpfnm" 0<&2 1>&2
47         rv=$?
48         ssh -o ControlPath=$tmpfnm "$target" "cat $tmpfnm.sig; rm -f $tmpfnm $tmpfnm.sig"
49         ssh -o ControlPath=$tmpfnm "$target" -O exit
50         return $rv
51 }
52
53 function putfile {
54         tee $1 | gzip -n9 >$1.gz
55 }
56
57 function sortlist {
58         typeset x u=$1
59
60         if [[ $u = -u ]]; then
61                 shift
62         else
63                 u=
64         fi
65
66         for x in "$@"; do
67                 print -r -- "$x"
68         done | sort $u
69 }
70
71 # DJB cdb hash (not via stdio, for speed)
72 typeset -Z11 -Uui16 Lcdbhash_result
73 function Lcdbhash_add {
74         typeset s="$*"
75         typeset -i i=0 n=${#s}
76
77         while (( i < n )); do
78                 ((# Lcdbhash_result = (Lcdbhash_result * 33) ^ 1#${s:(i++):1} ))
79         done
80 }
81
82 set +U
83 export LC_ALL=C
84 unset LANGUAGE
85 saveIFS=$IFS
86 cd "$(dirname "$0")"
87 rm -f dpkg_578162_workaround
88
89 IFS=:
90 dpkgarchl=:all:"${dpkgarchs[*]}":
91 IFS=$saveIFS
92
93 suites=:
94 for suite in "$@"; do
95         suites=:dists/$suite$suites
96 done
97
98 allsuites=
99 for suite in dists/*; do
100         allsuites="$allsuites${allsuites:+ }${suite##*/}"
101         [[ $suites = : || $suites = *:"$suite":* ]] || continue
102         archs=
103         distribution=
104         . $suite/distinfo.sh
105         suitearchs=${archs:-${normarchs[*]}}
106         components=Components:
107         for dist in $suite/*; do
108                 [[ -d $dist/. ]] || continue
109                 rm -rf $dist/binary-* $dist/source
110                 ovf= oef= osf=
111                 [[ -s $dist/override.file ]] && ovf=$dist/override.file
112                 [[ -s $dist/override.extra ]] && oef="-e $dist/override.extra"
113                 [[ -s $dist/override.src ]] && osf="-s $dist/override.src"
114                 components="$components ${dist##*/}"
115                 archs=
116                 [[ -s $dist/distinfo.sh ]] && . $dist/distinfo.sh
117                 set -A distarchs -- $(sortlist -u all ${archs:-$suitearchs})
118                 IFS=:; distarchl=:"${distarchs[*]}":; IFS=$saveIFS
119                 for arch in $(sortlist -u ${distarchs[*]} ${dpkgarchs[*]}) /; do
120                         # put "all" last
121                         [[ $arch = all ]] && continue
122                         [[ $arch = / ]] && arch=all
123                         # create index
124                         if [[ $dpkgarchl != *:"$arch":* ]]; then
125                                 print -u2 "Invalid arch '$arch' in $dist"
126                                 exit 1
127                         elif [[ $distarchl != *:"$arch":* ]]; then
128                                 print "\n===> Linking all =>" \
129                                     "${dist#dists/}/$arch/Packages"
130                                 ln -s binary-all $dist/binary-$arch
131                         else
132                                 print "\n===> Creating" \
133                                     "${dist#dists/}/$arch/Packages\n"
134                                 mkdir -p $dist/binary-$arch
135                                 dpkg-scanpackages $oef -m -a $arch \
136                                     $dist $ovf | \
137                                     putfile $dist/binary-$arch/Packages
138                         fi
139                 done
140                 print "\n===> Creating ${dist#dists/}/Sources"
141                 mkdir -p $dist/source
142                 [[ -e dpkg_578162_workaround ]] || (dpkg-scansources $oef $osf \
143                     $dist $ovf || touch dpkg_578162_workaround) | \
144                     putfile $dist/source/Sources
145                 [[ -e dpkg_578162_workaround ]] && dpkg-scansources $osf \
146                     $dist $ovf | \
147                     putfile $dist/source/Sources
148                 print done.
149         done
150         print "\n===> Creating ${suite#dists/}/Release.gpg"
151         rm -f $suite/Release*
152         (cat <<-EOF
153                 Origin: ${repo_origin}
154                 Label: ${repo_label}
155                 Suite: ${distribution:-${suite##*/}}
156                 Codename: ${suite##*/}
157                 Date: $(date -u)
158                 Architectures: all ${dpkgarchs[*]} source
159                 $components
160                 Description: $(repo_description "$nick")
161                 MD5Sum:
162         EOF
163         exec 4>$suite/Release-sha1
164         exec 5>$suite/Release-sha2
165         print -u4 SHA1:
166         print -u5 SHA256:
167         cd $suite
168         set -A cache_fn
169         set -A cache_md5
170         set -A cache_sha1
171         set -A cache_sha2
172         set -A cache_size
173         for n in Contents-* */{binary-*,source}/{Packag,Sourc}es*; do
174                 [[ -f $n ]] || continue
175                 # realpath-ise $n and cache the checksum
176                 nn=$(realpath "$n")
177                 #XXX once mksh can, use associative arrays instead
178                 Lcdbhash_result=5381
179                 Lcdbhash_add "$nn"
180                 # simple hash collision solver by increment
181                 nc=${cache_fn[Lcdbhash_result]}
182                 while [[ -n $nc && $nc != "$nn" ]]; do
183                         nc=${cache_fn[++Lcdbhash_result]}
184                 done
185                 if [[ $nc = "$nn" ]]; then
186                         nm=${cache_md5[Lcdbhash_result]}
187                         ns=${cache_size[Lcdbhash_result]}
188                         nsha1=${cache_sha1[Lcdbhash_result]}
189                         nsha2=${cache_sha2[Lcdbhash_result]}
190                 else
191                         # GNU *sum tools are horridly inefficient
192                         set -A x -- $(md5sum "$nn")
193                         nm=${x[0]}
194                         set -A x -- $(sha1sum "$nn")
195                         nsha1=${x[0]}
196                         set -A x -- $(sha256sum "$nn")
197                         nsha2=${x[0]}
198                         ns=$(stat -c '%s' "$nn")
199                         cache_md5[Lcdbhash_result]=$nm
200                         cache_size[Lcdbhash_result]=$ns
201                         cache_fn[Lcdbhash_result]=$nn
202                         cache_sha1[Lcdbhash_result]=$nsha1
203                         cache_sha2[Lcdbhash_result]=$nsha2
204                 fi
205                 print " $nm $ns $n"
206                 print -u4 " $nsha1 $ns $n"
207                 print -u5 " $nsha2 $ns $n"
208         done) >$suite/Release
209         cat $suite/Release-sha1 $suite/Release-sha2 >>$suite/Release
210         rm $suite/Release-sha1 $suite/Release-sha2
211         $gpg_remote gpg -u $repo_keyid -sb <$suite/Release >$suite/Release.gpg
212 done
213
214 print "\n===> Creating debidx.htm\n"
215
216 set -A preplsrc
217 set -A prepldst
218 integer nsrc=0 nbin=0 nrpl=0
219 br='<br />'
220
221 # syntax:       ${suitename}/${distname}/${pN}/${pp} <suite>
222 # example:      sid/wtf/openntpd/i386 lenny
223 if [[ -s mkdebidx.lnk ]]; then
224         while read pn pd; do
225                 [[ $pn = '#'* ]] && continue
226                 if [[ $pn != +([a-z0-9_])/+([a-z0-9_-])/+([!/])/@(%|=|+([a-z0-9])) || \
227                     $pd != +([a-z0-9_]) ]]; then
228                         print -u2 "Invalid lnk line '$pn' '$pd'"
229                         continue
230                 fi
231                 preplsrc[nrpl]=$pn
232                 prepldst[nrpl++]=$pd
233         done <mkdebidx.lnk
234 fi
235
236 for suite in dists/*; do
237         for dist in $suite/*; do
238                 [[ -d $dist/. ]] || continue
239                 suitename=${suite##*/}
240                 if [[ $suitename != +([a-z0-9_]) ]]; then
241                         print -u2 "Invalid suite name '$suitename'"
242                         continue 2
243                 fi
244                 distname=${dist##*/}
245                 if [[ $distname != +([a-z0-9_-]) ]]; then
246                         print -u2 "Invalid dist name '$distname'"
247                         continue
248                 fi
249
250                 gzip -dc $dist/source/Sources.gz |&
251                 pn=; pv=; pd=; pp=; Lf=
252                 while IFS= read -pr line; do
253                         case $line {
254                         (" "*)
255                                 if [[ -n $Lf ]]; then
256                                         eval x=\$$Lf
257                                         x=$x$line
258                                         eval $Lf=\$x
259                                 fi
260                                 ;;
261                         ("Package: "*)
262                                 pn=${line##Package:*([   ])}
263                                 Lf=pn
264                                 ;;
265                         ("Version: "*)
266                                 pv=${line##Version:*([   ])}
267                                 Lf=pv
268                                 ;;
269                         ("Binary: "*)
270                                 pd=${line##Binary:*([    ])}
271                                 Lf=pd
272                                 ;;
273                         ("Directory: "*)
274                                 pp=${line##Directory:*([         ])}
275                                 Lf=pp
276                                 ;;
277                         (?*)    # anything else
278                                 Lf=
279                                 ;;
280                         (*)     # empty line
281                                 if [[ -n $pn && -n $pv && -n $pd && -n $pp ]]; then
282                                         i=0
283                                         while (( i < nsrc )); do
284                                                 [[ ${sp_name[i]} = "$pn" && \
285                                                     ${sp_dist[i]} = "$distname" ]] && break
286                                                 let i++
287                                         done
288                                         if (( i == nsrc )); then
289                                                 let nsrc++
290                                                 pvo=
291                                                 ppo=
292                                         else
293                                                 eval pvo=\$\{sp_ver_${suitename}[i]\}
294                                                 eval ppo=\$\{sp_dir_${suitename}[i]\}
295                                         fi
296                                         sp_name[i]=$pn
297                                         sp_dist[i]=$distname
298                                         #sp_suites[i]="${sp_suites[i]} $suitename"
299                                         if (( nrpl )); then
300                                                 x=${suitename}/${distname}/${pn}/source
301                                                 j=0
302                                                 while (( j < nrpl )); do
303                                                         [[ ${preplsrc[j]} = "$x" ]] && break
304                                                         let j++
305                                                 done
306                                                 (( j < nrpl )) && pv="${pv}\1afrom ${prepldst[j]}"
307                                         fi
308                                         eval sp_ver_${suitename}[i]='${pvo:+$pvo,}$pv'
309                                         eval sp_dir_${suitename}[i]='${ppo:+$ppo,}$pp/'
310                                         sp_desc[i]=${sp_desc[i]},$pd
311                                 fi
312                                 pn=; pv=; pd=; pp=; Lf=
313                                 ;;
314                         }
315                 done
316
317                 gzip -dc $(for f in $dist/binary-*/Packages.gz; do
318                         [[ -e $f ]] || continue
319                         realpath "$f"
320                 done | sort -u) |&
321                 pn=; pv=; pd=; pp=; pN=; pf=; Lf=
322                 while IFS= read -pr line; do
323                         case $line {
324                         (" "*)
325                                 if [[ -n $Lf ]]; then
326                                         eval x=\$$Lf
327                                         x=$x$line
328                                         eval $Lf=\$x
329                                 fi
330                                 ;;
331                         ("Package: "*)
332                                 pN=${line##Package:*([   ])}
333                                 Lf=pN
334                                 ;;
335                         ("Source: "*)
336                                 pn=${line##Source:*([    ])}
337                                 pn=${pn%% *}
338                                 Lf=pn
339                                 ;;
340                         ("Version: "*)
341                                 pv=${line##Version:*([   ])}
342                                 Lf=pv
343                                 ;;
344                         ("Description: "*)
345                                 pd=${line##Description:*([       ])}
346                                 ;;
347                         ("Architecture: "*)
348                                 pp=${line##Architecture:*([      ])}
349                                 Lf=pp
350                                 ;;
351                         ("Filename: "*)
352                                 pf=${line##Filename:*([  ])}
353                                 Lf=pf
354                                 ;;
355                         (?*)    # anything else
356                                 Lf=
357                                 ;;
358                         (*)     # empty line
359                                 if [[ $pf = *:* || $pf = *'%'* ]]; then
360                                         print -u2 Illegal character in $dist \
361                                             packages $pp "'Filename: $pf'"
362                                         exit 1
363                                 fi
364                                 [[ -n $pn ]] || pn=$pN
365                                 if [[ -n $pn && -n $pv && -n $pd && -n $pp ]]; then
366                                         i=0
367                                         while (( i < nbin )); do
368                                                 [[ ${bp_disp[i]} = "$pN" && ${bp_desc[i]} = "$pd" && \
369                                                     ${bp_dist[i]} = "$distname" ]] && break
370                                                 let i++
371                                         done
372                                         (( i == nbin )) && let nbin++
373                                         bp_name[i]=$pn
374                                         bp_disp[i]=$pN
375                                         bp_dist[i]=$distname
376                                         #bp_suites[i]="${bp_suites[i]} $suitename"
377                                         if (( nrpl )); then
378                                                 x=${suitename}/${distname}/${pN}/${pp}
379                                                 j=0
380                                                 while (( j < nrpl )); do
381                                                         [[ ${preplsrc[j]} = "$x" ]] && break
382                                                         let j++
383                                                 done
384                                                 (( j < nrpl )) && pv="from ${prepldst[j]}"
385                                         fi
386                                         [[ -n $pf ]] && pv="<a href=\"$pf\">$pv</a>"
387                                         pv="$pp: $pv"
388                                         eval x=\${bp_ver_${suitename}[i]}
389                                         [[ $br$x$br = *"$br$pv$br"* ]] || x=$x${x:+$br}$pv
390                                         eval bp_ver_${suitename}[i]=\$x
391                                         bp_desc[i]=$pd
392                                 fi
393                                 pn=; pv=; pd=; pp=; pN=; pf=; Lf=
394                                 ;;
395                         }
396                 done
397         done
398 done
399
400 (cat <<'EOF'
401 <?xml version="1.0"?>\r
402 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
403  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
404 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head>
405  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
406  <meta name="MSSmartTagsPreventParsing" content="TRUE" />
407 EOF
408 print -r -- " <title>${repo_title} Index</title>"
409 cat <<'EOF'
410  <meta name="generator" content="$MirOS: contrib/hosted/tg/deb/mkdebidx.sh,v 1.51 2011/05/13 20:53:29 tg Exp $" />
411  <style type="text/css">
412   table {
413    border: 1px solid black;
414    border-collapse: collapse;
415    text-align: left;
416    vertical-align: top;
417   }
418   tr {
419    border: 1px solid black;
420    text-align: left;
421    vertical-align: top;
422   }
423   td {
424    border: 1px solid black;
425    text-align: left;
426    vertical-align: top;
427   }
428   th {
429    background-color: #000000;
430    color: #FFFFFF;
431   }
432   .tableheadcell {
433    border: 1px solid #999999;
434    padding: 3px;
435    white-space: nowrap;
436   }
437   .srcpkgline {
438    background-color: #CCCCCC;
439   }
440   .srcpkgdist {
441    background-color: #666666;
442    color: #FFFFFF;
443    font-weight: bold;
444   }
445   .binpkgdist {
446    background-color: #999999;
447    color: #FFFFFF;
448    font-weight: bold;
449   }
450  </style>
451 </head><body>
452 EOF
453 print -r -- "<h1>${repo_title}</h1>"
454 cat <<'EOF'
455 <p><a href="dists/">Browse</a> the repository or read about how to amend <a
456  href="sources.txt">/etc/apt/sources.list</a> in order to use it.
457 EOF
458 [[ -s 0-NOTE.txt ]] && print ' Also read my <a href="0-NOTE.txt">notes</a>.'
459 cat <<EOF
460  This repository uses <a
461   href="http://pgp.uni-mainz.de:11371/pks/lookup?search=${repo_keyid}&amp;op=vindex">${repo_keyid}</a>
462  as signing key.
463 </p>
464 <h2>Suites</h2>
465 <ul>
466 EOF
467
468 allsuites=$(for suitename in $allsuites; do
469         print $suitename
470 done | sort -u)
471
472 for suitename in $allsuites; do
473         suite=dists/$suitename
474         . $suite/distinfo.sh
475         print -n " <li>${suite##*/}: <a href=\"$suite/\">$desc</a> (dists:"
476         for dist in $suite/*; do
477                 [[ -d $dist/. ]] || continue
478                 distname=${dist##*/}
479                 print -n " <a href=\"$suite/$distname/\">$distname</a>"
480         done
481         print ")</li>"
482 done
483 print "</ul>"
484 print "<h2>Packages</h2>"
485 print "<table width=\"100%\"><thead>"
486 print "<tr class=\"tablehead\">"
487 print " <th class=\"tableheadcell\">dist</th>"
488 print " <th class=\"tableheadcell\" rowspan=\"2\">Binary / Description</th>"
489 for suitename in $allsuites; do
490         print " <th class=\"tableheadcell\" rowspan=\"2\">$suitename</th>"
491 done
492 print "</tr><tr class=\"tablehead\">"
493 print " <th class=\"tableheadcell\">package name</th>"
494 print "</tr></thead><tbody>"
495
496 set -A bp_sort
497 i=0
498 while (( i < nbin )); do
499         print $i ${bp_disp[i++]} #${bp_suites[i]}
500 done | sort -k2 |&
501 while read -p num rest; do
502         bp_sort[${#bp_sort[*]}]=$num
503 done
504
505 i=0
506 while (( i < nsrc )); do
507         print $i ${sp_name[i++]}
508 done | sort -k2 |&
509 while read -p num rest; do
510         print "\n<!-- sp #$num = ${sp_name[num]} -->"
511         print "<tr class=\"srcpkgline\">"
512         print " <td class=\"srcpkgdist\">${sp_dist[num]}</td>"
513         pd=
514         for x in $(tr ', ' '\n' <<<"${sp_desc[num]}" | sort -u); do
515                 [[ -n $x ]] && pd="$pd, $x"
516         done
517         print " <td rowspan=\"2\" class=\"srcpkgdesc\">${pd#, }</td>"
518         for suitename in $allsuites; do
519                 eval pvo=\${sp_ver_${suitename}[num]}
520                 eval ppo=\${sp_dir_${suitename}[num]}
521                 IFS=,
522                 set -A pva -- $pvo
523                 set -A ppa -- $ppo
524                 IFS=$saveIFS
525                 (( ${#pva[*]} )) || pva[0]=
526                 y=
527                 i=0
528                 while (( i < ${#pva[*]} )); do
529                         pv=${pva[i]}
530                         pp=${ppa[i]}
531                         if [[ $pv = *"\1a"* ]]; then
532                                 pvdsc=${pv%%"\1a"*}
533                                 pv=${pv##*"\1a"}
534                         else
535                                 pvdsc=$pv
536                         fi
537                         if [[ -z $pv ]]; then
538                                 pv=-
539                                 if (( nrpl )); then
540                                         x=${suitename}/${sp_dist[num]}/${sp_name[num]}/%
541                                         j=0
542                                         while (( j < nrpl )); do
543                                                 [[ ${preplsrc[j]} = "$x" ]] && break
544                                                 let j++
545                                         done
546                                         (( j < nrpl )) && pv=${prepldst[j]}
547                                 fi
548                         elif [[ $pp != ?(/) ]]; then
549                                 pv="<a href=\"$pp${sp_name[num]}_${pvdsc##+([0-9]):}.dsc\">$pv</a>"
550                         fi
551                         [[ $pp != ?(/) ]] && pv="<a href=\"$pp\">[dir]</a> $pv"
552                         y=${y:+"$y<br />"}$pv
553                         let i++
554                 done
555                 print " <td rowspan=\"2\" class=\"srcpkgitem\">$y</td>"
556         done
557         print "</tr><tr class=\"srcpkgline\">"
558         print " <td class=\"srcpkgname\">${sp_name[num]}</td>"
559         print "</tr>"
560         k=0
561         while (( k < nbin )); do
562                 (( (i = bp_sort[k++]) < 0 )) && continue
563                 [[ ${bp_name[i]} = "${sp_name[num]}" && \
564                     ${bp_dist[i]} = "${sp_dist[num]}" ]] || continue
565                 bp_sort[k - 1]=-1
566                 #print "<!-- bp #$i for${bp_suites[i]} -->"
567                 print "<!-- bp #$i -->"
568                 print "<tr class=\"binpkgline\">"
569                 print " <td class=\"binpkgname\">${bp_disp[i]}</td>"
570                 print " <td class=\"binpkgdesc\">${bp_desc[i]}</td>"
571                 for suitename in $allsuites; do
572                         eval pv=\${bp_ver_${suitename}[i]}
573                         if [[ -z $pv ]]; then
574                                 pv=-
575                                 if (( nrpl )); then
576                                         x=${suitename}/${sp_dist[num]}/${sp_name[num]}/%
577                                         j=0
578                                         while (( j < nrpl )); do
579                                                 [[ ${preplsrc[j]} = "$x" ]] && break
580                                                 let j++
581                                         done
582                                         (( j < nrpl )) && pv=${prepldst[j]}
583                                 fi
584                         fi
585                         print " <td class=\"binpkgitem\">$pv</td>"
586                 done
587                 print "</tr>"
588         done
589 done
590
591 num=0
592 for i in ${bp_sort[*]}; do
593         (( i < 0 )) && continue
594         if (( !num )); then
595                 print "\n<!-- sp ENOENT -->"
596                 print "<tr class=\"srcpkgline\">"
597                 print " <td class=\"srcpkgname\">~ENOENT~</td>"
598                 print " <td class=\"srcpkgdesc\">binary" \
599                     "packages without a matching source package</td>"
600                 for suitename in $allsuites; do
601                         print " <td class=\"srcpkgitem\">-</td>"
602                 done
603                 print "</tr>"
604                 num=1
605         fi
606         #print "<!-- bp #$i for${bp_suites[i]} -->"
607         print "<!-- bp #$i -->"
608         print "<tr class=\"binpkgline\">"
609         print " <td class=\"binpkgdist\">${bp_dist[i]}</td>"
610         print " <td rowspan=\"2\" class=\"binpkgdesc\">${bp_desc[i]}</td>"
611         for suitename in $allsuites; do
612                 eval pv=\${bp_ver_${suitename}[i]}
613                 if [[ -z $pv ]]; then
614                         pv=-
615                         if (( nrpl )); then
616                                 x=${suitename}/${bp_dist[num]}/${bp_disp[num]}/=
617                                 j=0
618                                 while (( j < nrpl )); do
619                                         [[ ${preplsrc[j]} = "$x" ]] && break
620                                         let j++
621                                 done
622                                 (( j < nrpl )) && pv=${prepldst[j]}
623                         fi
624                 fi
625                 print " <td rowspan=\"2\" class=\"binpkgitem\">$pv</td>"
626         done
627         print "</tr><tr class=\"binpkgline\">"
628         print " <td class=\"binpkgname\">${bp_disp[i]}</td>"
629         print "</tr>"
630 done
631
632 cat <<EOF
633
634 </tbody></table>
635
636 <p>• <a href="http://validator.w3.org/check/referer">Valid XHTML/1.1!</a>
637  • <small>Generated on $(date -u +'%F %T') by <tt
638  style="white-space:pre;">$rcsid</tt></small> •</p>
639 </body></html>
640 EOF
641
642 :) >debidx.htm
643 print done.