#!/bin/bash

###########################################################################
# Connects to a remote server and offers it a local shell.
# Usage: sch-client [server] [port]
#
# Copyright (C) 2010 Alkis Georgopoulos <alkisg@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# On Debian GNU/Linux systems, the complete text of the GNU General
# Public License can be found in `/usr/share/common-licenses/GPL'.
###########################################################################

# The "boolean_is_true" name is used as a sentinel that prevents ltsp_config
# from sourcing ltsp_common_function. So we're using a different name.
my_boolean_is_true() {
    case $1 in
       # match all cases of true|y|yes
       [Tt][Rr][Uu][Ee]|[Yy]|[Yy][Ee][Ss]) return 0 ;;
       *) return 1 ;;
    esac
}

die() {
    echo "ERROR: $@" >&2
    exit 1
}

sch_info() {
    local def_iface

    # Ensure that the LTSP defaults are there (for $LTSP_FATCLIENT etc)
    if [ -f /usr/share/ltsp/ltsp_config ]; then
        . /usr/share/ltsp/ltsp_config
    fi

    HOSTNAME=$(hostname)
    test -n "$HOSTNAME" || die "Empty hostname"
    def_iface=$(route -n | sed -n "/^0.0.0.0/s/.* //p")
    def_iface=${def_iface:-$(route -n | awk '$2=="0.0.0.0" { print $8 }')}
    test -n "$def_iface" || die "Empty def_iface"
    IP=$(ip -oneline -family inet addr show dev "$def_iface" | sed "s/.* \([0-9.]*\)\/.*/\\1/")
    test -n "$IP" || die "Empty IP"
    MAC=$(ip -oneline -family inet link show dev "$def_iface" | sed "s/.*ether \([^ ]*\).*/\\1/")
    MAC=$(echo "$MAC" | sed 'y/abcdef-/ABCDEF:/;s/[^A-F0-9:]//g')
    test -n "$MAC" || die "Empty MAC"
    CPU=$(cat /proc/cpuinfo | grep "^model name" | head -1 | sed "s/.*: //")
    RAM=$(free -m | grep "^Mem" | awk '{print $2}')
    VGA=$(lspci -nn -m | sed -n -e '/"VGA/s/[^"]* "[^"]*" "[^"]*" "\([^"]*\)" .*/\1/p')
    # TODO: fix upstream "$LTSP_FATCLIENT" to be present on user sessions
    if my_boolean_is_true "$LTSP_FATCLIENT"; then
        TYPE="fat"
    elif [ -n "$LTSP_CLIENT" ] || [ -f /etc/ltsp_chroot ]; then
        TYPE="thin"
    else
        TYPE="standalone"
    fi
    test -n "$USER" || USER=$(whoami)
    test -n "$UID" || UID=$(id -u)

    # If sch-client is run on a thin client from a user account (meaning that
    # it actually runs on the server), then use $LTSP_CLIENT_HOSTNAME and
    # $LTSP_CLIENT instead of $HOSTNAME and $IP.
    # MAC, CPU, RAM and VGA are not available in the environment, so we're
    # leaving the ones of the server.
    if [ "$TYPE" = "thin" ] && [ "$UID" -ne 0 ]; then
        test -n "$LTSP_CLIENT" && IP="$LTSP_CLIENT"
        test -n "$LTSP_CLIENT_HOSTNAME" && HOSTNAME="$LTSP_CLIENT_HOSTNAME"
    fi
        
    export HOSTNAME IP MAC TYPE USER UID CPU RAM VGA
}

# Go to the scripts directory, so that we can run them with ./xxx
cd $(dirname "$0")
if [ -d ../sch-client ]; then
    cd ../sch-client
else
    cd /usr/share/sch-client
fi

# When called from /etc/xdg/autostart, /sbin is not in the system path.
PATH="/sbin:/usr/sbin:$PATH"

sch_info

# Don't run on the sch-server, neither as a service nor for the teacher.
if [ "$TYPE" = "standalone" ] && [ -n "$(dpkg-query -W -f '${Version}' sch-scripts 2>/dev/null)" ]; then
    exit 0
fi

if [ "$UID" -eq 0 ] || [ "$TYPE" != "thin" ]; then
    SERVER=server
else
    SERVER=localhost
fi
export SERVER=${1:-$SERVER}
export PORT=${2:-570}

echo "Connecting to $SERVER:$PORT..."

# Connect to the server. If your bash isn't compiled with tcp socket support,
# install netcat-traditional and substitude the following with
# nc $SERVER $PORT -e /bin/sh
while ! exec 0<>"/dev/tcp/$SERVER/$PORT"; do
    echo "Server $SERVER:$PORT did not respond, retrying in 10 sec..."
    sleep 10
done

echo "Connected!"

# Also redirect stdout to the server, but keep stderr to the local console,
# to avoid possible noise from applications started in the background.
# If the callee needs to grab stderr, it can use `cmd 2>&1`.
exec 1>&0

# Finally, exec sh instead of keeping bash, to save memory.
# Actually, exec a "sch-client" symlink to sh, to make it easier for `ps`.
# +m = disable job control.
exec ./sch-client +m
