#!/bin/sh -
#
# Alex Kozlov <ak@FreeBSD.org> , 2008 - 2020
# Public domain or 2-clause BSD License
#

PATH=/bin:/usr/bin
LANG=C

parse_options()
{
	local OPT OPTARG OPTIND

	while getopts aw OPT; do
		# escape meta
		OPTARG=${OPTARG%%[;\\\$]*}

		case ${OPT} in
		a)	opt_all=yes ;;
		w)	opt_skip_white=yes ;;
		*)	usage ;;
		esac
	done

	OPTC=$((${OPTIND} - 1))
}

usage()
{
	echo "usage: ${0##*/} [-aw] [portsdir]"
	echo '	-a all checks'
	echo '	-w disable whitelists'
	echo
	exit 1
}


#
# MAIN
#

parse_options ${1+"$@"}
shift ${OPTC}

_PORTSDIR=${1-'/usr/ports'}
# normalize
_PORTSDIR=$(realpath "${_PORTSDIR}")
[ -d ${_PORTSDIR} ] || usage

[ -n "$2" ] && usage

echo empty files and directories:
find "${_PORTSDIR}" -empty
echo

echo nonstandard directories:
whitelist="
/files
/scripts"

whitelist_userdir=E_m_P_t_Y_s_E_t

# validate whitelist
for name in ${whitelist_userdir}; do
	[ ${whitelist_userdir} == E_m_P_t_Y_s_E_t -o -d "${_PORTSDIR}/${name}" ] || \
		echo whitelist: ${name} doesn\'t exist
done

# convert to grep regexp
whitelist="$(echo ${whitelist} | sed -e 's/ /|/g')"

if [ -n "${opt_skip_white}" ]; then
	whitelist_userdir=E_m_P_t_Y_s_E_t
else
	# convert to grep regexp
	whitelist_userdir="$(echo ${whitelist_userdir} | sed -e 's/ /|/g')"
fi

# no maxdepth
find "${_PORTSDIR}" -mindepth 3 -type d | \
	grep -vE "${whitelist}|${whitelist_userdir}"
echo

echo nonstandard files:
whitelist="
${_PORTSDIR}/Templates
${_PORTSDIR}/Tools
${_PORTSDIR}/Mk/Uses
${_PORTSDIR}/Mk/Scripts
${_PORTSDIR}/Mk/Wrappers
${_PORTSDIR}/distfiles
${_PORTSDIR}/packages
Makefile$
distinfo$
pkg-help$
pkg-plist$
pkg-message$
pkg-descr$
pkg-install$
pkg-deinstall$
Makefile.common$
pkg-plist.i386$
pkg-plist.amd64$"

