~ubuntu-branches/debian/stretch/epoptes/stretch

« back to all changes in this revision

Viewing changes to data/client-functions

  • Committer: Package Import Robot
  • Author(s): Vagrant Cascadian, Alkis Georgopoulos, Vagrant Cascadian
  • Date: 2012-03-04 13:58:00 UTC
  • mfrom: (1.2.1) (6.1.1 precise)
  • Revision ID: package-import@ubuntu.com-20120304135800-9ou11fsepopebkiw
Tags: 0.4.4-1
[ Alkis Georgopoulos ]
* screenshot: exit cleanly when X isn't available.
* Handle late connectionLost events better.
* Replace the View menu with the Labels menu.
* Ability to show real names instead of usernames.
* Don't use epoptes-client.init on LTSP 5.3.
* Get the active display when executing root commands.
* Remember more user settings (labels, history).
* Don't hang on close, on Ubuntu 12.04.
* Mark epoptes as the owner of /etc/epoptes (Closes: #661083).
* Extract shell code from python scripts for maintainability.
* Don't crash when clients with a bad certificate connect (LP: #940114).
* Add Spanish and Swedish translations.
  Many thanks to the translators!

[ Vagrant Cascadian ]
* Update Standards-Version to 3.9.3, no changes necessary. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.
 
5
#
 
6
# Copyright (C) 2010, 2012 Alkis Georgopoulos <alkisg@gmail.com>
 
7
#
 
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.
 
12
#
 
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.
 
17
#
 
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/>.
 
20
#
 
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
###########################################################################
 
24
 
 
25
# Output a message and exit with an error.
 
26
# Parameters:
 
27
# $1..$N = The message.
 
28
die() {
 
29
    echo "epoptes-client ERROR: $@" >&2
 
30
    exit 1
 
31
}
 
32
 
 
33
# Calculate, export and return a collection of useful variables.
 
34
info() {
 
35
    local server_ip def_iface
 
36
 
 
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"
 
44
        else
 
45
            HOSTNAME=$(hostname)
 
46
            test -n "$HOSTNAME" || die "Empty hostname"
 
47
        fi
 
48
        if [ -n "$LTSP_CLIENT" ] && [ -n "$LTSP_CLIENT_MAC" ]; then
 
49
            # LTSP exports those vars, use them if available.
 
50
            MAC="$LTSP_CLIENT_MAC"
 
51
            IP="$LTSP_CLIENT"
 
52
        else
 
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"
 
66
        fi
 
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')
 
70
        OS=$(uname -o)
 
71
 
 
72
        export VERSION USER NAME HOME HOSTNAME MAC IP CPU RAM VGA OS
 
73
        cached_info=true
 
74
    fi
 
75
    cat <<EOF
 
76
uid=$UID
 
77
type=$TYPE
 
78
version=$VERSION
 
79
user=$USER
 
80
name=$NAME
 
81
home=$HOME
 
82
hostname=$HOSTNAME
 
83
mac=$MAC
 
84
ip=$IP
 
85
cpu=$CPU
 
86
ram=$RAM
 
87
vga=$VGA
 
88
os=$OS
 
89
EOF
 
90
}
 
91
 
 
92
# Execute a command in the background and print its pid.
 
93
# Parameters:
 
94
# $1..$N = The command and its parameters.
 
95
execute() {
 
96
    if [ $# -eq 1 ]; then
 
97
        # If there's only one parameter, it might be a file or URL.
 
98
        which -- "$1" >/dev/null || set "xdg-open" "$1"
 
99
    fi
 
100
 
 
101
    # On root clients, try to get the active DISPLAY, the command may need it.
 
102
    test "$UID" -eq 0 && export $(./get-display)
 
103
 
 
104
    # Do some logging, either in ~/.xsession-errors or on the console.
 
105
    echo "$(LANG=C date '+%c'), epoptes-client executing: $@" >&2
 
106
 
 
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 ) &
 
111
 
 
112
    # Print the pid.
 
113
    echo $!
 
114
}
 
115
 
 
116
# Log out the connected user.
 
117
logout() {
 
118
    ./endsession --logout
 
119
}
 
120
 
 
121
# Reboot the client.
 
122
reboot() {
 
123
    ./endsession --reboot
 
124
}
 
125
 
 
126
# Shut down the client.
 
127
shutdown() {
 
128
    ./endsession --shutdown
 
129
}
 
130
 
 
131
# Create a thumbnail of the user screen.
 
132
# Parameters:
 
133
# $1 = thumbnail width.
 
134
# $2 = thumbnail height.
 
135
screenshot() {
 
136
    if ./screenshot "$1" "$2"; then
 
137
        BAD_SCREENSHOTS=0
 
138
    elif [ "$BAD_SCREENSHOTS" -eq 3 ]; then
 
139
        die "3 failed screenshots, exiting..."
 
140
    else
 
141
        BAD_SCREENSHOTS=$(($BAD_SCREENSHOTS+1))
 
142
    fi
 
143
}
 
144
 
 
145
# Lock the screen.
 
146
# Parameters:
 
147
# $1 = seconds to keep screen locked, 0 means forever - currently ignored.
 
148
# $2 = message to display to the user.
 
149
lock_screen() {
 
150
    test -n "$EPOPTES_LOCK_SCREEN_PID" && kill "$EPOPTES_LOCK_SCREEN_PID"
 
151
    EPOPTES_LOCK_SCREEN_PID=$(execute ./lock-screen "$2")
 
152
}
 
153
 
 
154
# Unlock a locked screen.
 
155
unlock_screen() {
 
156
    if [ -n "$EPOPTES_LOCK_SCREEN_PID" ]; then
 
157
        kill "$EPOPTES_LOCK_SCREEN_PID"
 
158
        unset EPOPTES_LOCK_SCREEN_PID
 
159
    fi
 
160
}
 
161
 
 
162
# Mute the system sound.
 
163
# Parameters:
 
164
# $1 = seconds to keep sound muted, 0 means forever - currently ignored.
 
165
mute_sound() {
 
166
    execute amixer -c 0 -q sset Master mute
 
167
}
 
168
 
 
169
# Unute the system sound.
 
170
unmute_sound() {
 
171
    execute amixer -c 0 -q sset Master unmute
 
172
}
 
173
 
 
174
# Display some text to the user.
 
175
# Parameters:
 
176
# $1 = text.
 
177
# $2 = dialog type, one of "info", "warning" or "error".
 
178
message() {
 
179
    local type
 
180
 
 
181
    type=${2:-info}
 
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"
 
186
    else
 
187
        echo "$type: $1" >&2
 
188
    fi
 
189
}
 
190
 
 
191
# Connect to the server to be monitored.
 
192
get_monitored() {
 
193
    execute x11vnc -noshm -24to32 -viewonly -connect_or_exit "$SERVER"
 
194
}
 
195
 
 
196
# Connect to the server to get assistance.
 
197
get_assisted() {
 
198
    execute x11vnc -noshm -24to32 -connect_or_exit "$SERVER"
 
199
}
 
200
 
 
201
# Deactivate the screensaver, in order for the users to watch a broadcast.
 
202
stop_screensaver() {
 
203
    if [ -x /usr/bin/gnome-screensaver-command ]; then
 
204
        gnome-screensaver-command -d
 
205
    fi
 
206
}
 
207
 
 
208
# Receive a broadcasted screen from the server.
 
209
# Parameters:
 
210
# $1 = port.
 
211
# $2 = fullscreen.
 
212
receive_broadcast() {
 
213
    stop_transmissions
 
214
    export $(./get-display)
 
215
    xset dpms force on
 
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")
 
219
}
 
220
 
 
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
 
226
}
 
