Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 26cf848

Browse files
committedApr 25, 2024
etc: Add iptsd-foreach script
This script is used to run commands on any number of IPTS devices. The user-facing scripts will be reimplemented using this.
1 parent 871bc4f commit 26cf848

File tree

3 files changed

+182
-0
lines changed

3 files changed

+182
-0
lines changed
 

‎etc/meson.build

+6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ install_data(
1010
install_mode: 'rwxr-xr-x',
1111
)
1212

13+
install_data(
14+
'scripts/iptsd-foreach',
15+
install_dir: bindir,
16+
install_mode: 'rwxr-xr-x',
17+
)
18+
1319
conf = configuration_data()
1420
conf.set('bindir', bindir)
1521
conf.set('datadir', datadir)

‎etc/scripts/iptsd-foreach

+175
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
#!/bin/bash
2+
# SPDX-License-Identifier: GPL-2.0-or-later
3+
4+
function spdlog() {
5+
local level="${1}" messages=("${@:2}")
6+
7+
case "${level}" in
8+
info)
9+
level="$(printf "%s%s%s" "\033[32m" "info" "\e[0m")"
10+
;;
11+
warn)
12+
level="$(printf "%s%s%s" "\033[33m\033[1m" "warning" "\e[0m")"
13+
;;
14+
error)
15+
level="$(printf "%s%s%s" "\033[31m\033[1m" "error" "\e[0m")"
16+
;;
17+
esac
18+
19+
echo -e "[$(date '+%H:%M:%S.%3N')] [${level}]" "${messages[@]}" >&2
20+
}
21+
22+
function print-if-executable() {
23+
local file="${1}"
24+
25+
if [ -x "${file}" ]; then
26+
echo "${file}"
27+
return 0
28+
fi
29+
30+
return 1
31+
}
32+
33+
function find-program() {
34+
local name="${1}" script_dir="${2}" project_dir="${3:-}"
35+
36+
# If the calling script is installed to /usr, the program should be right next to it
37+
if print-if-executable "${script_dir}/${name}"; then
38+
return 0
39+
fi
40+
41+
# Otherwise the script might be called from the cloned git repository
42+
if [ -n "${project_dir}" ] && [ -f "${project_dir}/meson_options.txt" ]; then
43+
local -r file="$(find "${project_dir}" -type f -executable -name "${name}" | head -n1)"
44+
45+
if print-if-executable "${file}"; then
46+
spdlog info "Located ${name} at ./$(realpath --relative-to="${PWD}" "${file}")"
47+
return 0
48+
fi
49+
fi
50+
51+
# Fall back to looking in PATH
52+
if print-if-executable "$(command -v "${name}" || true)"; then
53+
spdlog warn "Located ${name} using PATH"
54+
spdlog warn "This script is designed to not use PATH, something might be wrong"
55+
return 0
56+
fi
57+
58+
return 1
59+
}
60+
61+
function run-iptsd-foreach() {
62+
local -r script_dir="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"
63+
local -r project_dir="$(realpath "${script_dir}/../..")"
64+
65+
local device_index=""
66+
local device_type="any"
67+
local xargs_procs="1"
68+
local tmux_socket=""
69+
local show_help=""
70+
71+
while getopts ":t:i:pmh" args; do
72+
case "${args}" in
73+
i)
74+
device_index="${OPTARG}"
75+
;;
76+
t)
77+
device_type="${OPTARG}"
78+
;;
79+
p)
80+
xargs_procs="0"
81+
;;
82+
m)
83+
xargs_procs="0"
84+
tmux_socket="$(mktemp -u)"
85+
;;
86+
*)
87+
show_help="1"
88+
;;
89+
esac
90+
done
91+
92+
shift $((OPTIND - 1))
93+
94+
if [ -n "${show_help}" ]; then
95+
echo "Usage: iptsd-foreach [OPTIONS] -- COMMAND"
96+
echo "Run commands on one or many IPTS devices"
97+
echo ""
98+
echo "Options:"
99+
echo " -h Print this help message and exit"
100+
echo " -t TEXT:{any,touchscreen,touchpad} Selects all devices with the given type"
101+
echo " -i INTEGER Selects a single device by its index"
102+
echo " -p Run all commands in parallel"
103+
echo " -m Like -p, but runs every instance in seperate tmux windows"
104+
105+
return 0
106+
fi
107+
108+
if [ -n "${tmux_socket}" ] && [ ! -x "$(command -v tmux)" ]; then
109+
spdlog error "tmux is not installed"
110+
return 1
111+
fi
112+
113+
local -r check_device="$(find-program "iptsd-check-device" "${script_dir}" "${project_dir}")"
114+
115+
if [ -z "${check_device}" ]; then
116+
spdlog error "Could not locate iptsd-check-device"
117+
return 1
118+
fi
119+
120+
local devices=()
121+
122+
while read -rd $'\n' device; do
123+
if [ ! -r "${device}" ]; then
124+
spdlog warn "Can't read from ${device}, is the program running as root?"
125+
continue
126+
fi
127+
128+
if ! "${check_device}" --quiet --type="${device_type}" "${device}"; then
129+
continue
130+
fi
131+
132+
devices+=("${device}")
133+
done <<<"$(find "/dev" -maxdepth 1 | grep -E "hidraw[0-9]+" | sort)"
134+
135+
# If no devices were found, exit
136+
if (("${#devices[@]}" == 0)); then
137+
spdlog info "No devices found"
138+
return 0
139+
fi
140+
141+
if [ -n "${device_index}" ]; then
142+
if (("${#devices[@]}" <= "${device_index}")) || (("${device_index}" < 0)); then
143+
spdlog error "Device index is out of range"
144+
return 1
145+
fi
146+
147+
devices=("${devices[${device_index}]}")
148+
fi
149+
150+
# Ignore the tmux option if there is only one device
151+
if (("${#devices[@]}" == 1)); then
152+
tmux_socket=""
153+
fi
154+
155+
local xargs_cmd=("bash" "-c" "$*")
156+
157+
if [ -n "${tmux_socket}" ]; then
158+
xargs_cmd=("tmux" "-S" "${tmux_socket}" "new-window" "-n" "{}" "${xargs_cmd[@]}")
159+
tmux -S "${tmux_socket}" new-session -d -n iptsd
160+
fi
161+
162+
# Run the supplied commands on all devices
163+
echo -n "${devices[@]}" | xargs -d ' ' -P "${xargs_procs}" -i "${xargs_cmd[@]}"
164+
165+
if [ -n "${tmux_socket}" ]; then
166+
tmux -S "${tmux_socket}" kill-window -t 0
167+
tmux -S "${tmux_socket}" attach
168+
fi
169+
170+
return 0
171+
}
172+
173+
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
174+
run-iptsd-foreach "$@"
175+
fi

‎iptsd.spec

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ kernel driver, and sends them back to the kernel using uinput devices.
6969
%{_bindir}/iptsd-dump
7070
%{_bindir}/iptsd-find-hidraw
7171
%{_bindir}/iptsd-find-service
72+
%{_bindir}/iptsd-foreach
7273
%{_bindir}/iptsd-perf
7374
%{_bindir}/iptsd-plot
7475
%{_bindir}/iptsd-show

0 commit comments

Comments
 (0)
Please sign in to comment.