whitelist_userfile="
audio/baresip/Makefile.depends
audio/fluidplug-lv2/Makefile.list
audio/timidity++/Makefile.interface
cad/kicad-devel/Makefile.git_rev
cad/kicad-library-footprints-devel/Makefile.git_rev
cad/kicad-library-packages3d-devel/Makefile.git_rev
cad/kicad-library-symbols-devel/Makefile.git_rev
cad/kicad-library-templates-devel/Makefile.git_rev
chinese/ttfm/Makefile.ttf
comms/hackrf-devel/Makefile.git_rev
comms/opencbm/Makefile.inc
comms/owfs/Makefile.options
databases/apq/Makefile.version
databases/firebird25-server/pkg-install-server
databases/firebird25-server/pkg-plist.client
databases/linux-oracle-instantclient-basic/distinfo.amd64
databases/linux-oracle-instantclient-basic/distinfo.i386
databases/linux-oracle-instantclient-sdk/distinfo.amd64
databases/linux-oracle-instantclient-sdk/distinfo.i386
databases/phpmyadmin/pkg-plist-chunk
databases/phpmyadmin5/pkg-plist-chunk
databases/postgresql95-server/pkg-install-server
databases/postgresql95-server/pkg-plist-client
databases/postgresql95-server/pkg-plist-contrib
databases/postgresql95-server/pkg-plist-plperl
databases/postgresql95-server/pkg-plist-plpython
databases/postgresql95-server/pkg-plist-pltcl
databases/postgresql95-server/pkg-plist-server
databases/postgresql96-server/pkg-install-server
databases/postgresql96-server/pkg-plist-client
databases/postgresql96-server/pkg-plist-contrib
databases/postgresql96-server/pkg-plist-plperl
databases/postgresql96-server/pkg-plist-plpython
databases/postgresql96-server/pkg-plist-pltcl
databases/postgresql96-server/pkg-plist-server
databases/postgresql10-server/pkg-install-server
databases/postgresql10-server/pkg-plist-client
databases/postgresql10-server/pkg-plist-contrib
databases/postgresql10-server/pkg-plist-plperl
databases/postgresql10-server/pkg-plist-plpython
databases/postgresql10-server/pkg-plist-pltcl
databases/postgresql10-server/pkg-plist-server
databases/postgresql11-server/pkg-install-server
databases/postgresql11-server/pkg-plist-client
databases/postgresql11-server/pkg-plist-contrib
databases/postgresql11-server/pkg-plist-plperl
databases/postgresql11-server/pkg-plist-plpython
databases/postgresql11-server/pkg-plist-pltcl
databases/postgresql11-server/pkg-plist-server
databases/postgresql12-server/pkg-install-server
databases/postgresql12-server/pkg-plist-client
databases/postgresql12-server/pkg-plist-contrib
databases/postgresql12-server/pkg-plist-plperl
databases/postgresql12-server/pkg-plist-plpython
databases/postgresql12-server/pkg-plist-pltcl
databases/postgresql12-server/pkg-plist-server
databases/postgresql13-server/pkg-install-server
databases/postgresql13-server/pkg-plist-client
databases/postgresql13-server/pkg-plist-contrib
databases/postgresql13-server/pkg-plist-plperl
databases/postgresql13-server/pkg-plist-plpython
databases/postgresql13-server/pkg-plist-pltcl
databases/postgresql13-server/pkg-plist-server
deskutils/gnome-shell-extra-extensions/pkg-message.slaves
devel/avr-libc/pkg-plist.doc
devel/binutils/pkg-plist-aarch64
devel/binutils/pkg-plist-aarch64-none-elf
devel/binutils/pkg-plist-arm-gnueabi
devel/binutils/pkg-plist-arm-none-eabi
devel/binutils/pkg-plist-avr
devel/binutils/pkg-plist-mingw32
devel/binutils/pkg-plist-mips
devel/binutils/pkg-plist-mips64
devel/binutils/pkg-plist-powerpc
devel/binutils/pkg-plist-powerpc64
devel/binutils/pkg-plist-powerpc64le
devel/binutils/pkg-plist-riscv32-unknown-elf
devel/binutils/pkg-plist-riscv64
devel/binutils/pkg-plist-riscv64-none-elf
devel/binutils/pkg-plist-s390x
devel/binutils/pkg-plist-sparc64
devel/boost-all/common.mk
devel/boost-all/compiled.mk
devel/boost-all/pkg-message.python
devel/boost-all/pkg-message.threads
devel/bugzilla44/Makefile.options
devel/bugzilla50/Makefile.options
devel/ccache/distinfo.memcached
devel/compiler-rt/Makefile.svn_rev
devel/cppcheck/pkg-plist-gui
devel/electron11/Makefile.version
devel/eric6/Makefile.inc
devel/eric6/bsd.eric6.mk
devel/freebsd-gcc6/pkg-plist.mips
devel/freebsd-gcc6/pkg-plist.powerpc
devel/freebsd-gcc6/pkg-plist.sparc64
devel/freebsd-gcc6/pkg-plist.aarch64
devel/freebsd-gcc6/pkg-plist.arm
devel/freebsd-gcc6/pkg-plist.common
devel/freebsd-gcc9/pkg-plist.arm
devel/freebsd-gcc9/pkg-plist.sparc64
devel/freebsd-gcc9/pkg-plist.mips
devel/freebsd-gcc9/pkg-plist.riscv
devel/freebsd-gcc9/pkg-plist.powerpc64
devel/freebsd-gcc9/pkg-plist.powerpc
devel/freebsd-gcc9/pkg-plist.aarch64
devel/git/pkg-descr-gui
devel/git/pkg-descr-tiny
devel/git/pkg-descr-lite
devel/gnome-vfs/pkg-deinstall.in
devel/gnome-vfs/pkg-install.in
devel/llvm-devel/Makefile.COMMANDS
devel/llvm-devel/Makefile.LICENSE
devel/llvm-cheri/Makefile.snapshot
devel/llvm-devel/Makefile.snapshot
devel/llvm60/Makefile.COMMANDS
devel/llvm70/Makefile.COMMANDS
devel/llvm80/Makefile.COMMANDS
devel/llvm90/Makefile.COMMANDS
devel/llvm10/Makefile.COMMANDS
devel/llvm11/Makefile.COMMANDS
devel/monodevelop/nupkg-vssdk
devel/monodevelop/nupkg-roslyn
devel/monodevelop/nupkg-nuget
devel/monodevelop/nupkg-roslyn_for_vs_for_mac
devel/monodevelop/nupkg-vstest
devel/monodevelop/nupkg-vs_impl
devel/monodevelop/nupkg-vs_editor
devel/monodevelop/nupkg-templating
devel/msbuild/nupkg-roslyn_tools
devel/msbuild/nupkg-symreader_converter
devel/msbuild/nupkg-nuget
devel/msbuild/nupkg-dotnet_core
devel/msbuild/nupkg-roslyn
devel/p4/Makefile.inc
devel/pear/bsd.pear.channel.mk
devel/pear/pear-deinstall.in
devel/pear/pear-install
devel/qt5/Makefile.sqldrivers
devel/sdl12/pkg-message.linjoy
devel/sdl12/pkg-message.vgl
devel/subversion/Makefile.addons
devel/thrift/bsd.thrift.mk
devel/tig/pkg-message-git
dns/bind-tools/pkg-plist-devel
dns/doh-proxy/Makefile.crates
editors/emacs/pkg-descr-canna
editors/libreoffice/Makefile.i18n
editors/libreoffice/pkg-descr.i18n
editors/libreoffice6/Makefile.i18n
editors/libreoffice6/pkg-descr.i18n
emulators/i386-wine/Makefile.i386
emulators/i386-wine/Makefile.amd64
emulators/i386-wine-devel/Makefile.i386
emulators/i386-wine-devel/Makefile.amd64
emulators/qemu-cheri/Makefile.snapshot
french/aster/bsd.aster.mk
games/digger-vgl/pkg-message.sound
games/doom-data/Makefile.include
games/linux-unigine-valley/pkg-license
games/openarena/Makefile.include
games/prboom-plus/Makefile.include
games/quake-data/Makefile.include
games/quake-source/Makefile.include
games/quake2-data/Makefile.include
games/quake3-data/Makefile.include
games/redeclipse-data/Makefile.tuples
games/simutrans/Makefile.pak
games/xpilot-ng-server/pkg-descr.client
games/xpilot-ng-server/pkg-descr.server
games/xpilot-ng-server/pkg-plist.client
games/xpilot-ng-server/pkg-plist.server
graphics/blender/Makefile.options
graphics/blender/Makefile.versions
graphics/evince/pkg-plist-lite
graphics/mesa-dri/Makefile.targets
graphics/opencolorio/pkg-plist-pyglue
graphics/opencolorio/pkg-plist-tools
graphics/openimageio/pkg-plist-pybind
graphics/openshadinglanguage/pkg-plist-pybind
java/bootstrap-openjdk6/Makefile.update
java/bootstrap-openjdk6/distinfo.amd64
java/bootstrap-openjdk6/distinfo.i386
java/bootstrap-openjdk8/Makefile.update
java/bootstrap-openjdk8/distinfo.aarch64
java/bootstrap-openjdk8/distinfo.amd64
java/bootstrap-openjdk8/distinfo.arm
java/bootstrap-openjdk8/distinfo.i386
java/bootstrap-openjdk8/distinfo.ppc64
java/bootstrap-openjdk8/distinfo.ppc64le
java/eclipse/Makefile.plugins
java/intellij/common.mk
korean/nanumfonts-otf/distinfo.otf
korean/nanumfonts-otf/distinfo.ttf
korean/unfonts-core/distinfo.core-ttf
korean/unfonts-core/distinfo.extra-ttf
lang/fpc/Makefile.units
lang/fsharp/nupkg-nuget
lang/gcc6-aux/Makefile.version
lang/gnat_util/Makefile.sources
lang/io/Makefile.addons
lang/perl5.28/version.mk
lang/perl5.30/version.mk
lang/perl5.32/version.mk
lang/perl5-devel/version.mk
lang/php73/Makefile.ext
lang/php73/pkg-message.mod
lang/php73/pkg-plist.mod
lang/php74/Makefile.ext
lang/php74/pkg-message.mod
lang/php74/pkg-plist.mod
lang/php80/Makefile.ext
lang/php80/pkg-message.mod
lang/php80/pkg-plist.mod
lang/pypy/bsd.pypy.cffi.mk
lang/pypy/bsd.pypy.mk
lang/python27/Makefile.version
lang/python36/Makefile.version
lang/python37/Makefile.version
lang/python38/Makefile.version
lang/python39/Makefile.version
mail/cclient/pkg-message-ssl
mail/claws-mail/Makefile.claws
mail/courier/Makefile.doc
mail/courier/Makefile.own
mail/dk-milter/Makefile.features
mail/dk-milter/pkg-message.postfix
mail/exim/options
mail/opendkim/Makefile.options
mail/panda-cclient/pkg-message-ssl
mail/sendmail/bsd.milter.mk
mail/thunderbird-dictionaries/Makefile.dict
mail/thunderbird-dictionaries/Makefile.options
math/octave/Makefile.version
math/rubygem-narray/Makefile.version
misc/compat12x/pkg-plist.armv6
misc/compat12x/pkg-plist.armv7
misc/compat12x/pkg-plist.aarch64
misc/compat4x/pkg-plist.freebsd4
misc/compat4x/pkg-plist.freebsd5
misc/compat6x/pkg-plist.sparc64
misc/dnetc/distinfo.amd64
misc/dnetc/distinfo.i386
misc/dnetc/distinfo.powerpc
misc/dnetc/distinfo.sparc64
misc/freebsd-doc-bn/pkg-plist.common
misc/freebsd-doc-bn/pkg-plist.html
misc/freebsd-doc-bn/pkg-plist.html-common
misc/freebsd-doc-bn/pkg-plist.html-split
misc/freebsd-doc-bn/pkg-plist.pdf
misc/freebsd-doc-bn/pkg-plist.txt
misc/freebsd-doc-da/pkg-plist.common
misc/freebsd-doc-da/pkg-plist.html
misc/freebsd-doc-da/pkg-plist.html-common
misc/freebsd-doc-da/pkg-plist.html-split
misc/freebsd-doc-da/pkg-plist.pdf
misc/freebsd-doc-da/pkg-plist.txt
misc/freebsd-doc-de/pkg-plist.common
misc/freebsd-doc-de/pkg-plist.extras
misc/freebsd-doc-de/pkg-plist.html
misc/freebsd-doc-de/pkg-plist.html-common
misc/freebsd-doc-de/pkg-plist.html-split
misc/freebsd-doc-de/pkg-plist.pdf
misc/freebsd-doc-de/pkg-plist.txt
misc/freebsd-doc-el/pkg-plist.common
misc/freebsd-doc-el/pkg-plist.html
misc/freebsd-doc-el/pkg-plist.html-common
misc/freebsd-doc-el/pkg-plist.html-split
misc/freebsd-doc-el/pkg-plist.pdf
misc/freebsd-doc-el/pkg-plist.txt
misc/freebsd-doc-en/pkg-plist.common
misc/freebsd-doc-en/pkg-plist.extras
misc/freebsd-doc-en/pkg-plist.html
misc/freebsd-doc-en/pkg-plist.html-common
misc/freebsd-doc-en/pkg-plist.html-split
misc/freebsd-doc-en/pkg-plist.pdf
misc/freebsd-doc-en/pkg-plist.txt
misc/freebsd-doc-es/pkg-plist.common
misc/freebsd-doc-es/pkg-plist.html
misc/freebsd-doc-es/pkg-plist.html-common
misc/freebsd-doc-es/pkg-plist.html-split
misc/freebsd-doc-es/pkg-plist.pdf
misc/freebsd-doc-es/pkg-plist.txt
misc/freebsd-doc-fr/pkg-plist.common
misc/freebsd-doc-fr/pkg-plist.html
misc/freebsd-doc-fr/pkg-plist.html-common
misc/freebsd-doc-fr/pkg-plist.html-split
misc/freebsd-doc-fr/pkg-plist.pdf
misc/freebsd-doc-fr/pkg-plist.txt
misc/freebsd-doc-hu/pkg-plist.common
misc/freebsd-doc-hu/pkg-plist.html
misc/freebsd-doc-hu/pkg-plist.html-common
misc/freebsd-doc-hu/pkg-plist.html-split
misc/freebsd-doc-hu/pkg-plist.pdf
misc/freebsd-doc-hu/pkg-plist.txt
misc/freebsd-doc-it/pkg-plist.common
misc/freebsd-doc-it/pkg-plist.html
misc/freebsd-doc-it/pkg-plist.html-common
misc/freebsd-doc-it/pkg-plist.html-split
misc/freebsd-doc-it/pkg-plist.pdf
misc/freebsd-doc-it/pkg-plist.txt
misc/freebsd-doc-ja/pkg-plist.common
misc/freebsd-doc-ja/pkg-plist.html
misc/freebsd-doc-ja/pkg-plist.html-common
misc/freebsd-doc-ja/pkg-plist.html-split
misc/freebsd-doc-ja/pkg-plist.pdf
misc/freebsd-doc-ja/pkg-plist.txt
misc/freebsd-doc-ko/pkg-plist.common
misc/freebsd-doc-ko/pkg-plist.html
misc/freebsd-doc-ko/pkg-plist.html-common
misc/freebsd-doc-ko/pkg-plist.html-split
misc/freebsd-doc-ko/pkg-plist.pdf
misc/freebsd-doc-ko/pkg-plist.txt
misc/freebsd-doc-mn/pkg-plist.common
misc/freebsd-doc-mn/pkg-plist.html
misc/freebsd-doc-mn/pkg-plist.html-common
misc/freebsd-doc-mn/pkg-plist.html-split
misc/freebsd-doc-mn/pkg-plist.pdf
misc/freebsd-doc-mn/pkg-plist.txt
misc/freebsd-doc-nl/pkg-plist.common
misc/freebsd-doc-nl/pkg-plist.html
misc/freebsd-doc-nl/pkg-plist.html-common
misc/freebsd-doc-nl/pkg-plist.html-split
misc/freebsd-doc-nl/pkg-plist.pdf
misc/freebsd-doc-nl/pkg-plist.txt
misc/freebsd-doc-pl/pkg-plist.common
misc/freebsd-doc-pl/pkg-plist.html
misc/freebsd-doc-pl/pkg-plist.html-common
misc/freebsd-doc-pl/pkg-plist.html-split
misc/freebsd-doc-pl/pkg-plist.pdf
misc/freebsd-doc-pl/pkg-plist.txt
misc/freebsd-doc-pt/pkg-plist.common
misc/freebsd-doc-pt/pkg-plist.extras
misc/freebsd-doc-pt/pkg-plist.html
misc/freebsd-doc-pt/pkg-plist.html-common
misc/freebsd-doc-pt/pkg-plist.html-split
misc/freebsd-doc-pt/pkg-plist.pdf
misc/freebsd-doc-pt/pkg-plist.txt
misc/freebsd-doc-ru/pkg-plist.common
misc/freebsd-doc-ru/pkg-plist.html
misc/freebsd-doc-ru/pkg-plist.html-common
misc/freebsd-doc-ru/pkg-plist.html-split
misc/freebsd-doc-ru/pkg-plist.pdf
misc/freebsd-doc-ru/pkg-plist.txt
misc/freebsd-doc-tr/pkg-plist.common
misc/freebsd-doc-tr/pkg-plist.html
misc/freebsd-doc-tr/pkg-plist.html-common
misc/freebsd-doc-tr/pkg-plist.html-split
misc/freebsd-doc-tr/pkg-plist.pdf
misc/freebsd-doc-tr/pkg-plist.txt
misc/freebsd-doc-zh_cn/pkg-plist.common
misc/freebsd-doc-zh_cn/pkg-plist.html
misc/freebsd-doc-zh_cn/pkg-plist.html-common
misc/freebsd-doc-zh_cn/pkg-plist.html-split
misc/freebsd-doc-zh_cn/pkg-plist.pdf
misc/freebsd-doc-zh_cn/pkg-plist.txt
misc/freebsd-doc-zh_tw/pkg-plist.common
misc/freebsd-doc-zh_tw/pkg-plist.html
misc/freebsd-doc-zh_tw/pkg-plist.html-common
misc/freebsd-doc-zh_tw/pkg-plist.html-split
misc/freebsd-doc-zh_tw/pkg-plist.pdf
misc/freebsd-doc-zh_tw/pkg-plist.txt
multimedia/librespot/Makefile.crates
multimedia/mplayer-skins/Makefile.options
multimedia/mplayer-skins/Makefile.skins
multimedia/mplayer/Makefile.options
multimedia/mplayer/Makefile.optvars
multimedia/vdr/Makefile.plugins
net-im/tox/pkg-message.daemon
net-mgmt/ndpmon/pkg-message.MACRESOLV
net-mgmt/pandorafms_server/bsd.pandora.mk
net-mgmt/pandorafms_server/pkg-plist.spool
net-mgmt/prometheus2/Makefile.modules
net-mgmt/seafile-server/Makefile.include
net-mgmt/zabbix3-server/pkg-plist.agent
net-mgmt/zabbix3-server/pkg-plist.frontend
net-mgmt/zabbix3-server/pkg-plist.java
net-mgmt/zabbix4-server/pkg-plist.agent
net-mgmt/zabbix4-server/pkg-plist.frontend
net-mgmt/zabbix4-server/pkg-plist.java
net-mgmt/zabbix5-server/pkg-plist.agent
net-mgmt/zabbix5-server/pkg-plist.frontend
net-mgmt/zabbix5-server/pkg-plist.java
net-mgmt/zabbix52-server/pkg-plist.agent
net-mgmt/zabbix52-server/pkg-plist.frontend
net-mgmt/zabbix52-server/pkg-plist.java
net-p2p/qbittorrent/pkg-plist-nox
net-p2p/openethereum/Makefile.crates
net/cvsup-static/Makefile.DragonFly
net/cvsup-static/distinfo.amd64
net/ntp/Makefile.inc
net/openldap24-server/pkg-descr.client
net/openldap24-server/pkg-plist.client
net/remmina/pkg-descr-lite
net/storj/Makefile.deps
net/tigervnc-server/Makefile.common.mk
net/trafshow/pkg-message.nodevfs
net/unison240/pkg-message.nox11
net/unison248/pkg-message.nox11
net/unison/pkg-message.nox11
news/inn/Makefile.layout
print/ghostscript7-base/Makefile.drivers
print/ghostscript8-base/Makefile.drivers
print/ghostscript9-base/Makefile.drivers
print/pkfonts300/pkg-plist.118
print/pkfonts300/pkg-plist.240
print/pkfonts300/pkg-plist.300
print/pkfonts300/pkg-plist.360
print/pkfonts300/pkg-plist.400
print/pkfonts300/pkg-plist.600
science/healpix/pkg-plist-c
science/healpix/pkg-plist-cxx
science/gnudatalanguage/pkg-plist.pymod
science/jmol/pkg-plist-jsmol
science/msms/distinfo-amd64
science/msms/distinfo-i386
science/py-tensorflow/Makefile.MASTER_SITES
security/boringssl/version.mk
security/courier-authlib/Makefile.dep
security/courier-authlib/Makefile.opt
security/courier-authlib/pkg-descr-base
security/courier-authlib/pkg-descr-ldap
security/courier-authlib/pkg-descr-mysql
security/courier-authlib/pkg-descr-pgsql
security/courier-authlib/pkg-descr-sqlite
security/courier-authlib/pkg-descr-userdb
security/courier-authlib/pkg-descr-usergdbm
security/courier-authlib/pkg-descr-vchkpw
security/courier-authlib/pkg-plist-base
security/courier-authlib/pkg-plist-ldap
security/courier-authlib/pkg-plist-mysql
security/courier-authlib/pkg-plist-pgsql
security/courier-authlib/pkg-plist-sqlite
security/courier-authlib/pkg-plist-userdb
security/courier-authlib/pkg-plist-vchkpw
security/libressl/version.mk
security/libressl-devel/version.mk
security/openssl/version.mk
security/openssl-devel/version.mk
security/openssl-unsafe/version.mk
security/ossec-hids/version.mk
security/ossec-hids-local-config/opt-ar.mk
security/ossec-hids-local-config/opt-cmdout.mk
security/ossec-hids-local-config/pkg-help-agent
security/ossec-hids-local-config/pkg-help-local
security/ossec-hids-local-config/pkg-help-server
security/ossec-hids-local-config/opt-logs.mk
security/ossec-hids-local-config/opt-syscheck.mk
security/ossec-hids-local-config/pkg-plist-server
security/ossec-hids-local-config/opt-rootcheck.mk
security/ossec-hids-local-config/opt-rules.mk
security/ossec-hids-local-config/pkg-plist-local
security/ossec-hids-local-config/pkg-plist-agent
security/ossec-hids-local/pkg-plist-server
security/ossec-hids-local/pkg-plist-local
security/ossec-hids-local/pkg-plist-agent
security/pinentry/pkg-message.gnome3
security/py-angr/Makefile.version
security/py-acme/version.mk
security/trezord/Makefile.modules
security/vuxml/vuln.xml
security/vuxml/vuln-2003.xml
security/vuxml/vuln-2004.xml
security/vuxml/vuln-2005.xml
security/vuxml/vuln-2006.xml
security/vuxml/vuln-2007.xml
security/vuxml/vuln-2008.xml
security/vuxml/vuln-2009.xml
security/vuxml/vuln-2010.xml
security/vuxml/vuln-2011.xml
security/vuxml/vuln-2012.xml
security/vuxml/vuln-2013.xml
security/vuxml/vuln-2014.xml
security/vuxml/vuln-2015.xml
security/vuxml/vuln-2016.xml
security/vuxml/vuln-2017.xml
security/vuxml/vuln-2018.xml
security/vuxml/vuln-2019.xml
security/vuxml/vuln-2020.xml
sysutils/bacula9-server/pkg-plist.client
sysutils/bacula11-server/pkg-plist.client
sysutils/bareos-server/pkg-plist.client
sysutils/bareos17-server/pkg-plist.client
sysutils/bareos18-server/pkg-plist.client
sysutils/bareos19-server/pkg-plist.client
sysutils/cbsd/pkg-plist-chunk
sysutils/cdrtools-devel/pkg-install.rscsi
sysutils/cdrtools/pkg-install.rscsi
sysutils/jail_exporter/Makefile.crates
sysutils/munin-common/munin.mk
sysutils/node_exporter/Makefile.modules
textproc/apache-solr/create-plist.php
textproc/aspell/Makefile.inc
textproc/aspell/pkg-plist.en
textproc/jdictionary/Makefile.plugin
textproc/jdictionary/pkg-plist.plugin
textproc/xhtml-modularization/contents.inc
www/apache24/Makefile.options
www/apache24/Makefile.options.desc
www/chromium/Makefile.tests
www/firefox/Makefile.options
www/foswiki/bsd.foswiki.mk
www/madsonic/pkg-message-jetty
www/madsonic/pkg-message-resin3
www/madsonic/pkg-message-spacer
www/madsonic/pkg-message-tomcat
www/madsonic/pkg-plist-chunk
www/nginx/Makefile.extmod
www/nginx/Makefile.options.desc
www/nginx-devel/Makefile.extmod
www/nginx-devel/Makefile.options.desc
www/redmine4/bsd.redmine.mk
www/rt44/Makefile.cpan
www/rt50/Makefile.cpan
www/twiki/bsd.twiki.mk
www/unit/version.mk
x11-themes/gnome-icons/bsd.gnome-icons.mk
x11-themes/irssi-themes/Makefile.inc
x11-themes/kde-icons-noia/Makefile.icons
x11-themes/metacity-themes/Makefile.metacity
x11-themes/qtcurve/pkg-plist.gtk2
x11-themes/qtcurve/pkg-plist.kf5
x11-themes/qtcurve/pkg-plist.utils
x11/gnome3/pkg-descr-lite
x11/gnome3/pkg-message-lite
x11/xterm/pkg-message.wchar"

