[package] allow restarting of server process only and add a killcients
[openwrt/svn-archive/archive.git] / net / sslh / files / sslh.init
index 56b7d22606be9276afd4a382384181e7f047f5b4..b4b9e5afcc304191965a644976383bff9d531a92 100644 (file)
@@ -5,6 +5,8 @@ NAME=sslh
 PROG=/usr/sbin/sslh
 START=95
 PIDCOUNT=0
+EXTRA_COMMANDS="killclients"
+EXTRA_HELP="   killclients Kill ${NAME} processes except servers and yourself"
 
 sslh_start()
 {
@@ -23,23 +25,23 @@ sslh_start()
        local val
        # A) listen parameter
        config_get val "${section}" listen
-       [ ! -z "${val}" ] && append args "-p ${val}"
+       [ -n "${val}" ] && append args "-p ${val}"
        # B) ssh parameter
        config_get val "${section}" ssh
-       [ ! -z "${val}" ] && append args "-s ${val}"
+       [ -n "${val}" ] && append args "-s ${val}"
        # C) ssl parameter
        config_get val "${section}" ssl
-       [ ! -z "${val}" ] && append args "-l ${val}"
+       [ -n "${val}" ] && append args "-l ${val}"
        # D) timeout (for ssh, then ssl is assumed)
        config_get val "${section}" timeout
-       [ ! -z "${val}" ] && append args "-t ${val}"
+       [ -n "${val}" ] && append args "-t ${val}"
        # E) verbose parameter
        local verbosed
        config_get_bool verbosed "${section}" verbose 0
        [ "${verbosed}" -ne 0 ] && append args "-v"
 
        # execute program and return its exit code
-       [ "${verbosed}" -ne 0 ] && echo "${NAME}: section ${section} starting ${PROG} ${args}"
+       [ "${verbosed}" -ne 0 ] && echo "${initscript}: section ${section} started via ${PROG} ${args}"
        ${PROG} ${args}
        return $?
 }
@@ -55,27 +57,88 @@ stop()
        local pidfile
        local rc=0
 
-       # killing all known processes
+       # killing all server processes
        for pidfile in `ls /var/run/${NAME}.*.pid`
         do
-               start-stop-daemon -K -s KILL -p "${pidfile}" -n "${NAME}"
+               start-stop-daemon -K -s KILL -p "${pidfile}" -n "${NAME}" >/dev/null
                [ $? -ne 0 ] && rc=1
                rm -f "${pidfile}"
        done
+       [ -z "${pidfile}" ] && echo "${initscript}: no pid files, if you get problems with start then try killclients"
+       [ ${rc} -ne 0 ] && echo "${initscript}: inconsistency in pid files, if you get problems with start then try killclients"
+}
 
-       # kill orphaned processes
-       if [ ${rc} -ne 0 ]
-        then
-               echo "${NAME}: inconsistency in pid files killing all orphaned processes"
-               for pid in `pidof sslh`
-                do
-                       # check if correct program
-                       ps | grep "${pid}" | grep "${PROG}" >/dev/null
-                       [ $? -ne 0 ] && continue
+killclients()
+{
+       local ignore=''
+       local server
+       local pid
+       local connection
+       local proto
+       local address
+
+       # if this script is run from inside a client session, then ignore that session
+       pid="$$"
+       while [ "${pid}" -ne 0 ]
+        do
+               # get parent process id
+               pid=`cut -d ' ' -f 4 "/proc/${pid}/stat"`
+               [ "${pid}" -eq 0 ] && break
+
+               # check if pid is connected to a client connection
+               # a) get established connection for pid
+               connection=`netstat -tupn 2>/dev/null | sed "s/[ ]\+/ /g" | grep -e "ESTABLISHED ${pid}/"`
+               [ -z "${connection}" ] && continue
+               #    get connection details for foreign address
+               proto=`echo ${connection} | cut -d ' ' -f 1`
+               address=`echo ${connection} | cut -d ' ' -f 5`
+
+               # b) get pid for foreign address, only possible if foreign address is from this machine itself
+               connection=`netstat -tupn 2>/dev/null | sed "s/[ ]\+/ /g" | grep -e "^${proto}.*${address}.*ESTABLISHED.*/${NAME}"`
+               [ -z "${connection}" ] && continue
+               #    check that the local address (field 4) corresponds to the foreign address of the previous connection
+               server=`echo ${connection} | cut -d ' ' -f 4`
+               [ "${server}" != "${address}" ] && continue
+               #    get pid from connection
+               server=`echo ${connection} | cut -d ' ' -f 7 | cut -d '/' -f 1`
+
+               # check if client connection
+               ps | grep -e "^[ ]*${server} " | grep -e "${PROG}" >/dev/null
+               if [ $? -eq 0 ]
+                then
+                       append ignore "${server}"
+                       break
+               fi
+       done
 
-                       # kill process
-                       echo "Killing ${pid}..."
-                       kill -s KILL ${pid}
+       # get all server pids that should be ignored
+       for server in `cat /var/run/${NAME}.*.pid`
+        do
+               append ignore "${server}"
+       done
+
+       # get all running pids and kill client connections
+       local skip
+       for pid in `pidof "${NAME}"`
+        do
+               # check if correct program
+               ps | grep -e "^[ ]*${pid} " | grep -e "${PROG}" >/dev/null
+               [ $? -ne 0 ] && continue
+
+               # check if pid should be ignored (servers, ourself)
+               skip=0
+               for server in ${ignore}
+                do
+                       if [ "${pid}" == "${server}" ]
+                        then
+                               skip=1
+                               break
+                       fi
                done
-       fi
+               [ "${skip}" -ne 0 ] && continue
+
+               # kill process
+               echo "${initscript}: Killing ${pid}..."
+               kill -KILL ${pid}
+       done
 }