update
authormirabilos <m@mirbsd.org>
Wed, 19 Jul 2017 12:39:50 +0000 (12:39 +0000)
committermirabilos <m@mirbsd.org>
Wed, 19 Jul 2017 12:39:50 +0000 (12:39 +0000)
15 files changed:
mksh/bdfctool.1
mksh/bdfctool.sh
mksh/debian-dev/BuildDSC.sh
mksh/debian-dev/mkdebidx.sh
mksh/wtf
posix/cleanenv
posix/cleanenv.1
posix/pbuilder-hooks/A88shell-raw [new file with mode: 0644]
posix/pbuilder-hooks/C80shell-jupp
posix/pbuilder-hooks/D00local [new file with mode: 0644]
posix/pbuilder-hooks/D02debhelper
posix/pbuilder-hooks/D10wtfrepo
posix/pbuilder-hooks/D25backports [new file with mode: 0644]
posix/wcdiff
posix/wcdiff.1 [new file with mode: 0644]

index 8e4552f..41f91f8 100644 (file)
@@ -1,7 +1,7 @@
-.\" $MirOS: X11/extras/bdfctool/bdfctool.1,v 1.10 2013/05/17 21:51:40 tg Exp $
+.\" $MirOS: X11/extras/bdfctool/bdfctool.1,v 1.14 2016/02/11 20:16:24 tg Exp $
 .\"-
-.\" Copyright © 2012, 2013
-.\"    Thorsten “mirabilos” Glaser <tg@mirbsd.org>
+.\" Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015, 2016
+.\"    mirabilos <m@mirbsd.org>
 .\"-
 .\" Try to make GNU groff and AT&T nroff more compatible
 .\" * ` generates ‘ in gnroff, so use \`
@@ -12,7 +12,9 @@
 .\" * ^ is size-reduced and placed atop in groff, so use \*(ha
 .\" * \(en does not work in nroff, so use \*(en
 .\" * <>| are problematic, so redefine and use \*(Lt\*(Gt\*(Ba
-.\" Also make sure to use \& especially with two-letter words.
+.\" Also make sure to use \& *before* a punctuation char that is to not
+.\" be interpreted as punctuation, and especially with two-letter words
+.\" but also (after) a period that does not end a sentence (“e.g.\&”).
 .\" The section after the "doc" macropackage has been loaded contains
 .\" additional code to convene between the UCB mdoc macropackage (and
 .\" its variant as BSD mdoc in groff) and the GNU mdoc macropackage.
@@ -57,7 +59,7 @@
 .\" with -mandoc, it might implement .Mx itself, but we want to
 .\" use our own definition. And .Dd must come *first*, always.
 .\"
-.Dd $Mdocdate: May 17 2013 $
+.Dd $Mdocdate: February 11 2016 $
 .\"
 .\" Check which macro package we use, and do other -mdoc setup.
 .\"
 .Fl c
 .Nm
 .Fl d
-.Op Fl F
+.Op Fl FGg
 .Nm
 .Fl e
 .Op Fl a
@@ -171,7 +173,9 @@ and the line end separator
 .It Ic +a
 In edit mode, emit Unicode (1:1) encoding (default).
 .It Fl d
-Decompress the font from bdfc into
+Decompress the font from bdfc
+.Pq or Tn BDF
+into
 .Tn BDF .
 .It Fl c
 Compress the font from
@@ -191,12 +195,17 @@ Revert selected glyphs from edit form back to compressed form
 Do a fast decompression with no error checking.
 Run this on files passed through
 .Nm