# contains user-defined USE_* variables
whitelist_usermkfile="
devel/cl-asdf/bsd.cl-asdf.mk
mail/squirrelmail/bsd.squirrelmail.mk"

# validate whitelist
for name in ${whitelist_usermkfile} ${whitelist_userfile}; do
	[ -f "${_PORTSDIR}/${name}" ] || echo whitelist: ${name} doesn\'t exist
done

# convert to grep regexp
whitelist="$(echo ${whitelist} | sed -e 's/ /|/g')"

if [ -n "${opt_skip_white}" ]; then
	__whitelist_usermkfile=E_m_P_t_Y_s_E_t
	whitelist_userfile=E_m_P_t_Y_s_E_t
else
	# convert to grep regexp, escape '+'
	__whitelist_usermkfile="$(echo ${whitelist_usermkfile} | \
		sed -e 's/ /|/g;s/+/\\+/g')"
	whitelist_userfile="$(echo ${whitelist_userfile} | \
		sed -e 's/ /|/g;s/+/\\+/g')"
fi

find "${_PORTSDIR}" -mindepth 3 -maxdepth 3 -type f | \
	grep -vwE "${whitelist}|${__whitelist_usermkfile}|${whitelist_userfile}"
echo
unset __whitelist_usermkfile

[ -n "${opt_all}" ] && \
{
	echo missing, nonstandard or duplicated lines in distinfo:
	whitelist_userdistinfo=E_m_P_t_Y_s_E_t

	# validate whitelist
	for name in ${whitelist_userdistinfo}; do
		[ "${name}" = E_m_P_t_Y_s_E_t -o -f "${_PORTSDIR}/${name}" ] || \
		echo whitelist: ${name} doesn\'t exist
	done

	if [ -n "${opt_skip_white}" ]; then
		whitelist_userdistinfo=E_m_P_t_Y_s_E_t
	else
		# convert to grep regexp
		whitelist_userdistinfo="$(echo ${whitelist_userdistinfo} | \
			sed -e 's/ /|/g')"
	fi

	DISTINFOLIST=$(find "${_PORTSDIR}" -mindepth 3 -maxdepth 3 -name distinfo\*)

	for file in $(echo "${DISTINFOLIST}" | \
		grep -vE "${whitelist_userdistinfo}"); do
		NAMELIST=$(while read alg fname equal chksum; do \
			case "${chksum}" in \
				*) \
					fname="${fname##(}"; \
					fname="${fname%%)}"; \
					case "${alg}" in \
						SIZE) echo "${fname}_size" ;; \
						SHA256) echo "${fname}_sha256" ;; \
						TIMESTAMP) ;; \
						*) echo "${fname}_anomaly" ;; \
					esac ; \
					;; \
			esac ; \
		done < "${file}")

		unset prevname
		unset name
		# __END__ token is necessary to detect incomplete strings
		for name in $(echo ${NAMELIST} | tr ' ' '\n' | sort) __END__; do
			# check for anomalies
			[ "${name%%_anomaly}" != "${name}" ] && \
			{
				echo "${file}: ${name%%_anomaly} ???"
				continue
			}

			if [ -z "${prevname}" ]; then
				prevname="${name}"
			else
				# check for duplicate lines
				[ "${prevname}" = "${name}" ] && \
				{
					echo ${file}: duplicate line ${name%%_s[ih][za][e2]*}
					prevname="${name}"
					continue
				}

				# after sorting $prevname always *_sha256 and $name always *_size
				[ "${prevname%%_sha256}" = "${name%%_size}" ] && \
				{
					unset prevname
					continue
				}
				[ "${prevname%%_sha256}" != "${prevname}" ] && \
					echo ${file}: missing SIZE for ${prevname%%_sha256}
				[ "${prevname%%_size}" != "${prevname}" ] && \
					echo ${file}: missing SHA256 for ${prevname%%_size}
				prevname="${name}"
			fi
		done
	done

	echo
	unset NAMELIST
	unset DISTINFOLIST

	echo BROKEN/IGNORE quoted:

	broken_ignore_re='^(BROKEN|IGNORE)[+]*=[[:space:]]*"[^"]*"'

	find "${_PORTSDIR}" -type f -mindepth 3 -maxdepth 3 -name Makefile\* -exec \
		grep -E "${broken_ignore_re}" {} \+
	echo
}

