summaryrefslogtreecommitdiffstats
path: root/lexd-spool.sh
blob: eea19e011bc466b6ccca07a196ef28164a3fafcf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/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"
SPOOL_DIR="/var/www/var/lex/spool/new"
DICT_DIR="/var/www/var/lex/dict"
SOCKET_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 "${SOCKET_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}"

		# Write remote dict file & remove spool file
		print -r -- "${response}" \
			| ssh -F "${SSH_CONFIG}" "${SSH_HOST}" \
			"cat > '${target_file}' && rm -f '${SPOOL_DIR}/${SPOOL_FILE}'"

		log_info "Finished processing: ${target_word}"
	)

	if [ $? -ne 0 ]; then
		log_err "Processing failed for file: ${SPOOL_FILE}"
	fi

	sleep "${SLEEP_INTERVAL}"
done