summaryrefslogtreecommitdiffstats
path: root/src/main.sh
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.sh')
-rw-r--r--src/main.sh223
1 files changed, 223 insertions, 0 deletions
diff --git a/src/main.sh b/src/main.sh
new file mode 100644
index 0000000..e17b751
--- /dev/null
+++ b/src/main.sh
@@ -0,0 +1,223 @@
+#!@@SH@@
+#
+# pro-archman
+# src/pro-archman.sh
+# Main program file
+#
+# Copyright (C) 2013 Patrick "P. J." McDermott
+#
+# This program 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.
+#
+# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+set -u
+
+# Constant global variables
+PKGLIBDIR='@@PKGLIBDIR@@'
+PKGLIBCMDDIR='@@PKGLIBCMDDIR@@'
+PKGLIBCMD='@@PKGLIBCMD@@'
+LF='
+'
+OPTSTRING='hVvb:'
+
+# Global variables
+loading_cmd=
+base_dir=
+conf_incoming_channel=
+conf_incoming_dir=
+conf_pool_gc_delay=
+conf_verbose=
+conf_gzip=
+lock=
+exit_status=
+
+# use() must be defined inline so it can be used to load other modules.
+use()
+{
+ local module="${1}"
+ local default_dir=
+ local lib_subdir=
+ local dir=
+
+ if [ "x${module%/*}" = "x${module}" ]; then
+ default_dir="${PKGLIBDIR}"
+ lib_subdir=''
+ else
+ case "${module%/*}" in
+ 'cmd')
+ loading_cmd="$(printf '%s' "${module##*/}" | \
+ tr '[A-Z]' '[a-z]' | \
+ tr -C '[a-z0-9_]' '_')"
+ default_dir="${PKGLIBCMDDIR}"
+ lib_subdir='cmd'
+ ;;
+ esac
+ fi
+
+ if [ "${ARCHMAN_LIBDIR+set}" = 'set' ]; then
+ dir="${ARCHMAN_LIBDIR:-.}/${lib_subdir}"
+ else
+ dir="${default_dir}"
+ fi
+
+ if [ -f "${dir}/${module##*/}.sho" ]; then
+ . "${dir}/${module##*/}.sho"
+ else
+ printf '%s: Error: Failed to load module "%s": %s\n' \
+ "${0##*/}" "${module}" 'no such file or directory' >&2
+ exit 2
+ fi
+}
+
+use locale
+use cmd
+use index
+use garbage
+
+main()
+{
+ local cmd=
+ local status=
+
+ init_sigs
+ load_locale
+ load_cmds
+
+ get_options "${@}"
+ 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 >&2
+ exit 1
+ else
+ cmd="${1}"
+ shift
+ fi
+
+ run_cmd "${cmd}" "${@}"
+ status=${?}
+
+ return ${status}
+}
+
+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_options()
+{
+ local opt=
+
+ unset OPTARG
+ while getopts "${OPTSTRING}" opt; do
+ if [ "x${opt}" != 'x?' ]; then
+ eval "opt_${opt}=\"\${OPTARG:-true}\""
+ fi
+ unset OPTARG
+ done
+
+ return 0
+}
+
+init()
+{
+ lock
+ get_conf
+}
+
+lock()
+{
+ mkdir -p "${base_dir}/.db"
+ lock="${base_dir}/.db/lock"
+ if ! (set -C; printf '%d\n' "${$}" >"${lock}") 2>/dev/null; then
+ error 2 "$(get_msg 'lock_fail')"
+ fi
+}
+
+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
+
+ if [ -f "${base_dir}/conf" ]; then
+ . "${base_dir}/conf"
+ fi
+
+ 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_verbose}" in
+ 'false' | '0' | 'off' | 'no') conf_verbose=false;;
+ *) conf_verbose=true;;
+ esac
+
+ return 0
+}
+
+fini()
+{
+ update_feeds
+ collect_garbage
+ unlock
+}
+
+unlock()
+{
+ rm -f "${lock}"
+}
+
+handle_sig()
+{
+ local sig="${1}"
+
+ unlock
+
+ if [ "x${exit_status:+set}" = 'xset' ]; then
+ exit ${exit_status}
+ else
+ exit $((128 + $sig))
+ fi
+}
+
+main "${@}"