#!/usr/bin/env bash

paths=()
excludes=()
strip="strip"
break_on_error="1"

while [ $# -gt 0 ]; do
	case "${1}" in
		--strip=*)
			strip="${1#*=}"
			;;
		--exclude=*)
			if [ -n "${1#*=}" ]; then
				excludes+=( "!" "-path" "${1#*=}" "!" "-path" "${1#*=}/*" )
			fi
			;;
		--ignore-errors)
			break_on_error="0"
			;;
		*)
			paths+=( "${1}" )
			;;
	esac
	shift
done

function _strip() {
	local file="${1}"
	local args=()

	# Fetch the filetype
	local type="$(readelf -h "${file}" 2>/dev/null)"

	case "${type}" in
		# Libraries and Relocatable binaries
		*Type:*"DYN (Shared object file)"*)
			args+=( "--strip-all" )
			;;

		*Type:*"DYN (Position-Independent Executable file)"*)
			args+=( "--strip-all" )
			;;

		# Binaries
		*Type:*"EXEC (Executable file)"*)
			args+=( "--strip-all" )
			;;

		# Static libraries
		*Type:*"REL (Relocatable file)"*)
			args+=( "--strip-debug" "--remove-section=.comment" "--remove-section=.note" )
			;;

		# Skip any unrecognised files
		*)
			return 0
			;;
	esac

	# Fetch any capabilities
	local capabilities="$(getfattr --no-dereference --name="security.capability" \
		--absolute-names --dump "${file}" 2>/dev/null)"

	echo "Stripping ${file}..."
	if ! "${strip}" "${args[@]}" "${file}"; then
		return ${break_on_error}
	fi

	# Restore capabilities
	if [ -n "${capabilities}" ]; then
		setfattr --no-dereference --restore=<(echo "${capabilities}")
	fi
}

for path in ${paths[@]}; do
	for file in $(find -H "${path}" -xdev "${excludes[@]}" -type f \( -perm -0100 -or -perm -0010 -or -perm -0001 \) 2>/dev/null); do
		_strip "${file}" || exit $?
	done
done
