1
###########################################################################
2
# Implements the client side of the epoptes communications protocol.
3
# The daemon reads this file when it starts, and sends it to clients when they
4
# connect. The clients actually source it and then wait for further commands.
6
# Copyright (C) 2010, 2012 Alkis Georgopoulos <alkisg@gmail.com>
8
# This program is free software: you can redistribute it and/or modify
9
# it under the terms of the GNU General Public License as published by
10
# the Free Software Foundation, either version 3 of the License, or
11
# (at your option) any later version.
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU General Public License for more details.
18
# You should have received a copy of the GNU General Public License
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
21
# On Debian GNU/Linux systems, the complete text of the GNU General
22
# Public License can be found in `/usr/share/common-licenses/GPL'.
23
###########################################################################
25
# Output a message and exit with an error.
27
# $1..$N = The message.
29
echo "epoptes-client ERROR: $@" >&2
33
# Calculate, export and return a collection of useful variables.
35
local server_ip def_iface
37
if [ -z "$cached_info" ]; then
38
VERSION=${VERSION:-0.4.3} # Just in case the client wasn't updated
39
test -n "$USER" || USER=$(whoami)
40
NAME=$(getent passwd "$UID" | cut -d':' -f5 | cut -d',' -f1)
41
test -n "$HOME" || HOME=$(getent passwd "$UID" | cut -d: -f6)
42
if [ -n "$LTSP_CLIENT_HOSTNAME" ]; then
43
HOSTNAME="$LTSP_CLIENT_HOSTNAME"
46
test -n "$HOSTNAME" || die "Empty hostname"
48
if [ -n "$LTSP_CLIENT" ] && [ -n "$LTSP_CLIENT_MAC" ]; then
49
# LTSP exports those vars, use them if available.
50
MAC="$LTSP_CLIENT_MAC"
53
server_ip=$(getent hosts "$SERVER" | cut -d' ' -f1)
54
def_iface=$(ip -oneline -family inet route get "$server_ip" \
55
| sed -n '/.* dev \([^ ]*\).*/s//\1/p')
56
test "${def_iface:-lo}" = "lo" && def_iface=$(ip -oneline -family \
57
inet route show | sed -n '/^default .* dev \([^ ]*\).*/s//\1/p')
58
def_iface=${def_iface:-eth0}
59
MAC=$(ip -oneline -family inet link show dev "$def_iface" \
60
| sed "s/.*ether \([^ ]*\).*/\\1/")
61
MAC=$(echo "$MAC" | sed 'y/abcdef-/ABCDEF:/;s/[^A-F0-9:]//g')
62
test -n "$MAC" || die "Empty MAC"
63
IP=$(ip -oneline -family inet addr show dev "$def_iface" \
64
| sed "s/.* \([0-9.]*\)\/.*/\\1/")
65
test -n "$IP" || die "Empty IP"
67
CPU=$(cat /proc/cpuinfo | grep "^model name" | head -1 | sed "s/.*: //")
68
RAM=$(free -m | grep "^Mem" | awk '{print $2}')
69
VGA=$(lspci -nn -m | sed -n -e '/"VGA/s/[^"]* "[^"]*" "[^"]*" "\([^"]*\)" .*/\1/p')
72
export VERSION USER NAME HOME HOSTNAME MAC IP CPU RAM VGA OS
92
# Execute a command in the background and print its pid.
94
# $1..$N = The command and its parameters.
97
# If there's only one parameter, it might be a file or URL.
98
which -- "$1" >/dev/null || set "xdg-open" "$1"
101
# On root clients, try to get the active DISPLAY, the command may need it.
102
test "$UID" -eq 0 && export $(./get-display)
104
# Do some logging, either in ~/.xsession-errors or on the console.
105
echo "$(LANG=C date '+%c'), epoptes-client executing: $@" >&2
107
# The command is ran on a subshell with stdin and stdout redirected to
108
# /dev/null, so that it doesn't interfere with the output of other commands.
109
# stderr isn't changed, i.e. ~/.xsession-errors will be used.
110
( "$@" 0</dev/null >/dev/null ) &
116
# Log out the connected user.
118
./endsession --logout
123
./endsession --reboot
126
# Shut down the client.
128
./endsession --shutdown
131
# Create a thumbnail of the user screen.
133
# $1 = thumbnail width.
134
# $2 = thumbnail height.
136
if ./screenshot "$1" "$2"; then
138
elif [ "$BAD_SCREENSHOTS" -eq 3 ]; then
139
die "3 failed screenshots, exiting..."
141
BAD_SCREENSHOTS=$(($BAD_SCREENSHOTS+1))
147
# $1 = seconds to keep screen locked, 0 means forever - currently ignored.
148
# $2 = message to display to the user.
150
test -n "$EPOPTES_LOCK_SCREEN_PID" && kill "$EPOPTES_LOCK_SCREEN_PID"
151
EPOPTES_LOCK_SCREEN_PID=$(execute ./lock-screen "$2")
154
# Unlock a locked screen.
156
if [ -n "$EPOPTES_LOCK_SCREEN_PID" ]; then
157
kill "$EPOPTES_LOCK_SCREEN_PID"
158
unset EPOPTES_LOCK_SCREEN_PID
162
# Mute the system sound.
164
# $1 = seconds to keep sound muted, 0 means forever - currently ignored.
166
execute amixer -c 0 -q sset Master mute
169
# Unute the system sound.
171
execute amixer -c 0 -q sset Master unmute
174
# Display some text to the user.
177
# $2 = dialog type, one of "info", "warning" or "error".
182
if [ -x /usr/bin/zenity ]; then
183
execute zenity "--$type" --text "$1"
184
elif [ -x /usr/bin/xmessage ]; then
185
execute xmessage -center "$1"
191
# Connect to the server to be monitored.
193
execute x11vnc -noshm -24to32 -viewonly -connect_or_exit "$SERVER"
196
# Connect to the server to get assistance.
198
execute x11vnc -noshm -24to32 -connect_or_exit "$SERVER"
201
# Deactivate the screensaver, in order for the users to watch a broadcast.
203
if [ -x /usr/bin/gnome-screensaver-command ]; then
204
gnome-screensaver-command -d
208
# Receive a broadcasted screen from the server.
212
receive_broadcast() {
214
export $(./get-display)
216
EPOPTES_VNCVIEWER_PID=$(execute sh -c "
217
sleep 0.$(($(hexdump -e \"%d\" -n 2 /dev/urandom) % 50 + 50))
218
exec xvnc4viewer -Shared -ViewOnly ${2+-FullScreen -UseLocalCursor=0 -MenuKey F13} $SERVER:$1")
221
# The vnc clients should automatically exit when the server is killed.
222
# Unfortunately, that isn't always true, so try to kill it anyway.
223
stop_transmissions() {
224
test -n "$EPOPTES_VNCVIEWER_PID" && kill "$EPOPTES_VNCVIEWER_PID"
225
unset EPOPTES_VNCVIEWER_PID
228
# Open a root terminal inside the X session.
230
execute xterm -e bash -l
233
# Send a screen session to the server using socat.
239
if [ "$UID" -eq 0 ]; then
240
screen_params="bash -l"
247
TERM=xterm exec socat EXEC:'screen $screen_params',pty,stderr tcp:$SERVER:$1"
250
# Ping is called every few seconds just to make sure the connection is alive.
251
# But currently we use it as a workaround to kill stale clients too:
252
# Epoptes-client isn't registered as an X session client, and it doesn't
253
# exit automatically, so tell it to exit as soon as X is unavailable.
255
if [ "$UID" -gt 0 ]; then
256
xprop -root -f EPOPTES_CLIENT 32c -set EPOPTES_CLIENT $$ || exit
262
# $1..$N = The message.
264
# No need to implement it in the shell, it's embedded.
268
if [ -z "$UID" ] || [ -z "$TYPE" ] || [ -z "$SERVER" ]; then
269
die "Required environment variables are missing."
272
# Source the lsb init functions, for log_end_msg.
273
# Unfortunately it seems that Centos and Fedora don't have that file.
274
if [ -f /lib/lsb/init-functions ]; then
275
( # Use a subshell, we only need init-functions once
276
. /lib/lsb/init-functions