#!/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
	find_warnfiles "/usr/info may not contain filenames with spaces:" \
		usr/info -name '* *'

	for i in usr/info/*; do
		if [ "$i" != 'usr/info/*' ]; then
			case "$i" in
			*' '*) ;; # space in filename, already complained about
			*)
				if [ -d "$i" ]; then
					BADDIRS+="$i "
				else
					case "$i" in
						usr/info/dir)  dir_found=1 ;                                    ;;
						*.info*.gz)   info_found=1 ; check_info "$i" 1                  ;;
						*.info*)      info_found=1 ; check_info "$i" 0 ; NONGZIP+="$i " ;;
						*)            BADFILES+="$i " ;;
					esac
				fi
			esac
		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 valid info files" ;;
	esac

	[ -n "$BADDIRS" ]  && warn "/usr/info may not contain subdirectories: " && ls -ld $BADDIRS
	[ -n "$BADFILES" ] && warn "/usr/info contains non-info files: " && ls -ld $BADFILES
	[ -n "$NONINFO" ]  && warn "/usr/info contains invalid info files: " && ls -ld $NONINFO
	[ -n "$NONGZIP" ]  && note "/usr/info contains non-gzipped info files: " && ls -ld $NONGZIP
fi