echo "misspelled(wrong) USE_* variables in Makefile:"
# USE_* arguments for various *_ARGS varibles or USE_*_DESC
whitelist="
biology/seaview/Makefile
devel/py-pyopencl/Makefile
editors/picpas/Makefile
editors/cudatext/Makefile
games/freedoko/Makefile
games/ioquake3/Makefile
graphics/lazpaint/Makefile
java/openjdk11/Makefile
java/openjdk12/Makefile
math/gotoblas/Makefile
math/openblas/Makefile
math/primme/Makefile
multimedia/mpeg2codec/Makefile
multimedia/oscam/Makefile
net/haproxy/Makefile
net/haproxy-devel/Makefile
net/haproxy17/Makefile
net/haproxy18/Makefile
net/haproxy19/Makefile
net/haproxy20/Makefile
net/haproxy21/Makefile
net/haproxy23/Makefile
net/nuster/Makefile
net-mgmt/prometheus2/Makefile
net-p2p/awgg/Makefile
www/cgiwrap/Makefile"

whitelist_var="
USE_ANT
USE_APACHE_RUN
USE_BINUTILS
USE_CABAL
USE_CSTD
USE_CXXSTD
USE_FPC
USE_GCC
USE_GECKO
USE_GITHUB
USE_GITLAB
USE_GL
USE_GNOME_SUBR
USE_GNOME
USE_GNUSTEP
USE_GSTREAMER
USE_GSTREAMER1
USE_HORDE_BUILD
USE_HORDE_RUN
USE_JAVA
USE_KDE
USE_LDCONFIG32
USE_LDCONFIG
USE_LINUX_PREFIX
USE_LINUX_RPM_BAD_PERMS
USE_LINUX_RPM
USE_LINUX
USE_LOCALE
USE_LXQT
USE_MATE
USE_MOZILLA
USE_MYSQL
USE_OCAMLFIND_PLIST
USE_OCAML_CAMLP4
USE_OCAML_FINDLIB
USE_OCAML_LDCONFIG
USE_OCAML_TK
USE_OCAML_WASH
USE_OCAML
USE_OPENLDAP
USE_PERL5
USE_PHP
USE_PYQT
USE_PYTHON
USE_QT
USE_RC_SUBR
USE_RUBY_EXTCONF
USE_RUBY_RDOC
USE_RUBY_SETUP
USE_RUBY
USE_SDL
USE_SUBMAKE
USE_TEX
USE_WX
USE_XFCE
USE_XORG"

