#!/usr/bin/bash

export LC_ALL=C

conf=/etc/patchman/patchman-client.conf
protocol=1
verbose=false
debug=false
report=false
local_updates=false
repo_check=true
tags=''

usage() {
    echo "${0} [-v] [-d] [-n] [-u] [-r] [-s SERVER] [-c FILE] [-t TAGS] [-h HOSTNAME]"
    echo "-v: verbose output (default is silent)"
    echo "-d: debug output"
    echo "-n: no repo check (required when used as an apt or yum plugin)"
    echo "-u: find updates locally (e.g. for RHEL)"
    echo "-r: request a report from the server (default is no report)"
    echo "-s SERVER: web server address, e.g. https://patchman.example.com"
    echo "-c FILE: config file location (default is /etc/patchman/patchman-client.conf)"
    echo "-t TAGS: comma-separated list of tags, e.g. -t www,dev"
    echo "-h HOSTNAME: specify the hostname of the local host"
    echo
    echo "Command line options override config file options."
    exit 0
}

parseopts() {
    while getopts "vdnurs:c:t:h:" opt; do
        case ${opt} in
        v)
            verbose=true
            ;;
        d)
            debug=true
            verbose=true
            ;;
        n)
            repo_check=false
            ;;
        u)
            local_updates=true
            ;;
        r)
            cli_report=true
            ;;
        s)
            cli_server=${OPTARG}
            ;;
        c)
            cli_conf=${OPTARG}
            ;;
        t)
            cli_tags="${OPTARG}"
            ;;
        h)
            cli_hostname=${OPTARG}
            ;;
        *)
            usage
            ;;
        esac
    done
}

cleanup() {
    if ${verbose} && ${debug} ; then
        echo "Debug: not deleting ${tmpfile_pkg} (packages)"
        echo "Debug: not deleting ${tmpfile_rep} (repos)"
        echo "Debug: not deleting ${tmpfile_sec} (security updates)"
        echo "Debug: not deleting ${tmpfile_bug} (updates)"
        echo "Debug: not deleting ${tmpfile_mod} (modules)"
    elif ${verbose} && ! ${debug} ; then
        echo "Deleting ${tmpfile_pkg}"
        echo "Deleting ${tmpfile_rep}"
        echo "Deleting ${tmpfile_sec}"
        echo "Deleting ${tmpfile_bug}"
        echo "Deleting ${tmpfile_mod}"
    fi
    if ! ${debug} ; then
        rm -fr "${tmpfile_pkg}"
        rm -fr "${tmpfile_rep}"
        rm -fr "${tmpfile_sec}"
        rm -fr "${tmpfile_bug}"
        rm -fr "${tmpfile_mod}"
    fi
    flock -u 200
    rm -fr "${lock_dir}/patchman.lock"
}

