diff options
-rw-r--r-- | sbopkglint.d/60-usr_info.t.sh | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/sbopkglint.d/60-usr_info.t.sh b/sbopkglint.d/60-usr_info.t.sh new file mode 100644 index 0000000..61fe8dc --- /dev/null +++ b/sbopkglint.d/60-usr_info.t.sh @@ -0,0 +1,87 @@ +#!/bin/sh + +# sbopkglint test, must be sourced by sbopkglint (not run standalone). + +# PKG, PRGNAM, VERSION, ARCH are set by sbopkglint. also the current +# directory is the root of the installed package tree. + +####################################################################### +# check GNU info files in /usr/info. note that these have nothing to +# do with SBo .info files (those don't go in packages anyway). +# +# if /usr/info exists, it must have at least one *.info or *.info.gz +# file in it, and it must have 'dir' (which got created by doinst.sh; +# the preinstall test ensures /usr/info/dir isn't actually a regular +# file in the package). +# +# non-gzipped .info files cause warnings (non-fatal). +# +# content of 'dir' and each .info(.gz) file is checked, but not in +# great detail. +# +# if there are info files and a dir, check whether there's a douninst.sh to +# clean up on package removal... but it's just a "note", non-fatal, since +# we have thousands of packages that predate the existence of douninst.sh. +# +# this is more complicated than it should be because our file command +# doesn't recognize .info files (it just calls them "data", with MIME +# type "application/octet-stream"). all valid .info files that I've seen +# have the 0x1f character (US, unit separator), so we'll check for that. + +info_found=0 +dir_found=0 +BADDIRS="" +BADFILES="" +NONINFO="" +NONGZIP="" + +# 2 args: $1 is the file to check, $2 is 1 for .gz name, 0 otherwise. +# The LANG=C is because we're grepping for raw bytes, not characters +# in e.g. UTF-8 encoding. Believe it or not, using head and grep is +# quite a bit faster than using the file command... though we could +# make file faster with "file -m /etc/file/magic/compress". +check_info() { + local is_gzip=0 + head -c2 "$1" | LANG=C grep -Pq '\x1f\x8b' && is_gzip=1 + + if [ "$2" = 0 ]; then + [ "$is_gzip" = "1" ] && warn "$i is gzipped but lacks .gz extension" + else + [ "$is_gzip" = "0" ] && warn "$i has .gz extension but is not gzipped" + fi + + LANG=C zgrep -Pq '\x1f' "$1" || NONINFO+="$1 " +} + +if [ -d usr/info ]; then + for i in usr/info/*; do + if [ "$i" != 'usr/info/*' ]; then + if [ -d "$i" ]; then + BADDIRS+="$i " + else + case "$i" in + usr/info/dir) dir_found=1 ; check_info "$i" 0 ;; + *.info) info_found=1 ; check_info "$i" 0 ; NONGZIP+="$i " ;; + *.info.gz) info_found=1 ; check_info "$i" 1 ;; + *) BADFILES+="$i " ;; + esac + fi + fi + done + + case "$dir_found$info_found" in + "11") ## doinst.sh is OK, but do we have a good douninst.sh? + if ! grep '^[^#]*install-info' var/lib/pkgtools/douninst.sh/* &>/dev/null ; then + note "package adds to /usr/info/dir, needs a douninst.sh to clean it up" + fi + ;; + "01") warn "package has info files, but doinst.sh does not call install-info" ;; + "10") warn "package has no info files, but /usr/info/dir is created by doinst.sh (huh?)" ;; + "00") warn "/usr/info exists, but contains no info files" ;; + esac + + [ -n "$BADDIRS" ] && warn "/usr/info may not contain subdirectories: " && ls -ld $BADDIRS + [ -n "$BADFILES" ] && warn "/usr/info contains bogus files: " && ls -ld $BADFILES + [ -n "$NONINFO" ] && warn "/usr/info contains bad info files: " && ls -ld $NONINFO + [ -n "$NONGZIP" ] && note "/usr/info contains non-gzipped info files: " && ls -ld $NONGZIP +fi |