whitelist_uservar="
USE_ASDF_FASL
USE_ASDF
USE_GENERIC_PKGMESSAGE
USE_SBCL
USE_SM_COMPAT"

# validate USE_* whitelists
for name in ${whitelist}; do
	[ -f "${_PORTSDIR}/${name}" ] || echo whitelist: ${name} doesn\'t exist
done

# cache filelist
# remove Scripts dir as optimization and bsd.sanity.mk
# as source of no longer valid vars
FILELIST=$(find "${_PORTSDIR}/Mk/" -type f | \
	grep -Ev '/Scripts|/bsd.sanity.mk')

for var in ${whitelist_var}; do
	n=$(echo ${FILELIST} | xargs grep -m1 -wl "${var}")
	[ -z "${n}" ] && echo "whitelist: ${var} not in Mk/*"
done

# cache filelist
unset FILELIST
for name in ${whitelist_usermkfile}; do
	FILELIST="${FILELIST} ${_PORTSDIR}/${name}"
done

for var in ${whitelist_uservar}; do
	n=$(echo ${FILELIST} | xargs grep -m1 -wl "${var}")
	[ -z "${n}" ] && echo "whitelist: ${var} not in ports/*"
done

# convert to grep regexp
whitelist_var="$(echo ${whitelist_var} | sed -e 's/ /|/g')"