check_conf() {
    if [ ! -z "${cli_conf}" ] ; then
        conf=${cli_conf}
    fi

    if [ -z "${conf}" ] || [ ! -f "${conf}" ] ; then
        if ${verbose} ; then
            echo "Warning: config file '${conf}' not found."
        fi
    else
        source "${conf}"
    fi

    conf_dir=$(dirname "${conf}")/conf.d
    if [ -d "${conf_dir}" ] ; then
        let f=$(find "${conf_dir}" -maxdepth 1 -type f | wc -l)
        if [ ${f} -gt 0 ] ; then
            source "${conf_dir}"/*
        fi
    fi

    if [ -z "${server}" ] && [ -z "${cli_server}" ] ; then
        echo 'Patchman server not set, exiting.'
        exit 1
    else
        if [ ! -z "${cli_server}" ] ; then
            server=${cli_server}
        fi
    fi

    if [ ! -z "${cli_report}" ] ; then
        report=${cli_report}
    fi

    if [ ! -z "${cli_tags}" ] ; then
        tags="${cli_tags}"
    fi

    if [ -z "${hostname}" ] && [ -z "${cli_hostname}" ] ; then
        get_hostname
    else
        if [ ! -z "${cli_hostname}" ] ; then
            hostname=${cli_hostname}
        fi
    fi

    check_booleans

    if ${verbose} ; then
        echo "Patchman configuration seems OK:"
        if [ -f ${conf} ] ; then
            echo "Using configuration file: ${conf}"
        fi
        echo "Patchman Server: ${server}"
        echo "Hostname: ${hostname}"
        echo "Tags: ${tags}"
        for var in report local_updates repo_check verbose debug ; do
            eval val=\$${var}
            echo "${var}: ${val}"
        done
    fi
}

check_booleans() {
    for var in report local_updates repo_check verbose debug ; do
        eval val=\$${var}
        if [ -z ${val} ] || [ "${val}" == "0" ] || [ "${val,,}" == "false" ] ; then
            eval ${var}=false
        elif [ "${val}" == "1" ] || [ "${val,,}" == "true" ] ; then
            eval ${var}=true
        fi
    done
}

check_command_exists() {
    cmd=$(/usr/bin/which ${1} 2>/dev/null)
    if [ ! -z "${cmd}" ] && [ -x "${cmd}" ] ; then
        return 0
    else
        return 1
    fi
}

check_for_modularity() {
    modularity=false
    if check_command_exists yum ; then
        if ${verbose} ; then
            echo 'Checking for modularity...'
        fi
        if yum module 2>&1 | grep -q 'No such command' ; then
            modularity=false
        else
            modularity=true
        fi
    fi
}

get_enabled_modules() {
    if ${verbose} ; then
        echo 'Finding enabled yum modules...'
    fi
    enabled_modules=$(yum module list --enabled \
        | grep "\[e\]" \
        | grep -v ^Hint \
        | awk {'print $1'})

    OLDIFS=${IFS}
    IFS="
"
    for module in ${enabled_modules} ; do
        IFS=${OLDIFS}
        module_info=$(yum module info ${module})
        module_arch=$(echo ${module_info} | grep Architecture | cut -d : -f 2 | awk '{$1=$1};1')
        module_repo=$(echo ${module_info} | grep Repo | cut -d : -f 2 | awk '{$1=$1};1')
        module_stream=$(echo ${module_info} | grep Stream | cut -d : -f 2 | sed -e 's/ \[.*//g' | awk '{$1=$1};1')
        module_version=$(echo ${module_info} | grep Version | cut -d : -f 2 | awk '{$1=$1};1')
        module_context=$(echo ${module_info} | grep Context | cut -d : -f 2 | awk '{$1=$1};1')
        module_packages=$(echo $module_info} | sed -n '/Artifacts/,$p' | grep -v Hint | sed -e 's/.* : //g' | grep -v ^$)
        OLDIFS=${IFS}
        IFS="
"
        for package in ${module_packages} ; do
            module_package_str="${module_package_str} '${package}'"
        done
        IFS=${OLDIFS}
        echo "'${module}' '${module_stream}' '${module_version}' '${module_context}' '${module_arch}' '${module_repo}' ${module_package_str}" >> ${tmpfile_mod}
    done
    if [ ! -z ${CPE_NAME} ] ; then
        sed -i -e "s#${module_repo}#${CPE_NAME}-${module_repo}#g" "${tmpfile_mod}"
    fi
    if ${debug} ; then
        cat "${tmpfile_mod}"
    fi
}

get_installed_rpm_packages() {
    if check_command_exists rpm ; then
        if ${verbose} ; then
            echo 'Finding installed rpms...'
        fi

        rpm -qa --queryformat "'%{NAME}' '%{EPOCH}' '%{version}' '%{RELEASE}' '%{ARCH}' 'rpm'\n" 2>/dev/null \
        | sed -e 's/(none)//g' \
        | sed -e 's/\+/%2b/g' >> "${tmpfile_pkg}"

        if ${debug} ; then
            cat "${tmpfile_pkg}"
        fi
    fi
}

get_installed_deb_packages() {
    if check_command_exists dpkg-query ; then
        if ${verbose} ; then
            echo 'Finding installed debs...'
        fi
        dpkg-query -W --showformat='${Status}|${Package}|${Version}|${Architecture}\n' |
            awk -f <(cat <<'AWK'
                /^(install|hold) ok installed\|/ {
                    split($0, parts, "|");
                    package = parts[2];
                    version = parts[3];
                    architecture = parts[4];
                    epoch = "";
                    release = "";

                    if (split(version, epoch_t, ":") > 1) {
                        epoch = epoch_t[1];
                        version = substr(version, length(epoch) + 2);
                    }
                    n = split(version, version_t, "-");
                    if (n > 1) {
                        release = version_t[n]
                        version = substr(version, 1, length(version) - length(release) - 1);
                    }

                    print "'" package "'", "'" epoch "'", "'" version "'", "'" release "'", "'" architecture "'", "'deb'"
                }
AWK
            ) >> "${tmpfile_pkg}"
        if ${debug} ; then
            echo "'name' 'epoch' 'version' 'release' 'arch' 'type'"
            cat "${tmpfile_pkg}"
        fi
    fi
    IFS=${OLDIFS}
}

