#!/bin/bash

# $Id: profile-change.in,v 1.21 2005/03/01 20:50:19 cph Exp $
#
# Copyright 2001,2002,2003,2005 Massachusetts Institute of Technology
#
# This file is part of laptop-net.
#
# Laptop-net 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 2 of the License, or
# (at your option) any later version.
#
# Laptop-net 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 laptop-net; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.

# This script is called by the network-control scripts, after ifup or
# ifdown is run, and is intended to adjust the machine's profile as
# needed for the current network environment.

set -e

export PATH=/bin:/usr/bin:/sbin:/usr/sbin

PROFILE_DIR="/etc/laptop-net/profiles"
PROFILE_FILE="/var/run/laptop-net/profile"
GET_ADDR="/usr/lib/laptop-net/get-addr"
LOGGER="/usr/bin/logger -p daemon.info -t laptop-net"

export INTERFACE="${1}"
export IP_ADDRESS="${2}"

. "/usr/share/laptop-net/shared.sh"

NEW_PROFILE=""
if [ -d "${PROFILE_DIR}" ]; then
    if [ -z "${IP_ADDRESS}" ]; then
	# Either an IP address, "down", or "unknown".
	# "down" means the interface is down.
	# "unknown" means we were unable to examine the interface.
	export IP_ADDRESS="$("${GET_ADDR}" "${INTERFACE}" 2> /dev/null)"
    fi

    SCHEME=$(read_scheme_file "${INTERFACE}")
    HWADDR=$(/sbin/ifconfig "${INTERFACE}" | sed -ne 's/.*\(..:..:..:..:..:..\).*/\1/p')
    for P in $(cd "${PROFILE_DIR}"; /bin/ls -d [a-z0-9]* 2> /dev/null); do
	D="${PROFILE_DIR}/${P}"
	if [ -r "${D}/patterns" ]; then
	    for PATTERN in $(cat "${D}/patterns");do
		case "${PATTERN}" in
		*,*,*,*)
		    ;;
		*,*,*)
		    PATTERN="${PATTERN},*"
		    ;;
		*,*)
		    PATTERN="${PATTERN},*,*"
		    ;;
		*)
		    PATTERN="${PATTERN},*,*,*"
		    ;;
		esac
	    	case "${IP_ADDRESS},${SCHEME},${INTERFACE},${HWADDR}" in
		(${PATTERN})
		    NEW_PROFILE="${P}"
		    break 2
		    ;;
		esac
	    done
	fi
    done
fi

if [ -f "${PROFILE_FILE}" ]; then
    OLD_PROFILE="$(cat "${PROFILE_FILE}")"
else
    OLD_PROFILE=""
fi

# Do nothing if the profile isn't changing.
[ "${NEW_PROFILE}" != "${OLD_PROFILE}" ] || exit 0

run_init_scripts ()
(
    PROFILE="${1}"
    KEYWORD="${2}"
    RCDIR="${PROFILE_DIR}/${PROFILE}/rc.d"
    if [ "${KEYWORD}" = "start" ]; then
	PREFIX="S"
    else
	PREFIX="K"
    fi
    if [ -d "${RCDIR}" ]; then
	for FILENAME in ${RCDIR}/${PREFIX}[0-9][0-9]*; do
	    if [ -f "${FILENAME}" ]; then
		case "${FILENAME}" in
		(*.sh)
		    /bin/sh "${FILENAME}" "${KEYWORD}" || true
		    ;;
		(*)
		    "${FILENAME}" "${KEYWORD}" || true
		    ;;
		esac
	    fi
	done
    fi
)

run_script ()
(
    PROFILE="${1}"
    SCRIPT="${PROFILE_DIR}/${PROFILE}/${2}"
    if [ -x "${SCRIPT}" ]; then
	"${SCRIPT}" "${PROFILE_DIR}" "${PROFILE}" || true
    fi
)

if [ -n "${OLD_PROFILE}" ]; then
    ${LOGGER} "Deselecting network profile \"${OLD_PROFILE}\""
    run_script "${OLD_PROFILE}" "before-deselect"
    run_init_scripts "${OLD_PROFILE}" stop
    run_script "${OLD_PROFILE}" "after-deselect"
    # For backwards compatibility:
    run_script "${OLD_PROFILE}" "deselect"
fi

if [ -n "${NEW_PROFILE}" ]; then
    ${LOGGER} "Selecting network profile \"${NEW_PROFILE}\""
    run_script "${NEW_PROFILE}" "before-select"
    if [ -d "${PROFILE_DIR}/${NEW_PROFILE}/files.d" ]; then
	(
	    cd "${PROFILE_DIR}/${NEW_PROFILE}/files.d"
	    if [ -n "$(/bin/ls)" ]; then
		/bin/cp -a * /
	    fi
	)
    fi
    run_init_scripts "${NEW_PROFILE}" start
    run_script "${NEW_PROFILE}" "after-select"
fi

echo "${NEW_PROFILE}" > "${PROFILE_FILE}"

exit 0
