samcon

#!/usr/local/bin/python

# This is free software.  See LICENSE for terms.
# The python license may also apply.
# Copyright 2004 - 2015, Patricia Kirk.

# salmon command line control interface

import os, sys, socket, readline
from time import sleep

def stop(conns):
    for conn in conns:
	try:
	    conn[0].shutdown(socket.SHUT_RDWR)
	    conn[0].close()
	except socket.error, err:
	    print str(err)
	    continue

def scan(s, conns):
    stop(conns)
    conns = []
    cmd = str(os.getuid())
    s.settimeout(3.0)
    while 1:
	try:
	    conn, addr = s.accept()
	    conns.append([conn, ''])
	    conn.send(cmd)
	except socket.timeout:
	    break
    s.settimeout(0.0)
    if not conns:
	print '  No response on port# %05d' % port
    return conns

usage = 'Usage:\tsamcon port# >= 49152 or <= 65535'
help = ['\nLocal commands, effect samcon',
	'  h/?/help\tPrint this list',
	'  scan\t\tRefresh the list of connections',
	'  q\t\tExit',
	'\nGlobal commands, sent to all active connections',
	'  argv\t\tPrint the command line, short list',
	'  args\t\tPrint the startup options/arguments, short list',
	'\nDirected commands, must be preceeded with an index number or "all"',
	'  argv\t\tPrint the command line, full list',
	'  args\t\tPrint the startup options/arguments, full list',
	'  aargs\t\tPrint the current options/arguments, full list',
	'  get <option>\tPrint the current value of the named option',
	'  set <option> <value>\tSet <option> to <value>',
	'  kill\t\tStop the current child and start another',
	'  stop\t\tDie without spawning\n']

try:
    port = int(sys.argv[1])
    if port < 49152 or port > 65535:
	spam
except:
    print usage
    sys.exit()

host = ''
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while 1:
    try:
	s.bind((host, port))
	break
    except socket.error, err:
	print str(err)
	if str(err).find('Address already in use') < 0:
	    sys.exit()
	sleep(10)
s.listen(10)
conns = scan(s, [])
dest = None

while 1:
    if dest is None:
	indx = 1
	for conn in conns:
	    try:
		received = conn[0].recv(2048)
		if not conn[1]:
		    conn[1] = received.split(' ')[0]
		print '  %02d %s' % (indx, received)
		indx += 1
	    except socket.error:
		pass
    elif dest >= 0 and dest < len(conns):
	indx = dest + 1
	received = conns[dest][0].recv(2048)
	print '  %02d %s' % (indx, received)
	if cmd.find('kill') >= 0:
	    conns = scan(s, conns)
	    dest = None
	    continue
    dest = None
    cmd = raw_input('cmd > ')
    if not cmd:
	cmd = 'argv'
    if cmd.startswith('q'):
	for conn in conns:
	    conn[0].send('%s close' % conn[1])
	stop(conns)
	break
    if cmd.startswith('h') or cmd == '?':
	for line in help:
	    print line
	continue
    if cmd == 'scan':
	conns = scan(s, conns)
	continue
    try:
	dest = int(cmd.split(' ')[0]) - 1
	if dest < 0 or dest >= len(conns):
	    print 'Invalid index number'
	    continue
	conns[dest][0].send('%s %s' % (conns[dest][1], cmd[cmd.find(' ') + 1:]))
    except:
	for conn in conns:
	    try:
		if cmd.startswith('all'):
		    conn[0].send('%s %s' % (conn[1], cmd[cmd.find(' ') + 1:]))
		else:
		    conn[0].send(cmd)
	    except socket.error, err:
		print str(err)
		continue
    if cmd.find('stop') >= 0:
	conns = scan(s, conns)
	dest = None
    sleep(1)
s.shutdown(socket.SHUT_RDWR)
s.close()
sys.exit()
* * o * *