#!/bin/sh

set -o errexit

VERSION='1.1'

ELF_CODE=' 7f 45 4c 46'
STATIC_LINUX_CODE=' 21 3c 61 72'

print_version()
{
    echo "${VERSION}"
    exit 0
}

print_help()
{
    echo "\
Usage:
binfiles [-n] [-d|-s] [-l] [--] FILELIST
binfiles --help | --version

Print list of files, considered as binary executables or libraries.
"
    exit 0
}

error()
{
    echo "Error:" 1>&2
    echo "$@" 1>&2
    exit 1
}

extract_dir()
{
    dir="$1"

    find $dir -type f -o -type l || true
}

ignore_dir()
{
    return
}

exec_checker()
{
    arg="$1"

    binary_code="$(od -A none -t x1 -N4 "${arg}")" || true

    case "${binary_code}" in
        "${dynamic_CODE}"|"${static_CODE}")
            printf "%s\n" "${arg}"
        ;;
    esac
}

main_fileonly_filter()
{
    while read file_to_check <&0 ; do
        if test ! -e "${file_to_check}" ; then
            continue
        fi
        if test -L "${file_to_check}" -a -z "${use_LINKS}" ; then
            continue
        fi
        if test -f "${file_to_check}" ; then
            exec_checker "${file_to_check}"
        fi
    done
}

main_dir_filter()
{
    while read file_to_check <&0 ; do
        if test ! -e "${file_to_check}" ; then
            continue
        fi
        if test -d "${file_to_check}" ; then
            ${method_handle_dirs} "${file_to_check}" | main_fileonly_filter
            continue
        fi
        if test -f "${file_to_check}" ; then
            exec_checker "${file_to_check}"
        fi
    done
}

in_arg_cycle=1
method_handle_dirs='extract_dir'
static_CODE="${STATIC_LINUX_CODE}"
dynamic_CODE="${ELF_CODE}"
use_LINKS=

while [ -n "$in_arg_cycle" ] ; do
    arg="$1"
    in_arg_cycle=

    checked_arg="${arg#-}" || true
    if [ "$checked_arg" != "${arg}" ] ; then
        in_arg_cycle=1
        shift

        case ${checked_arg} in
            n)
                method_handle_dirs='ignore_dir'
            ;;
            d)
                static_CODE="NONE"
                dynamic_CODE="${ELF_CODE}"
            ;;
            s)
                dynamic_CODE="NONE"
                static_CODE="${STATIC_LINUX_CODE}"
            ;;
            l)
                use_LINKS="yes"
            ;;
            -version)
                print_version
            ;;
            -help)
                print_help
            ;;
            -)
                in_arg_cycle=
            ;;
            *)
                error "Unknown option ${arg}"
            ;;
        esac
    fi
done

for file_to_check ; do
    printf "%s\n" "${file_to_check}" | main_dir_filter
done

if [ ! -t 0 ] ; then
    while read file_to_check <&0 ; do
        printf "%s\n" "${file_to_check}" | main_dir_filter
    done
fi


# ---------------------------------------------------------

# Copyright (c) 2017 Random Crew.
#
# Available under ISC License.

# ---------------------------------------------------------

