# pro-archman # src/pro-archman.sh # Main program file # # Copyright (C) 2013, 2019 Patrick McDermott # # This file is part of the ProteanOS Archive Manager. # # The ProteanOS Archive Manager is free software: you can redistribute # it and/or modify it under the terms of the GNU General Public License # as published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # The ProteanOS Archive Manager is distributed in the hope that it # will be useful, but WITHOUT ANY WARRANTY; without even the implied # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with the ProteanOS Archive Manager. If not, see # . set -eu # Constant global variables LF=' ' OPTSTRING='hVvb:' # Global variables in_place= builddir= loading_cmd= base_dir= conf_incoming_channel= conf_incoming_dir= conf_pool_gc_delay= conf_verbose= conf_gzip= conf_key= lock= exit_status= _get_options() { local opt= OPTIND=1 unset OPTARG while getopts "${OPTSTRING}" opt; do case "${opt}" in '?') return 1 ;; *) eval "opt_${opt}=\"\${OPTARG:-true}\"" ;; esac unset OPTARG done return 0 } main() { local cmd= if [ -f "$(dirname -- "${0}")/.builddirstamp" ]; then in_place=true builddir="$(dirname -- "${0}")" else in_place=false builddir='' fi load_locale || return 1 if ! _get_options "${@}"; then cmd_help_main 1>&2 return 1 fi shift $((${OPTIND} - 1)) base_dir="${opt_b:-.}" if ${opt_h:-false}; then cmd='help' elif ${opt_V:-false}; then cmd='version' elif [ ${#} -lt 1 ]; then cmd_help_main 1>&2 return 1 else cmd="${1}" shift 1 fi if run_cmd "${cmd}" "${@}"; then return 0 else return ${?} fi } _lock() { mkdir -p -- "${base_dir}/.db" lock="${base_dir}/.db/lock" if ! (set -C; printf '%d\n' "${$}" 1>"${lock}") 2>/dev/null; then error 2 "$(get_msg 'lock_fail')" fi } _unlock() { rm -f -- "${lock}" } _handle_sig() { local sig="${1}" shift 1 _unlock if [ "x${exit_status:+set}" = 'xset' ]; then exit ${exit_status} else exit $((128 + ${sig})) fi } _init_sigs() { local i= local sig= # We need the signal *number* in the signal handler. The only portable # and easy way to get the number of a named signal is to search for it # as in the following loop hack. i=0 while [ ${i} -lt 127 ]; do i=$((${i} + 1)) sig="$(kill -l ${i} 2>/dev/null)" || continue case "${sig}" in 'HUP' | 'INT' | 'QUIT' | 'ABRT' | 'ALRM' | 'TERM') trap "_handle_sig ${i}" ${i} ;; esac done } _get_conf() { local old_dir= # Set defaults. conf_incoming_channel='dev' conf_incoming_dir='../incoming' conf_pool_gc_delay=86400 conf_verbose=false conf_gzip=true conf_key='' eval "$(cat -- "${base_dir}/conf" 2>/dev/null || :)" old_dir="$(pwd)" cd -- "${base_dir}" if [ -d "${conf_incoming_dir}" ]; then conf_incoming_dir="$(cd -- "${conf_incoming_dir}" && pwd)" fi cd -- "${old_dir}" case "${conf_pool_gc_delay}" in *[!0-9]* | '') error 1 "$(get_msg 'conf_invalid')" 'conf_pool_gc_delay' esac case "${conf_verbose}" in 'false' | '0' | 'off' | 'no' | '') conf_verbose=false;; *) conf_verbose=true;; esac case "${conf_gzip}" in 'false' | '0' | 'off' | 'no' | '') conf_gzip=false;; *) conf_gzip=true;; esac return 0 } init() { _init_sigs _lock _get_conf } fini() { update_feeds collect_garbage _unlock }