227
 
 
228
# Open a root terminal inside the X session.
 
229
root_term() {
 
230
    execute xterm -e bash -l
 
231
}
 
232
 
 
233
# Send a screen session to the server using socat.
 
234
# Parameters:
 
235
# $1 = port.
 
236
remote_term() {
 
237
    local screen_params
 
238
 
 
239
    if [ "$UID" -eq 0 ]; then
 
240
        screen_params="bash -l"
 
241
    else
 
242
        screen_params="-l"
 
243
    fi
 
244
    execute sh -c "
 
245
cd
 
246
sleep 1
 
247
TERM=xterm exec socat EXEC:'screen $screen_params',pty,stderr tcp:$SERVER:$1"
 
248
}
 
249
 
 
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.
 
254
ping() {
 
255
    if [ "$UID" -gt 0 ]; then
 
256
        xprop -root -f EPOPTES_CLIENT 32c -set EPOPTES_CLIENT $$ || exit
 
257
    fi
 
258
}
 
259
 
 
260
# Display a message.
 
261
# Parameters:
 
262
# $1..$N = The message.
 
263
# echo()
 
264
# No need to implement it in the shell, it's embedded.
 
265
 
 
266
# Main
 
267
 
 
268
if [ -z "$UID" ] || [ -z "$TYPE" ] || [ -z "$SERVER" ]; then
 
269
    die "Required environment variables are missing."
 
270
fi
 
271
 
 
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
 
277
    log_end_msg 0 >&5
 
278
    )
 
279
else
 
280
    echo "[ OK ]" >&5
 
281
fi