if [ -n "${opt_skip_white}" ]; then
	whitelist=E_m_P_t_Y_s_E_t
	whitelist_uservar=E_m_P_t_Y_s_E_t
else
	# convert to grep regexp
	whitelist="$(echo ${whitelist} | sed -e 's/ /|/g')"
	whitelist_uservar="$(echo ${whitelist_uservar} | sed -e 's/ /|/g')"
fi

# look for USE_* or #USE_* at the beginning of the line
# treat ':' as a separator, sort by second field
find "${_PORTSDIR}" -mindepth 3 -maxdepth 3 -name Makefile\* -print0 | \
	xargs -0 grep '^[[:space:]#]*USE_[^=]*=' | \
	grep -vwE "${whitelist}|${whitelist_var}|${whitelist_uservar}" | \
	sort -t: -k2
echo

echo "misspelled(wrong) USES variables in Makefile:"
whitelist="
devel/f18/Makefile
devel/flang/Makefile
devel/llvm-cheri/Makefile
devel/llvm-devel/Makefile
devel/llvm60/Makefile
devel/llvm70/Makefile
devel/llvm80/Makefile
devel/llvm90/Makefile
devel/llvm10/Makefile
devel/llvm11/Makefile
multimedia/gstreamer1-plugins/Makefile.common"