-.Fl c
+.Fl c ,
+without any subsequent manual or automated changes,
 .Em only .
 Used by the
 .Mx
 .Tn XFree86\(rg
 build process.
+.It Fl G
+Output a big-endian .gdf (libgd font) instead.
+.It Fl g
+Output a little-endian .gdf (libgd font) instead.
 .El
 .Sh BDFC FORMAT DESCRIPTION
 A
@@ -241,7 +250,7 @@ is put in
 Finally, there is the character block, which is somewhat stateless.
 There are two types of entries for that block, glyph defaults and glyph data.
 The block is ended with a period
-.Pq Dq Li .\&
+.Pq Dq Li \&.
 on a line by itself.
 .Pp
 Glyphs are sorted by their font encoding / Unicode code point, and each
@@ -372,8 +381,10 @@ The
 .Tn XFree86\(rg
 .Ic Bitmap Distribution Format ,
 version 2.1, specification
+.Pp
+.Pa http://php.net/manual/en/function.imageloadfont.php
 .Sh AUTHORS
-.An Thorsten Glaser Aq tg@mirbsd.org
+.An mirabilos Aq m@mirbsd.org
 wrote this tool because
 .Xr cvs 1
 does not scale for multi-thousand-line files,
@@ -396,3 +407,16 @@ is mandatory.
 The current practical limit on glyph width is 32.
 0-bit wide glyphs cause an error; those with height 0 are
 silently converted to an unset 1x1 bitmap.
+.Pp
+Passing a
+.Tn BDF
+file through
+.Nm
+.Fl d
+is not equivalent to compressing then decompressing it.
+The position of the
+.Li STARTPROPERTIES
+line can change, if bordering comments, for example.
+.Pp
+There is no support for padding BDF fonts yet.
+Output to gdf fonts requires padded input.
index 28fdd35..e66be7d 100644 (file)
@@ -1,8 +1,8 @@
 #!/bin/mksh
-# $MirOS: X11/extras/bdfctool/bdfctool.sh,v 1.12 2013/05/17 21:51:40 tg Exp $
+# $MirOS: X11/extras/bdfctool/bdfctool.sh,v 1.17 2015/02/26 03:05:33 tg Exp $
 #-
-# Copyright © 2012, 2013
-#      Thorsten Glaser <tg@mirbsd.org>
+# Copyright © 2007, 2008, 2009, 2010, 2012, 2013, 2015
+#      Thorsten “mirabilos” Glaser <tg@mirbsd.org>
 #
 # Provided that these terms and disclaimer and all copyright notices
 # are retained or reproduced in an accompanying document, permission
@@ -23,13 +23,15 @@ set -o noglob
 
 uascii=-1
 ufast=0
-while getopts "acdeFh" ch; do
+oform=0
+while getopts "acdeFGgh" ch; do
        case $ch {
        (a) uascii=1 ;;
        (+a) uascii=0 ;;
-       (c|d|e|+e) mode=$ch ;;
-       (F) ufast=1 ;;
-       (+F) ufast=0 ;;
+       (c|d|e|+e) mode=$ch oform=0 ;;
+       (F) ufast=1 oform=0 ;;
+       (G) oform=4 ;;
+       (g) oform=3 ;;
        (h) mode=$ch ;;
        (*) mode= ;;
        }
@@ -38,11 +40,17 @@ shift $((OPTIND - 1))
 (( $# )) && mode=
 
 if [[ $mode = ?(h) ]] || [[ $mode != e && $uascii != -1 ]] || \
-    [[ $mode != d && $ufast != 0 ]]; then
-       print -ru2 "Usage: ${0##*/} -c | -d [-F] | -e [-a] | +e"
+    [[ $mode != d && $ufast$oform != 00 ]]; then
+       print -ru2 "Usage: ${0##*/} -c | -d [-FGg] | -e [-a] | +e"
        [[ $mode = h ]]; exit $?
 fi
 
+# check padding on input, currently
+(( chkpad = (oform == 3 || oform == 4) ))
+
+# disable -F if -g
+(( ufast = (oform == 3 || oform == 4) ? 0 : ufast ))
+
 lno=0
 if [[ $mode = e ]]; then
        if (( uascii == 1 )); then
@@ -138,21 +146,36 @@ function parse_bdfc_file {
                        state=1
                        return
                elif [[ $line = '=bdfc 1' ]]; then
+                       set -A hFBB
                        continue
                fi
                last+=("$line")
-               [[ $line = \' || $line = "' "* ]] && continue
-               if [[ $line = h* ]]; then
+               case $line {
+               (\'|\'\ *)
+                       continue
+                       ;;
+               (hFONTBOUNDINGBOX\ +([0-9])\ +([0-9])\ +([0-9-])\ +([0-9-]))
+                       set -A hFBB -- $line
                        Fhead+=("${last[@]}")
-               elif [[ $line = p* ]]; then
+                       ;;
+               (h*)
+                       Fhead+=("${last[@]}")
+                       ;;
+               (p*)
                        Fprop+=("${last[@]}")
-               else
-                       print -ru2 "E: invalid line #$lno: '$line'"
+                       ;;
+               (*)
+                       print -ru2 "E: invalid line $lno: '$line'"
                        exit 2
-               fi
+                       ;;
+               }
                set -A last
        done
        Fprop+=("${last[@]}")
+       (( chkpad )) && if [[ -z $hFBB ]]; then
+               print -ru2 "E: missing FONTBOUNDINGBOX header"
+               exit 2
+       fi
        state=2
 }
 
@@ -192,7 +215,7 @@ function parse_bdfc_edit {
                linx=${linx//[ .]/0}
                linx=${linx//[#*]/1}
                if [[ $linx != +([01])'|' || ${#linx} != $((w + 1)) ]]; then
-                       print -ru2 "E: U+${ch#16#} (line #$lno) bitmap line" \
+                       print -ru2 "E: U+${ch#16#} (line $lno) bitmap line" \
                            $((f[3] - i)) "invalid: '$line'"
                        exit 2
                fi
@@ -223,10 +246,14 @@ function parse_bdfc_glyph {
                set -A f -- $line
                if [[ ${f[0]} = d ]]; then
                        Fdef="${f[*]}"
+                       (( chkpad )) && if [[ ${f[5]},${f[6]} != ${hFBB[3]},${hFBB[4]} ]]; then
+                               print -ru2 "E: d line $lno does not match FONTBOUNDINGBOX … ${hFBB[3]} ${hFBB[4]}"
+                               exit 2
+                       fi
                        continue
                fi
                if [[ ${f[0]} != [ce] ]]; then
-                       print -ru2 "E: invalid line #$lno: '$line'"
+                       print -ru2 "E: invalid line $lno: '$line'"
                        exit 2
                fi
                if [[ $Fdef != 'd '* ]]; then
@@ -247,6 +274,10 @@ function parse_bdfc_glyph {
                        print -ru2 "E: width ${f[2]} not in 1‥32 at line $lno"
                        exit 2
                fi
+               (( chkpad )) && if [[ ${f[2]} != ${hFBB[1]} ]]; then
+                       print -ru2 "E: c line $lno width ${f[2]} does not match FONTBOUNDINGBOX ${hFBB[1]}"
+                       exit 2
+               fi
                [[ ${f[4]} = "uni${ch#16#}" ]] && unset f[4]
                if [[ ${f[0]} = e ]]; then
                        parse_bdfc_edit
@@ -266,6 +297,13 @@ function parse_bdfc_glyph {
                                exit 2
                        fi
                fi
+               if (( chkpad )); then
+                       x=${f[3]//[!:]}
+                       if (( (${#x} + 1) != hFBB[2] )); then
+                               print -ru2 "E: c line $lno height $((${#x} + 1)) does not match FONTBOUNDINGBOX ${hFBB[2]}"
+                               exit 2
+                       fi
+               fi
                Gdata[ch]="${f[*]}"
                for line in "${last[@]}"; do
                        Gcomm[ch]+=$line$'\n'
@@ -290,6 +328,7 @@ function parse_bdfc {
 }
 
 function parse_bdf {
+       set -A hFBB
        while IFS= read -r line; do
                (( ++lno ))
                case $line {
@@ -302,11 +341,19 @@ function parse_bdf {
                (STARTPROPERTIES\ +([0-9]))
                        break
                        ;;
+               (FONTBOUNDINGBOX\ +([0-9])\ +([0-9])\ +([0-9-])\ +([0-9-]))
+                       set -A hFBB -- $line
+                       Fhead+=("h$line")
+                       ;;
                (*)
                        Fhead+=("h$line")
                        ;;
                }
        done
+       (( chkpad )) && if [[ -z $hFBB ]]; then
+               print -ru2 "E: missing FONTBOUNDINGBOX header"
+               exit 2
+       fi
        set -A f -- $line
        numprop=${f[1]}
        while IFS= read -r line; do
@@ -381,6 +428,10 @@ function parse_bdf {
                        ;;
                (BBX\ +([0-9])\ +([0-9])\ +([0-9-])\ +([0-9-]))
                        set -A cb -- $line
+                       (( chkpad )) && if [[ ${cb[1]},${cb[2]},${cb[3]},${cb[4]} != ${hFBB[1]},${hFBB[2]},${hFBB[3]},${hFBB[4]} ]]; then
+                               print -ru2 "E: BBX in line $lno does not match FONTBOUNDINGBOX ${hFBB[1]} ${hFBB[2]} ${hFBB[3]} ${hFBB[4]}"
+                               exit 2
+                       fi
                        ;;
                (BITMAP)
                        if [[ -z $cn ]]; then
@@ -424,14 +475,19 @@ function parse_bdf {
                        if (( (numlines = cb[2]) )); then
                                bmps=
                                typeset -u linu
-                               while IFS= read -r linu; do
+                               while IFS= read -r linx; do
                                        (( ++lno ))
-                                       if eval [[ '$linu' != "$ck" ]]; then
+                                       linu=$linx
+                                       while eval [[ '$linu' != "$ck" ]]; do
+                                               if [[ $linu = *00 ]]; then
+                                                       linu=${linu%00}
+                                                       continue
+                                               fi
                                                print -ru2 "E: invalid hex encoding" \
                                                    "for U+${ch#16#} (dec. $((ch)))" \
-                                                   "on line $lno: '$linu'"
+                                                   "on line $lno: '$linx'"
                                                exit 2
-                                       fi
+                                       done
                                        bmps+=$linu:
                                        (( --numlines )) || break
                                done
@@ -538,7 +594,7 @@ if [[ $mode = +e ]]; then
                fi
                set -A f -- $line
                if [[ ${f[0]} != [ce] ]]; then
-                       print -ru2 "E: invalid line #$lno: '$line'"
+                       print -ru2 "E: invalid line $lno: '$line'"
                        exit 2
                fi
                if [[ ${f[1]} != [0-9A-F][0-9A-F][0-9A-F][0-9A-F] ]]; then
@@ -589,12 +645,12 @@ if ! IFS= read -r line; then
        exit 2
 fi
 lno=1
-if [[ $line != '=bdfc 1' ]]; then
-       print -ru2 "E: not bdfc at BOF: '$line'"
-       exit 2
-fi
 
 if (( ufast )); then
+       if [[ $line != '=bdfc 1' ]]; then
+               print -ru2 "E: not bdfc at BOF: '$line'"
+               exit 2
+       fi
        if ! T=$(mktemp /tmp/bdfctool.XXXXXXXXXX); then
                print -u2 E: cannot make temporary file
                exit 4
@@ -613,9 +669,15 @@ if (( ufast )); then
                set -A last
        done
        Fprop+=("${last[@]}")
-else
+elif [[ $line = 'STARTFONT 2.1' ]]; then
+       # parse entire BDF file into memory
+       parse_bdf
+elif [[ $line = '=bdfc 1' ]]; then
        # parse entire bdfc file into memory
        parse_bdfc
+else
+       print -ru2 "E: not BDF or bdfc at BOF: '$line'"
+       exit 2
 fi
 
 # analyse data for BDF
@@ -625,6 +687,87 @@ for line in "${Fprop[@]}"; do
 done
 (( ufast )) || numchar=${#Gdata[*]}
 
+# handle diverging and non-ufast output formats
+case $oform {
+(3)
+       # little-endian .gdf
+       function out_int32 {
+               typeset -Uui16 value=$1
+               typeset -Uui8 ba bb bc bd
+
+               (( bd = (value >> 24) & 0xFF ))
+               (( bc = (value >> 16) & 0xFF ))
+               (( bb = (value >> 8) & 0xFF ))
+               (( ba = value & 0xFF ))
+               print -n "\\0${ba#8#}\\0${bb#8#}\\0${bc#8#}\\0${bd#8#}"
+       }
+       ;|
+(4)
+       # big-endian .gdf
+       function out_int32 {
+               typeset -Uui16 value=$1
+               typeset -Uui8 ba bb bc bd
+
+               (( ba = (value >> 24) & 0xFF ))
+               (( bb = (value >> 16) & 0xFF ))
+               (( bc = (value >> 8) & 0xFF ))
+               (( bd = value & 0xFF ))
+               print -n "\\0${ba#8#}\\0${bb#8#}\\0${bc#8#}\\0${bd#8#}"
+       }
+       ;|
+(3|4)
+       # do some input analysis for .gdf output
+       if [[ -z $hFBB ]]; then
+               print -ru2 "E: missing FONTBOUNDINGBOX header"
+               exit 2
+       fi
+       set -A f -- ${!Gdata[*]}
+       typeset -i firstch=${f[0]} lastch=${f[${#f[*]} - 1]}
+       nullch=
+       x=$((hFBB[1] * hFBB[2]))
+       while (( x-- )); do
+               nullch+=\\0
+       done
+       if (( hFBB[1] <= 8 )); then
+               adds=000000
+       elif (( hFBB[1] <= 16 )); then
+               adds=0000
+       elif (( hFBB[1] <= 24 )); then
+               adds=00
+       else
+               adds=
+       fi
+       # write .gdf stream
+       out_int32 $((# lastch - firstch + 1))
+       out_int32 $((# firstch))
+       out_int32 $((# hFBB[1]))
+       out_int32 $((# hFBB[2]))
+       typeset -i curch
+       ((# curch = firstch - 1 ))
+       while ((# ++curch <= lastch )); do
+               set -A f -- ${Gdata[curch]}
+               if [[ -z $f ]]; then
+                       print -n "$nullch"
+                       continue
+               fi
+               IFS=:
+               set -A bmp -- ${f[3]}
+               IFS=$' \t\n'
+               s=
+               for line in "${bmp[@]}"; do
+                       typeset -Uui2 bbin=16#$line$adds
+                       x=${hFBB[1]}
+                       while (( x-- )); do
+                               s+=\\0$(( (bbin & 0x80000000) ? 377 : 0 ))
+                               (( bbin <<= 1 ))
+                       done
+               done
+               print -n "$s"
+       done
+       exit 0
+       ;;
+}
+
 # write BDF stream
 print 'STARTFONT 2.1'
 for line in "${Fhead[@]}"; do
index ce4b0f7..3c10ef4 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/mksh
-# $MirOS: contrib/hosted/tg/deb/BuildDSC.sh,v 1.19 2016/02/23 18:05:35 tg Exp $
+# $MirOS: contrib/hosted/tg/deb/BuildDSC.sh,v 1.20 2016/11/12 04:02:48 tg Exp $
 #-
 # Copyright (c) 2010, 2011
 #      Thorsten Glaser <t.glaser@tarent.de>
 # 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.
+# -a: pass -sa to dpkg-buildpackage (include origtgz)
 # -d: pass -d to dpkg-buildpackage (ignore B-D absence)
 # -N: pass -nc to dpkg-buildpackage (do not clean)
 # -s arg: make a snapshot with “arg” being the version number suffix
 # -S: build a snapshot with snapshot.YYYYMMDD.HHMMSS (UTC) as suffix
+# -v: pass -v$OPTARG to dpkg-buildpackage (changelog since)
 # Any further arguments will be passed to debian/rules via MAKEFLAGS
 
 # sanitise environment
@@ -43,12 +45,18 @@ date >/dev/null
 stime_rfc=$(date +"%a, %d %b %Y %H:%M:%S %z")
 stime_vsn=$(date -u +"%Y%m%d.%H%M%S")
 
+opta=
 optd=
 optN=
+optv=
 snap=0
 ssuf=
-while getopts "dNSs:" ch; do
+while getopts "adNSs:v:" ch; do
        case $ch {
+       (a)     opta=-sa
+               ;;
+       (+a)    opta=
+               ;;
        (d)     optd=-d
                ;;
        (+d)    optd=
@@ -69,6 +77,8 @@ while getopts "dNSs:" ch; do
        (+s)    snap=0
                ssuf=
                ;;
+       (v)     optv=-v$OPTARG
+               ;;
        (*)     print -u2 Syntax error.
                exit 1
                ;;
@@ -144,7 +154,7 @@ curname=${mydir##*/}
 newname=$pkgstem-$upstreamversion
 [[ $newname = $curname ]] || mv "$curname" "$newname"
 cd "$newname"
-dpkg-buildpackage -rfakeroot -S -I -i $optd $optN -us -uc
+dpkg-buildpackage -rfakeroot -S -I -i $optd $optN $opta $optv -us -uc
 rv=$?
 [[ -n $optN ]] || fakeroot debian/rules clean
 cd ..
index b59749a..c98eb91 100644 (file)
@@ -1,7 +1,8 @@
 #!/bin/mksh
-rcsid='$MirOS: contrib/hosted/tg/deb/mkdebidx.sh,v 1.74 2016/11/05 16:45:56 tg Exp $'
+rcsid='$MirOS: contrib/hosted/tg/deb/mkdebidx.sh,v 1.76 2017/05/06 22:26:18 tg Exp $'
 #-
-# Copyright © 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016
+# Copyright © 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,
+#            2016, 2017
 #      mirabilos <m@mirbsd.org>
 #
 # Provided that these terms and disclaimer and all copyright notices
@@ -58,8 +59,8 @@ typeset -f repo_description >/dev/null || function repo_description {
        print -nr -- "WTF ${suite_nick} Repository"
 }
 set -A dpkgarchs -- alpha amd64 arm arm64 armel armhf hppa hurd-i386 i386 \
-    ia64 kfreebsd-amd64 kfreebsd-i386 m68k mips mipsel powerpc powerpcspe \
-    ppc64 ppc64el s390 s390x sh4 sparc sparc64 x32
+    ia64 kfreebsd-amd64 kfreebsd-i386 m68k mips mips64el mipsel powerpc \
+    powerpcspe ppc64 ppc64el s390 s390x sh4 sparc sparc64 x32
 [[ -n "${normarchs[*]}" ]] || set -A normarchs -- "${dpkgarchs[@]}"
 
 set +U
@@ -570,7 +571,6 @@ for suite in dists/*; do
 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>
index 56452c9..04f2312 100644 (file)
--- a/mksh/wtf
+++ b/mksh/wtf
@@ -1,9 +1,10 @@
 #!/bin/mksh
-# $MirOS: src/usr.bin/wtf/wtf,v 1.20 2012/08/18 04:48:46 tg Exp $
+myver='$MirOS: src/usr.bin/wtf/wtf,v 1.36 2017/06/15 21:00:45 tg Exp $'
 # $NetBSD: wtf,v 1.7 2000/11/21 00:18:52 soren Exp $
 #-
-# Copyright © 2002, 2003, 2004, 2006, 2007, 2008, 2010, 2011, 2012
-#      Thorsten “mirabilos” Glaser <tg@mirbsd.org>
+# Copyright © 2002, 2003, 2004, 2006, 2007, 2008, 2010, 2011,
+#            2012, 2014, 2015, 2017
+#      mirabilos <m@mirbsd.org>
 #
 # Provided that these terms and disclaimer and all copyright notices
 # are retained or reproduced in an accompanying document, permission
 
 acronyms=${ACRONYMDB:-/usr/share/misc/acronyms}
 
-function usage {
+usage() {
        print -u2 "usage: ${0##*/} [±adPpw] [-f dbfile] [is[t]] <acronym> [...]"
        exit 1
 }
 
-use_acronyms=1
-use_dict=0
-use_ports=0
-use_whatis=1
-while getopts "adf:Ppt:w" ch; do
+use_acronyms=-1
+use_dict=-1
+use_ports=-1
+use_whatis=-1
+hasopt=0
+show_ver=0
+while getopts "adf:hPpt:Vw" ch; do
        case $ch {
-       (+a)    use_acronyms=0 ;;
-       (a)     use_acronyms=1 ;;
-       (+d)    use_dict=0 ;;
-       (d)     use_dict=1 ;;
+       (+a)    hasopt=1 use_acronyms=0 ;;
+       (a)     hasopt=1 use_acronyms=1 ;;
+       (+d)    hasopt=1 use_dict=0 ;;
+       (d)     hasopt=1 use_dict=1 ;;
        (f)     acronyms=$OPTARG ;;
-       (+P)    use_ports=0 ;;
-       (P)     use_ports=2 ;;
-       (+p)    use_ports=0 ;;
-       (p)     use_ports=1 ;;
+       (+P)    hasopt=1 use_ports=0 ;;
+       (P)     hasopt=1 use_ports=2 ;;
+       (+p)    hasopt=1 use_ports=0 ;;
+       (p)     hasopt=1 use_ports=1 ;;
        (t)     ;;
-       (+w)    use_whatis=0 ;;
-       (w)     use_whatis=1 ;;
+       (V)     show_ver=1 ;;
+       (+w)    hasopt=1 use_whatis=0 ;;
+       (w)     hasopt=1 use_whatis=1 ;;
        (*)     usage ;;
        }
 done
 shift $((OPTIND - 1))
 
-[[ $1 = is || $1 = ist ]] && shift
+if (( hasopt )); then
+       (( use_acronyms = (use_acronyms == -1) ? 0 : use_acronyms ))
+       (( use_dict = (use_dict == -1) ? 0 : use_dict ))
+       (( use_ports = (use_ports == -1) ? 0 : use_ports ))
+       (( use_whatis = (use_whatis == -1) ? 0 : use_whatis ))
+else
+       use_acronyms=1
+       use_dict=0
+       use_ports=0
+       use_whatis=0
+fi
+
+if (( show_ver )); then
+       print -ru2 -- "$myver"
+       if (( use_acronyms )); then
+               exec <"$acronyms"
+               if ! IFS= read -r line || [[ $line != '  '* ]] || \
+                   ! IFS= read -r line || [[ $line != ' @(#)'* ]]; then
+                       print -ru2 "E: acronyms database ${acronyms@Q} too old"
+                       exit 1
+               fi
+               print -ru2 -- "${line# ????}"
+               print -nu2 'Counting, please be patient…'
+               last= nacr=0 nexp=0 lots=${EPOCHREALTIME%?????}
+               while IFS= read -r line; do
+                       [[ $line = *'   '* ]] || continue
+                       let ++nexp
+                       line=${line%%   *}
+                       [[ $line = "$last" ]] || let ++nacr
+                       last=$line
+                       [[ $lots = ${EPOCHREALTIME%?????} ]] && continue
+                       print -nu2 \\rwtf knows at least $nacr acronyms with $nexp expansions
+                       lots=${EPOCHREALTIME%?????}
+               done
+               print -u2 \\rwtf currently knows about $nacr acronyms with $nexp expansions
+       fi
+       exit 0
+fi
+
+(( $# > 1 )) && [[ $1 = is || $1 = ist ]] && shift
 (( $# < 1 )) && usage
 
 if (( use_ports )); then
@@ -58,14 +101,22 @@ if (( use_ports )); then
                # MirPorts Framework, OpenBSD ports tree
                binpkgs=ports
                function ports_acquire_filtered {
+                       local a b c d e
+                       local -l x y=$1
+
                        while IFS='|' read a b c d e; do
-                               [[ $a = *"$1"* ]] && \
+                               x=$a
+                               [[ $x = *"$y"* ]] && \
                                    print -r -- "$a|${d%% \(uses*}"
                        done </usr/ports/INDEX
                }
                function ports_acquire_unfiltered {
+                       local a b c d e
+                       local -l x y=$1
+
                        while IFS='|' read a b c d e; do
-                               [[ $a$d = *"$1"* ]] && \
+                               x=$a$d
+                               [[ $x = *"$y"* ]] && \
                                    print -r -- "$a|${d%% \(uses*}"
                        done </usr/ports/INDEX
                }
@@ -73,10 +124,13 @@ if (( use_ports )); then
                # Red Hat Yellowdog Updater Modified
                binpkgs=RPMs
                function ports_acquire_filtered {
+                       local -l x y=$1
+
                        yum search -q -- "$1" | \
                            tr '\n' '\ 1' | sed 's/\ 1 *: / /g' | tr '\ 1' '\n' | \
                            while read a b c; do
-                               [[ $a = *"$1"* ]] && print -r -- "$a|$c"
+                               x=$a
+                               [[ $x = *"$y"* ]] && print -r -- "$a|$c"
                        done
                }
                function ports_acquire_unfiltered {
@@ -90,8 +144,11 @@ if (( use_ports )); then
                # Debian Advanced Packaging Tool
                binpkgs=packages
                function ports_acquire_filtered {
+                       local -l x y=$1
+
                        apt-cache search -- "$1" | while read a b c; do
-                               [[ $a = *"$1"* ]] && print -r -- "$a|$c"
+                               x=$a
+                               [[ $x = *"$y"* ]] && print -r -- "$a|$c"
                        done
                }
                function ports_acquire_unfiltered {
@@ -109,13 +166,72 @@ if (( use_ports )); then
        }
 fi
 
+if (( use_acronyms )); then
+       # read input file only once
+       exec <"$acronyms"
+
+       # read case-folding code
+       if ! IFS= read -r line || [[ $line != '  '* ]]; then
+               print -ru2 "E: acronyms database ${acronyms@Q} too old"
+               exit 1
+       fi
+       set -A ucsrch -- $line
+
+       # create sorted input array, uppercased/folded
+       s='set -sA stsrch --'
+       i=0
+       # now: "$@"=("$0" foo bar baz)
+       for target in "$@"; do
+               typeset -u tgsrch=$target
+               [[ $tgsrch = *[A-Z].* ]] && tgsrch=${tgsrch//.}
+               for p in "${ucsrch[@]}"; do
+                       eval 'tgsrch=${tgsrch//'"$p}"
+               done
+               s+=" ${tgsrch@Q}=$((++i))"
+       done
+       eval "$s"
+       # now: stsrch=(BAR=2 BAZ=3 FOO=1)
+
+       # create output mapping, remove mapping number from stsrch
+       set -A omsrch
+       tgsrch=
+       i=0 n=-1
+       for s in "${stsrch[@]}"; do
+               p=${s%=*}
+               if [[ $p = $tgsrch ]]; then
+                       # this is a repeat
+                       unset stsrch[i++]
+               else
+                       stsrch[i++]=$p
+                       tgsrch=$p
+                       let ++n
+               fi
+               (( omsrch[${s##*=}] = n ))
+       done
+       set -A stsrch -- "${stsrch[@]}"
+       # now: stsrch=(BAR BAZ FOO) omsrch[1]=2 omsrch[2]=0 omsrch[3]=1
+
+       # look up acronyms
+       set -A acrout
+       i=-1
+       for s in "${stsrch[@]}"; do
+               let ++i
+               while :; do
+                       if [[ $line = "$s       "* ]]; then
+                               acrout[i]+=$'\n'${line#*        }
+                       elif [[ $line > "$s     " ]]; then
+                               continue 2
+                       fi
+                       IFS= read -r line || break 2
+               done
+       done
+
+       exec <&-
+       i=0
+fi
+
 rv=0
 for target in "$@"; do
-       typeset -u tgsrch=$target
-       tgsrch=${tgsrch//ä/Ä}
-       tgsrch=${tgsrch//ö/Ö}
-       tgsrch=${tgsrch//ü/Ü}
-
        if (( use_ports )); then
                p=$(ports_acquire "$target")
                if [[ -n $p ]]; then
@@ -125,13 +241,12 @@ for target in "$@"; do
        fi
 
        if (( use_acronyms )); then
-               found=0
-               while IFS= read -r line; do
-                       [[ $line = "$tgsrch     "* ]] || continue
-                       (( found++ )) || print -r "   $tgsrch:"
-                       print -r -- "${line#*   }"
-               done <"$acronyms"
-               if (( !found )); then
+               n=${omsrch[++i]}
+               s=${acrout[n]}
+               tgsrch=${stsrch[n]}
+               if [[ -n $s ]]; then
+                       print -r -- "   $tgsrch:$s"
+               else
                        print -ru2 Gee… I don’t know what “"$tgsrch"” means…
                        (( rv |= 1 ))
                fi
@@ -139,7 +254,7 @@ for target in "$@"; do
 
        (( use_dict || use_whatis )) && print "  - other information sources"
 
-       (( use_dict )) && if whence -p dict >&-; then
+       (( use_dict )) && if whence -p dict >/dev/null; then
                dict "$target" || (( rv |= 2 ))
        else
                (( rv |= 4 ))
index 978fa80..a70240b 100644 (file)
@@ -1,17 +1,23 @@
 #!/bin/sh
-# $MirOS: src/scripts/cleanenv,v 1.4+notz 2009/03/29 13:04:20 tg Exp $
-#-
-# Not complicated enough for copyright.
+# $MirOS: src/scripts/cleanenv,v 1.5 2014/09/28 19:49:56 tg Exp $
 
 p=/bin:/usr/bin:/sbin:/usr/sbin:/usr/X11R6/bin
 
-if test x"$1" = x"-"; then
+a1=$1
+
+if test x"$a1" = x"/"; then
+       cd /
+       a1=-
+fi
+
+if test x"$a1" = x"-"; then
        shift
        exec /usr/bin/env -i \
            PATH=$p HOME=/ \
            "$@"
 fi
+
 exec /usr/bin/env -i \
-    PATH=$p $(locale 2>/dev/null | fgrep LC_CTYPE) \
+    PATH=$p TZ=UTC $(locale 2>/dev/null | fgrep LC_CTYPE) \
     DISPLAY="$DISPLAY" HOME="${HOME:-/}" TERM="${TERM:-vt100}" USER="${USER}" \
     "$@"
index 24d7a22..59178a2 100644 (file)
@@ -1,6 +1,5 @@
-.\" $Id: cleanenv.1 3351+X11R6 2012-12-17 14:16:11Z tglase $
 .ds p. /bin:/usr/bin:/sbin:/usr/sbin:/usr/X11R6/bin
-.Dd September 25, 2012
+.Dd October 3, 2014
 .Dt CLEANENV 1
 .Os
 .Sh NAME
@@ -8,7 +7,9 @@
 .Nd run programs with cleaned-up environment
 .Sh SYNOPSIS
 .Nm
-.Op Fl
+.Oo Fl \*(Ba
+.Pa /
+.Oc
 .Op Ev Foo=bar ...
 .Ic utility
 .Op Ar ...
@@ -18,6 +19,13 @@ The
 utility cleans the environment pointer, sets a few environment
 variables as well as those passed, and runs the program passed.
 With
+.Pa /
+as first option, it first changes to the root directory
+.Pq Pa / ,
+then operates the same as if
+.Fl
+were passed.
+With
 .Fl
 set, it cleans even more, i.e. anonymises: only
 .Ev HOME Ns = Ns Pa /
@@ -38,6 +46,9 @@ if not set in the current environment,
 .Ev TERM
 defaults to
 .Ic vt100 ,
+.Ev TZ
+is forcibly set to
+.Ic UTC ,
 and the
 .Xr locale 1
 utility is used to determine the value of
diff --git a/posix/pbuilder-hooks/A88shell-raw b/posix/pbuilder-hooks/A88shell-raw
new file mode 100644 (file)
index 0000000..a3d6066
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh
+# $MirOS: contrib/hosted/tg/deb/hookdir/A88shell-raw,v 1.1 2016/10/07 23:05:20 tg Exp $
+#-
+# Not complicated enough for copyright.
+
+unset LANGUAGE
+LC_ALL=C; export LC_ALL
+
+echo "I: Current time: $(date)"
+echo
+echo Trying to invoke a shell, with no extra packages installed...
+echo
+/bin/sh 0<>/dev/tty >&0 2>&0
index 8c5764b..675a03b 100644 (file)
@@ -1,7 +1,9 @@
 #!/bin/sh
-# $MirOS: contrib/hosted/tg/deb/hookdir/C80shell-jupp,v 1.3 2013/02/06 18:27:04 tg Exp $
+# $MirOS: contrib/hosted/tg/deb/hookdir/C80shell-jupp,v 1.6 2016/10/07 23:05:21 tg Exp $
 #-
 # Not complicated enough for copyright.
+#
+# This can also be used in an A or B hook nowadays.
 
 unset LANGUAGE
 LC_ALL=C; export LC_ALL
@@ -10,6 +12,7 @@ echo "I: Current time: $(date)"
 echo
 echo Build failed. Trying to invoke a shell.
 echo
-apt-get -y --force-yes install less mksh ed jupp
+apt-get -y install less mksh ed jupp || \
+    apt-get -y install less mksh ed joe
 ENV=/etc/skel/.mkshrc /bin/mksh -l 0<>/dev/tty >&0 2>&0 || \
     /bin/sh 0<>/dev/tty >&0 2>&0
diff --git a/posix/pbuilder-hooks/D00local b/posix/pbuilder-hooks/D00local
new file mode 100644 (file)
index 0000000..cda212b
--- /dev/null
@@ -0,0 +1,51 @@
+#!/bin/bash
+# $MirOS: contrib/hosted/tg/deb/hookdir/D00local,v 1.5 2016/10/14 22:41:53 tg Exp $
+#-
+# Copyright © 2014, 2016
+#      mirabilos <m@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.
+#-
+# Configure $base and $this at the beginning of the file. Do ensure:
+# • base must be URI safe since we do not encode it for sources.list
+# • this must be a valid basename for sources.list.d: [A-Za-z0-9._-]
+
+base=/var/cache/apt
+this=D00local
+
+
+unset LANGUAGE
+LC_ALL=C; export LC_ALL
+
+shopt -s extglob
+base=${base%%*(/)}
+pstr=${base//\//_}_._Packages
+
+echo >&2 "I: creating Packages file for local APT cache in $base"
+rm -f "$base/Packages"
+(cd "$base"
+#dpkg-scanpackages -h md5 -m . >Packages 2>/dev/null || \
+    dpkg-scanpackages -m . >Packages)
+paste -d_ <(sed -n '/^Package: /s///p' "$base/Packages") \
+    <(sed -n '/^Version: /s///p' "$base/Packages") \
+    <(sed -n '/^Architecture: /s///p' "$base/Packages") | \
+    sed 's/^/N: /' >&2
+echo >&2 "I: updating APT repository information"
+cp "$base/Packages" "/var/lib/apt/lists/$pstr"
+echo "deb [trusted=yes] file://$base ./" >"/etc/apt/sources.list.d/$this.list"
+apt-cache gencaches
+echo >&2 "I: made $(grep -c '^Package: ' "$base/Packages") packages available from $base"
+exit 0
index 64551b7..2ec8f4c 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# $MirOS: contrib/hosted/tg/deb/hookdir/D02debhelper,v 1.3 2012/01/03 16:57:19 tg Exp $
+# $MirOS: contrib/hosted/tg/deb/hookdir/D02debhelper,v 1.4 2016/01/14 18:46:20 tg Exp $
 #-
 # Not complicated enough for copyright.
 
@@ -7,4 +7,4 @@ unset LANGUAGE
 LC_ALL=C; export LC_ALL
 
 dpkg -i /tmp/debhelper*deb
-apt-get -y --force-yes -o Dpkg::Options::=--force-confnew,confmiss -f install
+apt-get -y -o Dpkg::Options::=--force-confnew,confmiss -f install
index bf37299..f7ff532 100644 (file)
@@ -1,17 +1,65 @@
 #!/bin/sh
-# $MirOS: contrib/hosted/tg/deb/hookdir/D10wtfrepo,v 1.1 2012/01/03 16:57:19 tg Exp $
+# $MirOS: contrib/hosted/tg/deb/hookdir/D10wtfrepo,v 1.5 2016/08/23 18:02:06 tg Exp $
 #-
 # Not complicated enough for copyright.
 
 unset LANGUAGE
 LC_ALL=C; export LC_ALL
 
-dpkg -i /tmp/wtf-debian-keyring_*.deb /tmp/ca-bundle_*.deb
-apt-get -y --force-yes -o Dpkg::Options::=--force-confnew,confmiss -f install
-apt-get -y --purge install apt-transport-https
+d=${DIST%/*}
+d=${d%-backports*}
+case $d in
+(sarge|etch|lenny|squeeze|wheezy|jessie|sid)
+       ;;
+(stretch|buster|bullseye)
+       d=sid
+       ;;
+(*)
+       echo >&2 W: D10wtfrepo: ignoring unknown DIST "'$DIST'"
+       exit 0
+       ;;
+esac
 
-cat >>/etc/apt/sources.list <<'EOF'
-deb https://www.freewrt.org/~tg/debs sid wtf
+# Import 2015 key
+apt-key add - <<'EOF'
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.14 (MirBSD)
+
+mQGNBFSNsycBDADQdl54UXf9oXNjOSjwnzopJbeaK5CJ8tvotnVv69KUg0VGUzkx
+lndV8rBvg8mWnRq8hWeEQNw0Yt2TDt1kg/cuo3NX+1xrMcfFyeeXxQhFewkd9SSO
+71EnGaG1NnHytzFx1olcs74aOzXAvyIson86dvwp1oSKrFeyvVpY7X7eltzkeM9X
+2bpmNWl06NjmgLg5Pmboh6EGAQh6Zpk4zVl5nC1Gq0lYYnYuJNHoSwA3RQCH3zST
+Im8gKh98smZ8dVaOK7rWzQvSQiWXpkZ2fzWsF4e2sNbwCW+FWHLHM89BLJiPO4k0
+wEEkBWguYCpddUMWwfmewWzxFU8fjhxiTq31MJSrt4r5LLwh0N1GGQXp2soCmsAN
+gT1qIV3UUJb3Ion/0iiQSqCnDNZjFlaGziPIiezU4pavOl7+fUy0vq4RXac8f2TJ
+fda8Hk3uNRRlQAlcMc00mn0a3rdYFGGempitl29c3C4GarD7M3sXwcR/0xBDJnkQ
+ZRVTfNFYB91BpJEAEQEAAYkBtwQfAQkAIQUCVI2zJxcMgAGQMZVeepek/aMrK4Z2
+tTSy6ZAH4AIHAAAKCRAwwGD6ILJPR7KlC/9aNtjsuWCnLC8s4h+m5bJBvciLci14
+0/JNOkj9982r6ijtrorcu0krpkZV2uZlrWy6veER6uMMjKynKY8HD0KSkTZu6XJ+
+YYf4tAjaEsr+AOQIIZuuKUR1XT9tMJ9uQwZ/ZIXtGz6sulYmkvi+0dQpzLI7YfoW
+83PfujnBopU3CyMJR63eAlkmJBo/QWwrB4XEfGVZ765H5j/wMxb5Vzr8s/ZpGzQ6
+KDWYIHO49A7ShGGAq8oSAJbtqtBLkVCw63l1/CetPFBQMKnsZNUie0s04gOUvMBn
+oWp6+KL3RjWLsDV62/yHJfjATQ56UmgQztYbqc3VFDIQrO9c+reAItnNdNxdXjob
++c0ixCT4SYCas73Y9fi5fV5D3Lx/aIcBJmKONSfYcizkdDAs0eZpRbbdpggEaiBV
+2XFcMYrMDq3ZOsSn3/YTpYTn+ZT+jQB/Bf75nzZvNWPIKaeu5lw2ClcOdZ5z7r37
+DY2VSfUYLGbuXaPA37Bu0IhpRIfQULO4num0MVNpZ25pbmcga2V5IDIwMTUgZm9y
+IOKAnFdURuKAnSBwYWNrYWdlIHJlcG9zaXRvcnmJAdEEEwEJADsFAlSNsycCGwMF
+CQW7xvIFCwgECQcFFQkKAwgDFgIAAh4BAheAFRhoa3A6Ly9wZ3Auc3VyZm5ldC5u
+bAAKCRAwwGD6ILJPR3AMC/9Q2lXxARjdmZ+99/0zv5I/PFlUIY402uH0ryajIzZ6
+yCIbw85n32IE66BRs2YSyVDv9yK58btAx1zuvTM3HxkVHt76lQcVEPRSZnJKJErI
+J6h27nj5HDsJDs9dq3BK4xcN/Qv+YMtbNg7Rr0x3bYR7+vRTiNvnVIaqe78AvDfm
+zRgkAuUckbcyprSxB5wcMolPJsePDeWXNEsOHqMEQ5Kud2az7shCam361PtUHDHp
+nJD9piSzb7JnConxbkvMp+ulEfQyUYI+XMBOpGT+d+dyVnhgXy+StcS5lV8rEUYy
+DXKTpHI1AzJrdRpH1NgHz+r4GbRHbJ/gH2TbtXPq7mCswlVdzcTLZiQD/0TG4UZP
+gENBqZrRjMxIywm04sv4UjybIwHJikeYNMgmlk8hWKdt5mvIioBTxq6r8BifbA/1
+nBSnBj7EHBDFcWHKwfmXf8DEaznk8tPPLAJ5ZPv3HkqfPYBBvXJ26gQN/TzXM24p
+sptjizYTgjcFMaB/hIYnoNM=
+=Ar55
+-----END PGP PUBLIC KEY BLOCK-----
+EOF
+
+cat >>/etc/apt/sources.list <<EOF
+deb http://www.mirbsd.org/~tg/Debs/ $d wtf
 EOF
 
 apt-get update
diff --git a/posix/pbuilder-hooks/D25backports b/posix/pbuilder-hooks/D25backports
new file mode 100644 (file)
index 0000000..f5aef9c
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/sh
+# $MirOS: contrib/hosted/tg/deb/hookdir/D25backports,v 1.2 2016/10/08 20:44:33 tg Exp $
+#-
+# Not complicated enough for copyright.
+#
+# Note: Secure APT is a PITA, for old versions.
+#
+# Note: This will not work with pbuilder-satisfydepends-classic,
+# and on sarge not with pbuilder-satisfydepends (aptitude) either.
+
+unset LANGUAGE
+LC_ALL=C; export LC_ALL
+
+d=${DIST%/*}
+d=${d%-backports*}
+case $d in
+(sarge|etch|lenny|squeeze)
+       echo deb http://archive.debian.org/debian-backports/ \
+           $d-backports main >>/etc/apt/sources.list
+       ;;
+(wheezy|jessie)
+       echo deb http://httpredir.debian.org/debian/ \
+           $d-backports main >>/etc/apt/sources.list
+       ;;
+(*)
+       echo >&2 W: D25backports: ignoring unknown DIST "'$DIST'"
+       exit 0
+       ;;
+esac
+
+apt-get update
index 65bfe01..22368e6 100644 (file)
@@ -1,4 +1,5 @@
 #!/bin/sh
-# $MirOS: contrib/hosted/tg/wcdiff,v 1.1 2012/09/01 19:07:12 tg Exp $
+# $MirOS: contrib/hosted/tg/wcdiff,v 1.2 2014/11/17 10:34:14 tg Exp $
+
 exec wdiff -w '\e[4;34m⌦\e[0m\e[1;4;31m' -x '\e[0m\e[4;34m⌫\e[0m' \
     -y '\e[4;34m▶\e[0m\e[1;4;32m' -z '\e[0m\e[4;34m◀\e[0m' "$@"
diff --git a/posix/wcdiff.1 b/posix/wcdiff.1
new file mode 100644 (file)
index 0000000..6586067
--- /dev/null
@@ -0,0 +1,32 @@
+.Dd February 28, 2014
+.Dt WCDIFF 1
+.Os
+.Sh NAME
+.Nm wcdiff
+.Nd colourised display of word differences between text files
+.Sh SYNOPSIS
+.Nm
+.Op Ic wdiff-options
+.Ar old_file
+.Ar new_file
+.Sh DESCRIPTION
+The
+.Nm
+utility shows the whole of the two files passed, with differences
+marked with blue symbols, the new text being green (with pointing
+triangles) and the old text being red (with deletion symbols).
+In the background, it merely calls
+.Nm wdiff ,
+with some options preset, namely
+.Fl w ,
+.Fl x ,
+.Fl y
+and
+.Fl z .
+All arguments to
+.Nm
+are passed through as-is.
+.Sh SEE ALSO
+.Xr wdiff 1
+.Sh AUTHORS
+.An Thorsten Glaser Aq tg@mirbsd.org