get_installed_archlinux_packages() {
    if check_command_exists pacman ; then
        OLDIFS=${IFS}
        IFS="
"
        pacman -Q -i | awk -v q="'" -v s=" " '/^Name/{n=$3} /^Version/{l=split($3, e, ":"); if (l==2) {ep=e[1]; v=e[2]} else {ep=""; v=$3}; split(v, r, "-")} /^Architecture/{a=$3} /^$/{print q n q s q ep q s q r[1] q s q r[2] q s q a q s q"arch"q}' >> "${tmpfile_pkg}"
        IFS=${OLDIFS}
    fi
}

get_packages() {
    get_installed_rpm_packages
    get_installed_deb_packages
    get_installed_archlinux_packages
}

get_modules() {
    check_for_modularity
    if ${modularity} ; then
        get_enabled_modules
    fi
}

get_hostname() {
    hostname=$(hostname -f)
    if [ -z "${hostname}" ] ; then
        short_hostname=$(hostname)
        if [ -z "${short_hostname}" ] ; then
            short_hostname=$(cat /etc/hostname)
        fi
        domainname=$(dnsdomainname)
        if [ ! -z "${domainname}" ] ; then
            hostname=${short_hostname}.${domainname}
        else
            hostname=${short_hostname}
        fi
    fi
}

get_host_data() {
    host_kernel=$(uname -r | sed -e 's/\+/%2b/g')
    host_arch=$(uname -m)
    os='unknown'
    if [ -f /etc/os-release ] ; then
        . /etc/os-release
        if [ "${ID}" == "debian" ] ; then
            os="Debian $(cat /etc/debian_version | sed -e 's/\//-/')"
        elif [ "${ID}" == "raspbian" ] ; then
            os="Raspbian $(cat /etc/debian_version)"
        elif [ "${ID}" == "ubuntu" ] ; then
            os="${PRETTY_NAME}"
        elif [ "${ID}" == "centos" ] ; then
            os="$(cat /etc/centos-release)"
        elif [ "${ID}" == "rhel" ] ; then
            os="$(cat /etc/redhat-release)"
        elif [ "${ID}" == "fedora" ] ; then
            os="${PRETTY_NAME}"
        elif [ "${ID}" == "arch" ] ; then
            os="${NAME}"
        elif [[ "${ID}" =~ "suse" ]] ; then
            os="${PRETTY_NAME}"
        else
            os="${NAME} ${VERSION}"
        fi
    else
        releases="/etc/SuSE-release /etc/lsb-release /etc/debian_version /etc/fermi-release /etc/redhat-release /etc/fedora-release /etc/centos-release"
        for i in ${releases} ; do
            if [ -f ${i} ] ; then
                case "${i}" in
                /etc/SuSE-release)
                    os=$(grep -i suse ${i})
                    break
                    ;;
                /etc/lsb-release)
                    tmp_os=$(grep DISTRIB_DESCRIPTION ${i})
                    os=$(echo ${tmp_os} | sed -e 's/DISTRIB_DESCRIPTION="\(.*\)"/\1/')
                    if [ -z "${os}" ] ; then
                        tmp_os=$(grep  DISTRIB_DESC ${i})
                        os=$(echo ${tmp_os} | sed -e 's/DISTRIB_DESC="\(.*\)"/\1/')
                    fi
                    if [ -z "${os}" ] ; then
                        continue
                    fi
                    break
                    ;;
                /etc/debian_version)
                    os="Debian $(cat ${i})"
                    break
                    ;;
                /etc/fermi-release|/etc/redhat-release|/etc/fedora-release|/etc/centos-release)
                    os=$(cat ${i})
                    break
                    ;;
                esac
            fi
        done
    fi
    if ${verbose} ; then
        echo "Kernel:   ${host_kernel}"
        echo "Arch:     ${host_arch}"
        echo "OS:       ${os}"
    fi
}

