no sense in making arch:all when we have only one arch:any, just use it for all other...
[shellsnippets/shellsnippets.git] / mksh / debian-dev / mkdebidx.sh
1 #!/bin/mksh
2 rcsid='$MirOS: contrib/hosted/tg/deb/mkdebidx.sh,v 1.53 2011/12/28 00:45:47 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 armel armhf avr32 hppa hurd-i386 i386 \
37     ia64 kfreebsd-amd64 kfreebsd-i386 m68k mips mipsel powerpc powerpcspe \
38     ppc64 s390 s390x sh4 sparc sparc64
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                 nmds=0
120                 for arch in $(sortlist -u ${distarchs[*]} ${dpkgarchs[*]}) /; do
121                         # put "all" last
122                         [[ $arch = all ]] && continue
123                         [[ $arch = / ]] && arch=all
124                         # create index
125                         if [[ $dpkgarchl != *:"$arch":* ]]; then
126                                 print -u2 "Invalid arch '$arch' in $dist"
127                                 exit 1
128                         elif [[ $distarchl != *:"$arch":* ]]; then
129                                 print "\n===> Linking all =>" \
130                                     "${dist#dists/}/$arch/Packages"
131                                 ln -s binary-all $dist/binary-$arch
132                         elif [[ $arch = all ]] && (( nmds == 1 )); then
133                                 print "\n===> Linking $firstmd =>" \
134                                     "${dist#dists/}/all/Packages"
135                                 ln -s binary-$firstmd $dist/binary-all
136                         else
137                                 print "\n===> Creating" \
138                                     "${dist#dists/}/$arch/Packages\n"
139                                 mkdir -p $dist/binary-$arch
140                                 dpkg-scanpackages $oef -m -a $arch \
141                                     $dist $ovf | \
142                                     putfile $dist/binary-$arch/Packages
143                                 (( nmds++ )) || firstmd=$arch
144                         fi
145                 done
146                 print "\n===> Creating ${dist#dists/}/Sources"
147                 mkdir -p $dist/source
148                 [[ -e dpkg_578162_workaround ]] || (dpkg-scansources $oef $osf \
149                     $dist $ovf || touch dpkg_578162_workaround) | \
150                     putfile $dist/source/Sources
151                 [[ -e dpkg_578162_workaround ]] && dpkg-scansources $osf \
152                     $dist $ovf | \
153                     putfile $dist/source/Sources
154                 print done.
155         done
156         print "\n===> Creating ${suite#dists/}/Release.gpg"
157         rm -f $suite/Release*
158         (cat <<-EOF
159                 Origin: ${repo_origin}
160                 Label: ${repo_label}
161                 Suite: ${distribution:-${suite##*/}}
162                 Codename: ${suite##*/}
163                 Date: $(date -u)
164                 Architectures: all ${dpkgarchs[*]} source
165                 $components
166                 Description: $(repo_description "$nick")
167                 MD5Sum:
168         EOF
169         exec 4>$suite/Release-sha1
170         exec 5>$suite/Release-sha2
171         print -u4 SHA1:
172         print -u5 SHA256:
173         cd $suite
174         set -A cache_fn
175         set -A cache_md5
176         set -A cache_sha1
177         set -A cache_sha2
178         set -A cache_size
179         for n in Contents-* */{binary-*,source}/{Packag,Sourc}es*; do
180                 [[ -f $n ]] || continue
181                 # realpath-ise $n and cache the checksum
182                 nn=$(realpath "$n")
183                 #XXX once mksh can, use associative arrays instead
184                 Lcdbhash_result=5381
185                 Lcdbhash_add "$nn"
186                 # simple hash collision solver by increment
187                 nc=${cache_fn[Lcdbhash_result]}
188                 while [[ -n $nc && $nc != "$nn" ]]; do
189                         nc=${cache_fn[++Lcdbhash_result]}
190                 done
191                 if [[ $nc = "$nn" ]]; then
192                         nm=${cache_md5[Lcdbhash_result]}
193                         ns=${cache_size[Lcdbhash_result]}
194                         nsha1=${cache_sha1[Lcdbhash_result]}
195                         nsha2=${cache_sha2[Lcdbhash_result]}
196                 else
197                         # GNU *sum tools are horridly inefficient
198                         set -A x -- $(md5sum "$nn")
199                         nm=${x[0]}
200                         set -A x -- $(sha1sum "$nn")
201                         nsha1=${x[0]}
202                         set -A x -- $(sha256sum "$nn")
203                         nsha2=${x[0]}
204                         ns=$(stat -c '%s' "$nn")
205                         cache_md5[Lcdbhash_result]=$nm
206                         cache_size[Lcdbhash_result]=$ns
207                         cache_fn[Lcdbhash_result]=$nn
208                         cache_sha1[Lcdbhash_result]=$nsha1
209                         cache_sha2[Lcdbhash_result]=$nsha2
210                 fi
211                 print " $nm $ns $n"
212                 print -u4 " $nsha1 $ns $n"
213                 print -u5 " $nsha2 $ns $n"
214         done) >$suite/Release
215         cat $suite/Release-sha1 $suite/Release-sha2 >>$suite/Release
216         rm $suite/Release-sha1 $suite/Release-sha2
217         $gpg_remote gpg -u $repo_keyid -sb <$suite/Release >$suite/Release.gpg
218 done
219
220 print "\n===> Creating debidx.htm\n"
221
222 set -A preplsrc
223 set -A prepldst
224 integer nsrc=0 nbin=0 nrpl=0
225 br='<br />'
226
227 # syntax:       ${suitename}/${distname}/${pN}/${pp} <suite>
228 # example:      sid/wtf/openntpd/i386 lenny
229 if [[ -s mkdebidx.lnk ]]; then
230         while read pn pd; do
231                 [[ $pn = '#'* ]] && continue
232                 if [[ $pn != +([a-z0-9_])/+([a-z0-9_-])/+([!/])/@(%|=|+([a-z0-9])) || \
233                     $pd != +([a-z0-9_]) ]]; then
234                         print -u2 "Invalid lnk line '$pn' '$pd'"
235                         continue
236                 fi
237                 preplsrc[nrpl]=$pn
238                 prepldst[nrpl++]=$pd
239         done <mkdebidx.lnk
240 fi
241
242 for suite in dists/*; do
243         for dist in $suite/*; do
244                 [[ -d $dist/. ]] || continue
245                 suitename=${suite##*/}
246                 if [[ $suitename != +([a-z0-9_]) ]]; then
247                         print -u2 "Invalid suite name '$suitename'"
248                         continue 2
249                 fi
250                 distname=${dist##*/}
251                 if [[ $distname != +([a-z0-9_-]) ]]; then
252                         print -u2 "Invalid dist name '$distname'"
253                         continue
254                 fi
255
256                 gzip -dc $dist/source/Sources.gz |&
257                 pn=; pv=; pd=; pp=; Lf=
258                 while IFS= read -pr line; do
259                         case $line {
260                         (" "*)
261                                 if [[ -n $Lf ]]; then
262                                         eval x=\$$Lf
263                                         x=$x$line
264                                         eval $Lf=\$x
265                                 fi
266                                 ;;
267                         ("Package: "*)
268                                 pn=${line##Package:*([   ])}
269                                 Lf=pn
270                                 ;;
271                         ("Version: "*)
272                                 pv=${line##Version:*([   ])}
273                                 Lf=pv
274                                 ;;
275                         ("Binary: "*)
276                                 pd=${line##Binary:*([    ])}
277                                 Lf=pd
278                                 ;;
279                         ("Directory: "*)
280                                 pp=${line##Directory:*([         ])}
281                                 Lf=pp
282                                 ;;
283                         (?*)    # anything else
284                                 Lf=
285                                 ;;
286                         (*)     # empty line
287                                 if [[ -n $pn && -n $pv && -n $pd && -n $pp ]]; then
288                                         i=0
289                                         while (( i < nsrc )); do
290                                                 [[ ${sp_name[i]} = "$pn" && \
291                                                     ${sp_dist[i]} = "$distname" ]] && break
292                                                 let i++
293                                         done
294                                         if (( i == nsrc )); then
295                                                 let nsrc++
296                                                 pvo=
297                                                 ppo=
298                                         else
299                                                 eval pvo=\$\{sp_ver_${suitename}[i]\}
300                                                 eval ppo=\$\{sp_dir_${suitename}[i]\}
301                                         fi
302                                         sp_name[i]=$pn
303                                         sp_dist[i]=$distname
304                                         #sp_suites[i]="${sp_suites[i]} $suitename"
305                                         if (( nrpl )); then
306                                                 x=${suitename}/${distname}/${pn}/source
307                                                 j=0
308                                                 while (( j < nrpl )); do
309                                                         [[ ${preplsrc[j]} = "$x" ]] && break
310                                                         let j++
311                                                 done
312                                                 (( j < nrpl )) && pv="${pv}\1afrom ${prepldst[j]}"
313                                         fi
314                                         eval sp_ver_${suitename}[i]='${pvo:+$pvo,}$pv'
315                                         eval sp_dir_${suitename}[i]='${ppo:+$ppo,}$pp/'
316                                         sp_desc[i]=${sp_desc[i]},$pd
317                                 fi
318                                 pn=; pv=; pd=; pp=; Lf=
319                                 ;;
320                         }
321                 done
322
323                 gzip -dc $(for f in $dist/binary-*/Packages.gz; do
324                         [[ -e $f ]] || continue
325                         realpath "$f"
326                 done | sort -u) |&
327                 pn=; pv=; pd=; pp=; pN=; pf=; Lf=
328                 while IFS= read -pr line; do
329                         case $line {
330                         (" "*)
331                                 if [[ -n $Lf ]]; then
332                                         eval x=\$$Lf
333                                         x=$x$line
334                                         eval $Lf=\$x
335                                 fi
336                                 ;;
337                         ("Package: "*)
338                                 pN=${line##Package:*([   ])}
339                                 Lf=pN
340                                 ;;
341                         ("Source: "*)
342                                 pn=${line##Source:*([    ])}
343                                 pn=${pn%% *}
344                                 Lf=pn
345                                 ;;
346                         ("Version: "*)
347                                 pv=${line##Version:*([   ])}
348                                 Lf=pv
349                                 ;;
350                         ("Description: "*)
351                                 pd=${line##Description:*([       ])}
352                                 ;;
353                         ("Architecture: "*)
354                                 pp=${line##Architecture:*([      ])}
355                                 Lf=pp
356                                 ;;
357                         ("Filename: "*)
358                                 pf=${line##Filename:*([  ])}
359                                 Lf=pf
360                                 ;;
361                         (?*)    # anything else
362                                 Lf=
363                                 ;;
364                         (*)     # empty line
365                                 if [[ $pf = *:* || $pf = *'%'* ]]; then
366                                         print -u2 Illegal character in $dist \
367                                             packages $pp "'Filename: $pf'"
368                                         exit 1
369                                 fi
370                                 [[ -n $pn ]] || pn=$pN
371                                 if [[ -n $pn && -n $pv && -n $pd && -n $pp ]]; then
372                                         i=0
373                                         while (( i < nbin )); do
374                                                 [[ ${bp_disp[i]} = "$pN" && ${bp_desc[i]} = "$pd" && \
375                                                     ${bp_dist[i]} = "$distname" ]] && break
376                                                 let i++
377                                         done
378                                         (( i == nbin )) && let nbin++
379                                         bp_name[i]=$pn
380                                         bp_disp[i]=$pN
381                                         bp_dist[i]=$distname
382                                         #bp_suites[i]="${bp_suites[i]} $suitename"
383                                         if (( nrpl )); then
384                                                 x=${suitename}/${distname}/${pN}/${pp}
385                                                 j=0
386                                                 while (( j < nrpl )); do
387                                                         [[ ${preplsrc[j]} = "$x" ]] && break
388                                                         let j++
389                                                 done
390                                                 (( j < nrpl )) && pv="from ${prepldst[j]}"
391                                         fi
392                                         [[ -n $pf ]] && pv="<a href=\"$pf\">$pv</a>"
393                                         pv="$pp: $pv"
394                                         eval x=\${bp_ver_${suitename}[i]}
395                                         [[ $br$x$br = *"$br$pv$br"* ]] || x=$x${x:+$br}$pv
396                                         eval bp_ver_${suitename}[i]=\$x
397                                         bp_desc[i]=$pd
398                                 fi
399                                 pn=; pv=; pd=; pp=; pN=; pf=; Lf=
400                                 ;;
401                         }
402                 done
403         done
404 done
405
406 (cat <<'EOF'
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" />
413 EOF
414 print -r -- " <title>${repo_title} Index</title>"
415 cat <<'EOF'
416  <meta name="generator" content="$MirOS: contrib/hosted/tg/deb/mkdebidx.sh,v 1.53 2011/12/28 00:45:47 tg Exp $" />
417  <style type="text/css">
418   table {
419    border: 1px solid black;
420    border-collapse: collapse;
421    text-align: left;
422    vertical-align: top;
423   }
424   tr {
425    border: 1px solid black;
426    text-align: left;
427    vertical-align: top;
428   }
429   td {
430    border: 1px solid black;
431    text-align: left;
432    vertical-align: top;
433   }
434   th {
435    background-color: #000000;
436    color: #FFFFFF;
437   }
438   .tableheadcell {
439    border: 1px solid #999999;
440    padding: 3px;
441    white-space: nowrap;
442   }
443   .srcpkgline {
444    background-color: #CCCCCC;
445   }
446   .srcpkgdist {
447    background-color: #666666;
448    color: #FFFFFF;
449    font-weight: bold;
450   }
451   .binpkgdist {
452    background-color: #999999;
453    color: #FFFFFF;
454    font-weight: bold;
455   }
456  </style>
457 </head><body>
458 EOF
459 print -r -- "<h1>${repo_title}</h1>"
460 cat <<'EOF'
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.
463 EOF
464 [[ -s 0-NOTE.txt ]] && print ' Also read my <a href="0-NOTE.txt">notes</a>.'
465 cat <<EOF
466  This repository uses <a
467   href="http://pgp.uni-mainz.de:11371/pks/lookup?search=${repo_keyid}&amp;op=vindex">${repo_keyid}</a>
468  as signing key.
469 </p>
470 <h2>Suites</h2>
471 <ul>
472 EOF
473
474 allsuites=$(for suitename in $allsuites; do
475         print $suitename
476 done | sort -u)
477
478 for suitename in $allsuites; do
479         suite=dists/$suitename
480         . $suite/distinfo.sh
481         print -n " <li>${suite##*/}: <a href=\"$suite/\">$desc</a> (dists:"
482         for dist in $suite/*; do
483                 [[ -d $dist/. ]] || continue
484                 distname=${dist##*/}
485                 print -n " <a href=\"$suite/$distname/\">$distname</a>"
486         done
487         print ")</li>"
488 done
489 print "</ul>"
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>"
497 done
498 print "</tr><tr class=\"tablehead\">"
499 print " <th class=\"tableheadcell\">package name</th>"
500 print "</tr></thead><tbody>"
501
502 set -A bp_sort
503 i=0
504 while (( i < nbin )); do
505         print $i ${bp_disp[i++]} #${bp_suites[i]}
506 done | sort -k2 |&
507 while read -p num rest; do
508         bp_sort[${#bp_sort[*]}]=$num
509 done
510
511 i=0
512 while (( i < nsrc )); do
513         print $i ${sp_name[i++]}
514 done | sort -k2 |&
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>"
519         pd=
520         for x in $(tr ', ' '\n' <<<"${sp_desc[num]}" | sort -u); do
521                 [[ -n $x ]] && pd="$pd, $x"
522         done
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]}
527                 IFS=,
528                 set -A pva -- $pvo
529                 set -A ppa -- $ppo
530                 IFS=$saveIFS
531                 (( ${#pva[*]} )) || pva[0]=
532                 y=
533                 i=0
534                 while (( i < ${#pva[*]} )); do
535                         pv=${pva[i]}
536                         pp=${ppa[i]}
537                         if [[ $pv = *"\1a"* ]]; then
538                                 pvdsc=${pv%%"\1a"*}
539                                 pv=${pv##*"\1a"}
540                         else
541                                 pvdsc=$pv
542                         fi
543                         if [[ -z $pv ]]; then
544                                 pv=-
545                                 if (( nrpl )); then
546                                         x=${suitename}/${sp_dist[num]}/${sp_name[num]}/%
547                                         j=0
548                                         while (( j < nrpl )); do
549                                                 [[ ${preplsrc[j]} = "$x" ]] && break
550                                                 let j++
551                                         done
552                                         (( j < nrpl )) && pv=${prepldst[j]}
553                                 fi
554                         elif [[ $pp != ?(/) ]]; then
555                                 pv="<a href=\"$pp${sp_name[num]}_${pvdsc##+([0-9]):}.dsc\">$pv</a>"
556                         fi
557                         [[ $pp != ?(/) ]] && pv="<a href=\"$pp\">[dir]</a> $pv"
558                         y=${y:+"$y<br />"}$pv
559                         let i++
560                 done
561                 print " <td rowspan=\"2\" class=\"srcpkgitem\">$y</td>"
562         done
563         print "</tr><tr class=\"srcpkgline\">"
564         print " <td class=\"srcpkgname\">${sp_name[num]}</td>"
565         print "</tr>"
566         k=0
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
571                 bp_sort[k - 1]=-1
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
580                                 pv=-
581                                 if (( nrpl )); then
582                                         x=${suitename}/${sp_dist[num]}/${sp_name[num]}/%
583                                         j=0
584                                         while (( j < nrpl )); do
585                                                 [[ ${preplsrc[j]} = "$x" ]] && break
586                                                 let j++
587                                         done
588                                         (( j < nrpl )) && pv=${prepldst[j]}
589                                 fi
590                         fi
591                         print " <td class=\"binpkgitem\">$pv</td>"
592                 done
593                 print "</tr>"
594         done
595 done
596
597 num=0
598 for i in ${bp_sort[*]}; do
599         (( i < 0 )) && continue
600         if (( !num )); then
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>"
608                 done
609                 print "</tr>"
610                 num=1
611         fi
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
620                         pv=-
621                         if (( nrpl )); then
622                                 x=${suitename}/${bp_dist[num]}/${bp_disp[num]}/=
623                                 j=0
624                                 while (( j < nrpl )); do
625                                         [[ ${preplsrc[j]} = "$x" ]] && break
626                                         let j++
627                                 done
628                                 (( j < nrpl )) && pv=${prepldst[j]}
629                         fi
630                 fi
631                 print " <td rowspan=\"2\" class=\"binpkgitem\">$pv</td>"
632         done
633         print "</tr><tr class=\"binpkgline\">"
634         print " <td class=\"binpkgname\">${bp_disp[i]}</td>"
635         print "</tr>"
636 done
637
638 cat <<EOF
639
640 </tbody></table>
641
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>
645 </body></html>
646 EOF
647
648 :) >debidx.htm
649 print done.