#!/bin/ksh # OpenBSD ksh daemon script to process remote spool files over SSH # Fall back to the running user's home if $HOME is unset USER_HOME="${HOME:-$(eval echo "~${USER}")}" SSH_CONFIG="${USER_HOME}/.ssh/config" SSH_HOST="lex-spool" TMP_DIR="/var/www/var/lex/tmp" DICT_DIR="/var/www/var/lex/dict" SPOOL_DIR="/var/www/var/lex/spool" SOCK_PATH="/var/run/lexd/sock" SLEEP_INTERVAL=30 log_err() { logger -t lexd-spool -p daemon.err "$1" } log_info() { logger -t lexd-spool -p daemon.info "$1" } while true; do # Fetch one file SPOOL_FILE=$(ssh -F "${SSH_CONFIG}" -n "${SSH_HOST}" \ "ls -1 '${SPOOL_DIR}' 2>/dev/null | head -n 1") if [ $? -ne 0 ]; then log_err "Failed connection attempt to ${SSH_HOST}" sleep "${SLEEP_INTERVAL}" continue fi # If spool is empty, wait and retry if [ -z "${SPOOL_FILE}" ]; then sleep "${SLEEP_INTERVAL}" continue fi ( set -e # Fetch remote spool file content raw_prompt=$(ssh -F "${SSH_CONFIG}" -n "${SSH_HOST}" \ "cat '${SPOOL_DIR}/${SPOOL_FILE}'") if [ -z "${raw_prompt}" ]; then log_err "Empty spool file: ${SPOOL_FILE}" exit 1 fi # Log truncated input string (up to 45 characters) trunc_prompt=$(print -r -- "${raw_prompt}" | cut -c1-45) log_info "Processing: \"${trunc_prompt}\"" # Pass prompt to socket and insert missing empty lines before uppercase headers response=$(print -r -- "${raw_prompt}" | nc -w 300 -U "${SOCK_PATH}" | awk ' /^[A-Z ]+:[[:space:]]*$/ { if (NR > 1 && last != "") { print "" } } { print $0 last = $0 } ') if [ -z "${response}" ]; then log_err "Empty socket response for: ${SPOOL_FILE}" exit 1 fi # Extract first word (lowercased) target_word=$(print -r -- "${response}" \ | awk '{print tolower($1); exit}') if [ -z "${target_word}" ]; then log_err "No target filename for: ${SPOOL_FILE}" exit 1 fi # Validate target word case "${target_word}" in *[!a-z-]*) log_err "Invalid word '${target_word}': ${SPOOL_FILE}" exit 1 ;; [!a-z]*|*[!a-z]) log_err "Bad bounds '${target_word}': ${SPOOL_FILE}" exit 1 ;; esac target_file="${DICT_DIR}/${target_word}" tmp_file="${TMP_DIR}/${target_word}" remote_cmd="cat > '${tmp_file}' &&" remote_cmd="${remote_cmd} mv -f '${tmp_file}'" remote_cmd="${remote_cmd} '${target_file}' &&" remote_cmd="${remote_cmd} rm -f" remote_cmd="${remote_cmd} '${SPOOL_DIR}/${SPOOL_FILE}'" print -r -- "${response}" \ | ssh -F "${SSH_CONFIG}" "${SSH_HOST}" "${remote_cmd}" log_info "Finished processing: ${target_word}" ) if [ $? -ne 0 ]; then log_err "Processing failed for file: ${SPOOL_FILE}" fi sleep "${SLEEP_INTERVAL}" done