get_yum_updates() {
    yum -q makecache 2>/dev/null
    let yum_major_version=$(yum --version | head -n 1 | cut -d "." -f 1)
    if [ ${yum_major_version} -gt 3 ] ; then
        yum -q -C --security list updates --disablerepo="*" --enablerepo="${1}" 2>&1 \
        | tr "\n" "#" | sed -e 's/# / /g' | tr "#" "\n" \
        | grep -v ': ' \
        | grep -v 'Limiting package lists to security relevant ones' \
        | grep -v 'Available Upgrades' \
        | grep -v 'Updated Packages' \
        | grep -v 'excluded' \
        | grep -v 'Last metadata expiration check' \
        | grep -v 'needed for security' \
        | grep -v 'Loaded plugins' \
        | grep -v 'Subscription Management' \
        | grep -v 'Failed to set locale' \
        >> "${tmpfile_sec}"
        sed -i '/^$/d' "${tmpfile_sec}"
    fi
    yum -q -C list updates --disablerepo="*" --enablerepo="${1}" 2>&1 \
    | tr "\n" "#" | sed -e 's/# / /g' | tr "#" "\n" \
    | grep -v ': ' \
    | grep -v 'Available Upgrades' \
    | grep -v 'Updated Packages' \
    | grep -v 'excluded' \
    | grep -v 'Last metadata expiration check' \
    | grep -v 'needed for security' \
    | grep -v 'Loaded plugins' \
    | grep -v 'Subscription Management' \
    | grep -v 'Failed to set locale' \
    >> "${tmpfile_bug}"
    sed -i '/^$/d' "${tmpfile_bug}"
    if [ ! -z ${CPE_NAME} ] ; then
        sed -i -e "s#${1}#${CPE_NAME}-${1}#g" "${tmpfile_sec}"
        sed -i -e "s#${1}#${CPE_NAME}-${1}#g" "${tmpfile_bug}"
    fi
}

get_zypper_updates() {
    zypper -q -n ref
    # can't differentiate between security and bugfix updates yet
    zypper -q -n -s11 lu -r ${1} | grep ^v | awk '{print $2"."$5,$4}' | sed -e "s/$/ ${1}/" >> "${tmpfile_bug}"
}