whitelist_var=$(for f in "${_PORTSDIR}"/Mk/Uses/*; do f=${f%%.mk}; echo ${f##*/}; done)

# validate USES whitelists
for name in ${whitelist}; do
	[ -f "${_PORTSDIR}/${name}" ] || echo "whitelist: ${name} doesn\'t exist"
done

# convert to grep regexp
whitelist="$(echo ${whitelist} | sed -e 's/ /|/g')"
whitelist_var="$(echo ${whitelist_var} | sed -e 's/ /|/g')"

# XXX this is only partially works, because some ports have USES in multiple
# lines, more proper way to check them is to invoke make -V USES on each
# port. But it would cause huge performance penalty.
find  "${_PORTSDIR}" -mindepth 3 -maxdepth 3 -name Makefile\* -print0 | \
	xargs -0 grep "^[[:space:]#]*USES[+?]*=" | \
	grep -vwE "${whitelist}|${whitelist_var}" | \
	sort -t: -k2
echo

echo "lines after '.include <bsd.port.mk>|<bsd.port.post.mk>' in Makefile:"
# see pr59254
# typical cases: .endif or different .include <...>
whitelist="
base/binutils
databases/libgda5
devel/ORBit2
devel/aarch64-none-elf-gcc
devel/android-tools-adb
devel/android-tools-fastboot
devel/arm-none-eabi-gcc
devel/gconf2
devel/glib20
devel/glibmm
devel/gnome-vfs
devel/libbonobo
devel/libglade2
emulators/wine
emulators/wine-devel
emulators/i386-wine
emulators/i386-wine-devel
graphics/frei0r
graphics/libgnomecanvas
misc/freebsd-doc-bn
misc/freebsd-doc-ja
misc/freebsd-doc-ko
misc/freebsd-doc-zh_cn
misc/freebsd-doc-zh_tw
net/tigervnc-server
net/widentd
textproc/gtkspell
textproc/libxml2
textproc/libxml\+\+26
textproc/libxslt
x11-fonts/fontconfig
x11-toolkits/gtk20
x11-toolkits/gtkmm24
x11-toolkits/gtkmm30
x11-toolkits/gtksourceview2
x11-toolkits/gtksourceview3
x11-toolkits/libbonoboui
x11-toolkits/libgnomeui
x11-toolkits/libwnck
x11-toolkits/libwnck3
x11-toolkits/pangomm
x11-toolkits/vte
x11/libgnome"

