summaryrefslogtreecommitdiff
path: root/aports/uds_passthru/uds_passthru
blob: ba26b789212536979cc5b8dba0874667094b90ee (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
110
111
112
113
114
#!/bin/sh
# shellcheck disable=SC2034,SC3043,SC3060

log() {
    local _level="$1"
    local _message="$2"

    /usr/bin/logger -p "daemon.${_level}" -t "uds_passthru[$$]" "${_message}"
}

capture_output() {
    local _type="$1"
    local _id="$2"

    while read -r message; do
	log "${_type}" "[${_id}] ${message}"
    done
}

_block=
sockets=
network=

# shellcheck disable=SC1091
. /media/etc/uds_passthru.conf

log debug "Configuration: network=${network}, sockets=[${sockets}]"

if_lan=eth0

terminate() {
    local _sleep

    if [ -n "${_block}" ]; then
	log info "Received signal for termination, stopping PID ${_block}."
	/bin/kill -KILL "${_block}"
	log debug "Killed: $?"
	_sleep=$(/bin/ps -o ppid,comm,pid \
		     | /bin/grep -F "1 sleep" \
		     | /usr/bin/head -1 \
		     | /bin/sed "s@[ ]*1[ ]*sleep[ ]*@@")
	log info "Stopping the orphaned sleep as PID ${_sleep}."
	/bin/kill -KILL "${_sleep}"
	log debug "Killed: $?"
    else
	log warn "Nothing is blocked, nothing to do."
    fi
}

trap terminate TERM

find_network() {
    /sbin/ifconfig ${if_lan} \
	| /bin/grep -F "inet addr:" \
	| /bin/sed -E 's!.*inet addr:([0-9\.]+).*Mask:([0-9\.]+)!\1:\2!'
}

if [ -z "${network}" ]; then
    if ! /sbin/ifconfig ${if_lan}; then
	log error "Interface ${if_lan} not found, exiting."
	exit 1
    fi

    network=$(find_network)
fi

_ip=${network%%:*}

if [ -z "${_ip}" ]; then
    log error "No IP address for ${if_lan} could found, exiting."
    exit 1
fi

_socket_directory=$(/bin/mktemp -d)

for s in ${sockets}; do
    _path="${s##*path=}"
    _path="${_path%%,*}"

    if [ ! -S "${_path}" ]; then
	log warn "${_path} is not available, skipping."
	continue
    fi

    _socket=$(/bin/mktemp -up "${_socket_directory}")
    _port="${s##*port=}"
    _port="${_port%%,*}"

    if [ -z "${_port}" ]; then
        log warn "No port defined for ${_path}, skipping."
	continue
    fi

    log info "Associating ${_ip}:${_port} (${network}) with ${_path} (${_socket})"
    /usr/bin/socat \
	TCP4-LISTEN:"${_port}",reuseaddr,bind="${_ip}",range="${network}",fork \
	UNIX-SENDTO:"${_path}",bind="${_socket}",unlink-early 2>&1 \
	| capture_output debug socat &
done

(while /bin/true; do /bin/sleep 365d; done) &
_block=$!

log info "Waiting for PID ${_block} to stop."
wait "${_block}"

_socats=$(/usr/bin/pgrep -P $$ socat)
log info "Stopping, own socat processes: [${_socats}]"

# shellcheck disable=SC2086
[ -n "${_socats}" ] && /bin/kill -TERM ${_socats}
[ -n "${_socket_directory}" ] && /bin/rm -rf "${_socket_directory}"

log info "Finished."