get_repos() {
    OLDIFS=${IFS}
    IFS="
"

    # Red Hat / CentOS
    if check_command_exists yum ; then
        if ${verbose} ; then
            echo 'Finding yum repos...'
        fi
        releasever=$(rpm -q --qf "%{version}\n" --whatprovides redhat-release | sort -u)
        let numrepos=$(ls /etc/yum.repos.d/*.repo | wc -l)
        if [ ${numrepos} -gt 0 ] ; then
            priorities=$(sed -n -e "/^name/h; /priority *=/{ G; s/\n/ /; s/ity *= *\(.*\)/ity=\1/ ; s/\$releasever/${releasever}/ ; s/name *= *\(.*\)/'\1 ${host_arch}'/ ; p }" /etc/yum.repos.d/*.repo)
        fi
        # replace this with a dedicated awk or simple python script?
        yum_repolist=$(yum repolist enabled --verbose 2>/dev/null | sed -e "s/:\? *([0-9]\+ more)$//g" -e "s/ ([0-9]\+$//g" -e "s/:\? more)$//g" -e "s/'//g" -e "s/%/%%/g")
        for i in $(echo "${yum_repolist}" | awk '{ if ($1=="Repo-id") {printf "'"'"'"; for (i=3; i<NF; i++) printf $i " "; printf $NF"'"'"' "} if ($1=="Repo-name") {printf "'"'"'"; for (i=3; i<NF; i++) printf $i " "; printf $NF"'" ${host_arch}'"' "} if ($1=="Repo-mirrors" || $1=="Repo-metalink:") {printf "'"'"'"; for (i=3; i<NF; i++) printf $i " "; printf $NF"'"'"' "} if ($1=="Repo-baseurl" || $1=="Repo-baseurl:") { url=1; comma=match($NF,","); if (comma) out=substr($NF,1,comma-1); else out=$NF; printf "'"'"'"out"'"'"' "; } else { if (url==1) { if ($1==":") { comma=match($NF,","); if (comma) out=substr($NF,1,comma-1); else out=$NF; printf "'"'"'"out"'"'"' "; } else {url=0; print "";} } } }' | sed -e "s/\/'/'/g" | sed -e "s/ ' /' /") ; do
            full_id=$(echo ${i} | cut -d \' -f 2)
            id=$(echo ${i} | cut -d \' -f 2 | cut -d \/ -f 1)
            name=$(echo ${i} | cut -d \' -f 4)
            if [ "${priorities}" != "" ] ; then
                priority=$(echo "${priorities}" | grep "'${name}'" | sed -e "s/priority=\(.*\) '${name}'/\1/")
            fi
            # default yum priority is 99
            if [ "${priority}" == "" ] ; then
                priority=99
            fi
            redhat_repo=$(echo ${i} | grep -e "https://.*/XMLRPC.*\|https://cdn.redhat.com/.*")
            if [ ${?} == 0 ] || ${local_updates} ; then
                if ${verbose} ; then
                    echo "Finding updates locally for ${id}"
                fi
                get_yum_updates ${id}
            fi
            if [ ! -z ${CPE_NAME} ] ; then
                id="${CPE_NAME}-${id}"
            fi
            j=$(echo ${i} | sed -e "s#'${full_id}' '${name}'#'${name}' '${id}' '${priority}'#")
            echo "'rpm' ${j}" >> "${tmpfile_rep}"
            unset priority
        done
    fi

    # Debian
    if check_command_exists apt-cache ; then
        if ${verbose} ; then
            echo 'Finding apt repos...'
        fi
        IFS=${OLDIFS} read -r osname shortversion <<<$(echo "${os}" | awk '{print $1,$2}' | cut -d . -f 1,2)
        repo_string="'deb\' \'${osname} ${shortversion} ${host_arch} repo at"
        repos=$(apt-cache policy | grep -v Translation | grep -E "^ *[0-9]{1,5}" | grep -E " mirror\+file|http(s)?:" | sed -e "s/^ *//g" -e "s/ *$//g" | cut -d " " -f 1,2,3,4)
        non_mirror_repos=$(echo "${repos}" | grep -Ev "mirror\+file")
        dist_repos=$(echo "${non_mirror_repos}" | grep -v -e "Packages$")
        nondist_repos=$(echo "${non_mirror_repos}" | grep -e "Packages$")
        mirror_repos=$(echo "${repos}" | grep -E "mirror\+file")
        for mirror_repo in ${mirror_repos} ; do
            mirror_file=$(echo "${mirror_repo}" | sed -e "s/.* mirror+file://g" | cut -d " " -f 1)
            if [ -f "${mirror_file}" ] ; then
                for url in $(cat ${mirror_file}) ; do
                    dist_repo=$(echo "${mirror_repo}" | sed -e "s#mirror+file:${mirror_file}#${url}#g")
                    dist_repos="${dist_repos}"$'\n'"${dist_repo}"
                done
            fi
        done
        echo "${dist_repos}" | sed -e "s/\([0-9]*\) \(http:.*\|https:.*\)[\/]\? \(.*\/.*\) \(.*\)/${repo_string} \2\/dists\/\3\/binary-\4' '\1' '\2\/dists\/\3\/binary-\4'/" >> "${tmpfile_rep}"
        echo "${nondist_repos}" | sed -e "s/\([0-9]*\) \(http:.*\|https:.*\)[\/]\? \(.*\/\?.*\) Packages/${repo_string} \2\/\3' '\1' '\2\/\3'/" >> "${tmpfile_rep}"
    fi

    # SUSE
    if check_command_exists zypper ; then
        if ${verbose} ; then
            echo 'Finding zypper repos...'
        fi
        for i in $(zypper -q --no-refresh lr -E -u --details | grep -v ^$ | tail -n +3 | cut -d "|" -f 2,3,7,9 | sed -e "s/ *|/ ${host_arch} |/" -e "s/\?[a-zA-Z0-9_-]* *$//" -e "s/^ /'/g" -e "s/ *| */' '/g" -e "s/ *$/'/g") ; do
            echo \'rpm\' ${i} >> "${tmpfile_rep}"
            id=$(echo ${i} | cut -d \' -f 4)
            suse_repo=$(echo ${i} | grep -e "https://updates.suse.com/.*")
            if [ ${?} == 0 ] || ${local_updates} ; then
                if ${verbose} ; then
                    echo "Finding updates locally for ${id}"
                fi
                get_zypper_updates ${id}
            fi
        done
    fi

    # Arch
    if check_command_exists pacman ; then
        if ${verbose} ; then
            echo 'Finding pacman repos...'
        fi
        declare -A repos
        pacman_conf=$(awk '/\[/{prefix=$0; next} $1{print prefix $0}' /etc/pacman.conf | grep -v '\[options\]' | grep '^\[')
        for stanza in ${pacman_conf} ; do
            repo=$(echo ${stanza} | cut -d ']' -f 1 | sed -e 's/\[//')
            rhs=$(echo ${stanza} | cut -d ']' -f 2 | grep -v '^#')
            if [[ ${rhs} =~ "Include" ]] ; then
                include=$(echo ${rhs} | sed -e 's/^ *Include *= *//')
                for f in $(ls ${include} 2>/dev/null) ; do
                    if [ -f ${f} ] ; then
                        servers=$(cat ${f} | grep Server | sed -e 's/^ *Server *= *//')
                        for s in ${servers} ; do
                            repos[${repo}]+="'$(eval echo ${s})' "
                        done
                    fi
                done
            elif [[ ${rhs} =~ "Server" ]] ; then
                s=$(echo ${rhs} | sed -e 's/^ *Server *= *//')
                repos[${repo}]+="'$(eval echo ${s})' "
            fi
        done
        for r in "${!repos[@]}"; do
            echo "'arch' 'Arch Linux ${r} ${host_arch}' '${r}' ${repos[${r}]}" >> "${tmpfile_rep}"
        done
    fi

    IFS=${OLDIFS}

    sed -i -e '/^$/d' "${tmpfile_rep}"

    if ${debug} ; then
        cat "${tmpfile_rep}"
    fi
}

reboot_required() {
    # On debian-based clients, the update-notifier-common
    # package needs to be installed for this to work.
    if [ -e /var/run/reboot-required ] ; then
        reboot=True
    else
        reboot=ServerCheck
    fi
}

post_data() {
    curl_opts=${curl_options}

    if ${verbose} ; then
        curl_opts="${curl_opts} -i"
        echo "Sending data to ${server} with curl:"
    else
        curl_opts="${curl_opts} -s -S";
    fi

    if [ -z "${tags}" ] ; then
        tags='Default'
    fi

    sed -i -e 's/%2b/\+/g' "${tmpfile_pkg}"

    curl_opts="${curl_opts} -F host=\"${hostname}\""
    curl_opts="${curl_opts} -F tags=\"${tags}\""
    curl_opts="${curl_opts} -F kernel=\"${host_kernel}\""
    curl_opts="${curl_opts} -F arch=\"${host_arch}\""
    curl_opts="${curl_opts} -F protocol=\"${protocol}\""
    curl_opts="${curl_opts} -F os=\"${os}\""
    curl_opts="${curl_opts} -F report=\"${report}\""
    curl_opts="${curl_opts} -F packages=\<${tmpfile_pkg}"
    curl_opts="${curl_opts} -F repos=\<${tmpfile_rep}"
    curl_opts="${curl_opts} -F sec_updates=\<${tmpfile_sec}"
    curl_opts="${curl_opts} -F bug_updates=\<${tmpfile_bug}"
    curl_opts="${curl_opts} -F modules=\<${tmpfile_mod}"
    curl_opts="${curl_opts} -F reboot=\"${reboot}\""
    post_command="curl ${curl_opts} ${server%/}/reports/upload/"

    if ${verbose} ; then
        echo "${post_command}"
    fi

    result=$(eval ${post_command})
    retval=${?}

    if [ ! ${retval} -eq 0 ] ; then
        echo 'Failed to upload report.'
        exit ${retval}
    fi

    if ${report} || ${verbose} ; then
        if [ ! -z "${result}" ] ; then
            echo "${result}"
        else
            echo "No output returned."
        fi
    fi
}

if ! check_command_exists which || \
   ! check_command_exists mktemp || \
   ! check_command_exists curl || \
   ! check_command_exists flock ; then
    echo "which, mktemp, flock or curl was not found, exiting."
    exit 1
fi

os_lock_dir=/var/lock
lock_dir=$(dirname $(readlink -f ${os_lock_dir}))/patchman
mkdir -p "${lock_dir}"
if [ ! -d "${lock_dir}" ] ; then
    echo "Lock directory does not exist, exiting: ${lock_dir}"
    exit 1
fi

parseopts "$@"

if ${verbose} ; then
    echo "Attempting to obtain lock: ${lock_dir}/patchman.lock"
fi

exec 200>"${lock_dir}/patchman.lock"
flock -xn 200 || exit 1

check_conf

trap cleanup EXIT
tmpfile_pkg=$(mktemp)
tmpfile_rep=$(mktemp)
tmpfile_sec=$(mktemp)
tmpfile_bug=$(mktemp)
tmpfile_mod=$(mktemp)

get_host_data
get_packages
get_modules
if ${repo_check} ; then
    get_repos
fi
reboot_required
post_data