# atypical cases, probably worth investigating
whitelist2="
cad/zcad
databases/percona-pam-for-mysql
games/xray_re-tools
graphics/libfpx
graphics/php73-gd
graphics/php74-gd
graphics/php80-gd
graphics/simpleviewer
japanese/p5-Unicode-Japanese
lang/rust-bootstrap
mail/libdkim
misc/gedkeeper
misc/seabios
multimedia/kvazaar
multimedia/libdv
net/ipxe
net-p2p/udpt
sysutils/angrysearch
sysutils/grub2-bhyve
sysutils/memtest86\+
sysutils/uefi-edk2-bhyve
textproc/hunspell
textproc/nuspell"

# valid lastlines in port Makefile
# XXX '\s' doesn't work with LANG=C
lastline_re=':.include[[:space:]]*(<bsd\.port\.mk>|<bsd\.port\.post\.mk>|\"\${MASTERDIR}|\"\${\.CURDIR}/|\"\${\.CURDIR:H:H}/)'

# validate whitelist
for name in ${whitelist} ${whitelist2}; do
	# remove meta characters
	name=$(eval echo $name)
	[ -d "${_PORTSDIR}/${name}" ] || { echo whitelist: ${name} was removed; continue; }
	tail -n1 "${_PORTSDIR}/${name}/Makefile" | \
	grep -qE "${lastline_re}" && echo "whitelist: ${name} was fixed"
done

if [ -n "${opt_skip_white}" ]; then
	whitelist=E_m_P_t_Y_s_E_t
	whitelist2=E_m_P_t_Y_s_E_t
else
	# convert to grep regexp
	whitelist="$(echo ${whitelist} | sed -e 's/ /\/|/g')"
	whitelist2="$(echo ${whitelist2} | sed -e 's/ /\/|/g')"
fi

unset file
# parse output of tail -n1: first line is '==>' ${file} '<==',
# second is the last line of Makefile and third is an empty line
# append to the end of printed line ^A so we can convert it
# output to separate lines later
FILELIST=$(while read -r line; do
	# check if $file is set in case if the last Makefile's line was ^$
	[ -z "${line}" -a -z "${file}" ] && continue
	set -- ${line}
	if [ "$1" = '==>' -a "$3" = '<==' ]; then
		file=$2
	elif [ -n ${file} ]; then
		echo "${file}:${line}"
		unset file
	fi
done << EOF
`find "${_PORTSDIR}" -mindepth 3 -maxdepth 3 -name Makefile \
	-exec tail -n1 {} \+`
EOF
)

# '^$' pattern is to remove first (empty) output line
echo ${FILELIST} | tr '' '\n' | grep -vE ${lastline_re} | \
	grep -vE "${whitelist}|${whitelist2}|^$" | sort | sed -e 's/^ //'
echo
