#!/usr/bin/python

###############################################################################
###############################################################################
##
##  Copyright (C) 2006 Red Hat, Inc.  All rights reserved.
##
##  This copyrighted material is made available to anyone wishing to use,
##  modify, copy, or redistribute it subject to the terms and conditions
##  of the GNU General Public License v.2.
##
###############################################################################
###############################################################################

import getopt, sys
import os
import socket
import time

from telnetlib import Telnet

TELNET_TIMEOUT=5  #How long to wait for a response from a telnet try

# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and
# "#END_VERSION_GENERATION"  It is generated by the Makefile

#BEGIN_VERSION_GENERATION
FENCE_RELEASE_NAME="New APC Agent - test release"
REDHAT_COPYRIGHT=""
BUILD_DATE="September 21, 2006"
#END_VERSION_GENERATION

POWER_OFF = 0
POWER_ON = 1
POWER_STATUS = 2
POWER_REBOOT = 3

COMPLETE = 0
NOT_COMPLETE = 1

ON = "ON"
OFF = "OFF"

SUCCESS = "success"
FAIL = "fail"

address = ""
login = ""
passwd = ""
passwd_script = ""
port = ""
switchnum = ""
action = POWER_REBOOT   #default action
verbose = False

logfile = None

#set up regex list
CONTROL_CONSOLE = "Control Console -----"
DEVICE_MANAGER = "Device Manager -----"
OUTLET_CONTROL = "- Outlet Control/Configuration -----"
OUTLET_MANAGE = "- Outlet Management -----"
CONTROL_OUTLET = "- Control Outlet -----"
CONTROL_OUTLET_2 = "- Outlet Control "
COMMAND_SUCCESS = "Command successfully issued."
COMMAND_SUCCESS_2 = " Success"
CONFIRM = "Enter 'YES' to continue or <ENTER> to cancel :"
CONTINUE = "Press <ENTER> to continue..."
SCREEN_END = "<ESC>- Main Menu, <ENTER>- Refresh, <CTRL-L>- Event Log"
SCREEN_END_2 = "<ESC>- Back, <ENTER>- Refresh, <CTRL-L>- Event Log"
USERNAME = "User Name :"
PASSWORD = "Password  :"
MASTER = "------- MasterSwitch"
FIRMWARE_STR = "Rack PDU APP"

CONTINUE_INDEX = 0

FIRMWARE_REV = 2

regex_list = list()
regex_list.append(CONTINUE)
regex_list.append(SCREEN_END)
regex_list.append(SCREEN_END_2)
regex_list.append(USERNAME)
regex_list.append(PASSWORD)

def usage():
  print "Usage:\n"
  print "fence_apc [options]"
  print "Options:"
  print "   -a <ipaddress>           ip or hostname of APC switch"
  print "   -h                       print out help"
  print "   -l [login]               login name"
  print "   -n [port]                switch port"
  print "   -p [password]            password"
  print "   -S [path]                script to run to retrieve password"
  print "   -o [action]              Reboot (default), Off, On, or Status"
  print "   -v Verbose               Verbose mode - writes file to /tmp/apclog"
  print "   -V                       Print Version, then exit"

  sys.exit (0)

def version():
  print "fence_apc %s  %s\n" % (FENCE_RELEASE_NAME, BUILD_DATE)
  print "%s\n" % REDHAT_COPYRIGHT
  sys.exit(0)

def main():

  global address, login, passwd, passwd_script, port, action, verbose, logfile, switchnum

  if len(sys.argv) > 1:
    try:
      opts, args = getopt.getopt(sys.argv[1:], "a:hl:o:n:p:S:vV", ["help", "output="])
    except getopt.GetoptError:
      #print help info and quit
      usage()
      sys.exit(2)
      
    for o, a in opts:
      if o == "-v":
        verbose = True
      if o == "-V":
        version()
      if o in ("-h", "--help"):
        usage()
        sys.exit()
      if o == "-l":
        login = a
      if o == "-p":
        passwd = a
      if o == "-S":
        passwd_script = a
      if o == "-n":
        dex = a.find(":")
        if dex == (-1):
          port = a
        else:
          switchnum = a[:dex]
          port = a[(dex+1):]
      if o  == "-o":
        if a == "Off" or a == "OFF" or a == "off":
          action = POWER_OFF
        elif a == "On" or a == "ON" or a == "on":
          action = POWER_ON
        elif a == "Status" or a == "STATUS" or a == "status":
          action = POWER_STATUS
        elif a == "Reboot" or a == "REBOOT" or a == "reboot":
          action = POWER_REBOOT
        else:
          usage()
          sys.exit()
      if o == "-a":
        address = a
    if address == "" or login == "" or (passwd == "" and passwd_script == "") or port == "":
      usage()
      sys.exit()
    
  else: #Take args from stdin...
    params = {}
    #place params in dict
    for line in sys.stdin:
      val = line.split("=")
      if len(val) == 2:
        params[val[0].strip()] = val[1].strip()

    try:
      address = params["ipaddr"]
    except KeyError, e:
      sys.stderr.write("FENCE: Missing ipaddr param for fence_apc...exiting")
      sys.exit(1)
    try:
      login = params["login"]
    except KeyError, e:
      sys.stderr.write("FENCE: Missing login param for fence_apc...exiting")
      sys.exit(1)
    try:
      if 'passwd' in params:
        passwd = params["passwd"]
      if 'passwd_script' in params:
        passwd_script = params['passwd_script']
      if passwd == "" and passwd_script == "":
        raise "missing password"
    except:
      sys.stderr.write("FENCE: Missing passwd for fence_apc...exiting")
      sys.exit(1)
    try:
      port = params["port"]
    except KeyError, e:
      sys.stderr.write("FENCE: Missing port param for fence_apc...exiting")
      sys.exit(1)
    try:
      switchnum = params["switch"]
    except KeyError, e:
      pass
    try:
      verbose = params["verbose"]
      verbose = (verbose == 'True' or verbose == 'true' or verbose == 'TRUE')
    except KeyError, e:
      pass
    
    try:
      a = params["option"]
      if a == "Off" or a == "OFF" or a == "off":
        action = POWER_OFF
      elif a == "On" or a == "ON" or a == "on":
        action = POWER_ON
      elif a == "Reboot" or a == "REBOOT" or a == "reboot":
        action = POWER_REBOOT
    except KeyError, e:
      action = POWER_REBOOT
    
    #### End of stdin section
  
  
  # retrieve passwd from passwd_script (if specified)
  passwd_scr = ''
  if len(passwd_script):
    try:
      if not os.access(passwd_script, os.X_OK):
        raise 'script not executable'
      p = os.popen(passwd_script, 'r', 1024)
      passwd_scr = p.readline().strip()
      if p.close() != None:
        raise 'script failed'
    except:
      sys.stderr.write('password-script "%s" failed\n' % passwd_script)
      passwd_scr = ''
    
  if passwd == "" and passwd_scr == "":
    sys.stderr.write('password not available, exiting...')
    sys.exit(1)
  elif passwd == passwd_scr:
    pass
  elif passwd and passwd_scr:
    # execute self, with password_scr as passwd,
    # if that fails, continue with "passwd" argument as password
    if len(sys.argv) > 1:
      comm = sys.argv[0]
      skip_next = False
      for w in sys.argv[1:]:
        if skip_next:
          skip_next = False
        elif w in ['-p', '-S']:
          skip_next = True
        else:
          comm += ' ' + w
      comm += ' -p ' + passwd_scr
      ret = os.system(comm)
      if ret != -1 and os.WIFEXITED(ret) and os.WEXITSTATUS(ret) == 0:
        # success
        sys.exit(0)
      else:
        sys.stderr.write('Use of password from "passwd_script" failed, trying "passwd" argument\n')
    else: # use stdin
      p = os.popen(sys.argv[0], 'w', 1024)
      for par in params:
        if par not in ['passwd', 'passwd_script']:
          p.write(par + '=' + params[par] + '\n')
      p.write('passwd=' + passwd_scr + '\n')
      p.flush()
      if p.close() == None:
        # success
        sys.exit(0)
      else:
        sys.stderr.write('Use of password from "passwd_script" failed, trying "passwd" argument\n')
  elif passwd_scr:
    passwd = passwd_scr
  # passwd all set
  
  
  
  ### Order of events
  # 0) If verbose, prepare log file handle
  # 1) Open socket
  # 2) Log in
  # 3) Evaluate task. Task will be one of:
  # 3a - Check status and print to stdout (or log file if verbose)
  # 3b - Turn a port off, then confirm
  # 3c - Turn a port on, then confirm
  # 3d - Reboot by turning a port off, then on, and confirming each step.

  if verbose:
    setup_logging()

  sock = setup_socket()

  # Ok, now lets log in...
  do_login(sock)

  # Now we should be at the outside Control screen
    
  if action == POWER_STATUS:
    # We should be at the Control screen, so we need to write a '1'
    # to kick things off
    sock.write("1\r")
    statusval = do_status_check(sock)
    backout(sock)
    sock.write("4\r")  # Logs out
    
  elif action == POWER_OFF:
    sock.write("1\r")
    do_power_off(sock)
    backout(sock) # Return to control screen
    statusval = do_status_check(sock)
    if statusval == OFF:
      if verbose:
        logit("Power Off successful\n")
      print "Power Off successful"
      backout(sock)
      sock.write("4\r")  # Logs out
      sock.close()
      sys.exit(0)
    else:
      if verbose:
        logit("Power Off unsuccessful\n")
        logit("Undetermined error\n")
      sys.stderr.write("Power Off unsuccessful")
      backout(sock)
      sock.write("4\r")  # Logs out
      sock.close()
      sys.exit(1)
    
  elif action == POWER_ON:
    sock.write("1\r")
    do_power_on(sock)
    backout(sock) # Return to control screen
    statusval = do_status_check(sock)
    if statusval == ON:
      if verbose:
        logit("Power On successful\n")
      print "Power On successful"
      backout(sock)
      sock.write("4\r")  # logs out
      sock.close()
      sys.exit(0)
    else:
      if verbose:
        logit("Power On unsuccessful\n")
        logit("Undetermined error\n")
      sys.stderr.write("Power On unsuccessful")
      backout(sock)
      sock.write("4\r")  # Logs out
      sock.close()
      sys.exit(1)

  elif action == POWER_REBOOT:
    sock.write("1\r")
    do_power_off(sock)
    backout(sock) # Return to control screen
    statusval = do_status_check(sock)
    if statusval == OFF:
      if verbose:
        logit("Power Off successful\n")
      print "Power Off successful"
      backout(sock)
    else:
      if verbose:
        logit("Power Off unsuccessful\n")
        logit("Undetermined error\n")
      sys.stderr.write("Power Off unsuccessful")
      backout(sock)
      sock.write("4\r")  # Logs out
      sock.close()
      sys.exit(1)
    do_power_on(sock)
    backout(sock) # Return to control screen
    statusval = do_status_check(sock)
    if statusval == ON:
      if verbose:
        logit("Power Reboot successful\n")
      print "Power Reboot successful"
      backout(sock)
      sock.write("4\r")  # Logs out
      sock.close()
      sys.exit(0)
    else:
      if verbose:
        logit("Power Reboot unsuccessful\n")
        logit("Undetermined error\n")
      sys.stderr.write("Power Reboot unsuccessful")
      backout(sock)
      sock.write("4\r")  # Logs out
      sock.close()
      sys.exit(1)
    
  sock.close()

def backout(sock):
  sock.write(chr(27))
  
  while (1):
    i, mo, txt = sock.expect(regex_list, TELNET_TIMEOUT)

    if regex_list[i] == SCREEN_END:
      break
    elif regex_list[i] == SCREEN_END_2:
      sock.write(chr(27))

def setup_socket():
  ## Time to open telnet session and log in. 
  try:
    sock = Telnet(address.strip())
  except socket.error, (errno, msg):
    my_msg = "FENCE: A problem was encountered opening a telnet session with " + address
    if verbose:
      logit(my_msg)
      logit("FENCE: Error number: %d -- Message: %s\n" % (errno, msg))
      logit("Firewall issue? Correct address?\n")

    sys.stderr.write(my_msg)
    sys.stderr.write(("FENCE: Error number: %d -- Message: %s\n" % (errno, msg)))
    sys.stderr.write("Firewall issue? Correct address?\n")
    sys.exit(1)

  if verbose:
    logit("\nsocket open to %s\n" % address)

  return sock

def setup_logging( log_location="/tmp/apclog"):
  global logfile
  try:
    logfile = open(log_location, 'a')
    logfile.write("###############################################\n")
    logfile.write("Telnetting to apc switch %s\n" % address)
    now = time.localtime(time.time())
    logfile.write(time.asctime(now))
  except IOError, e:
    sys.stderr.write("Failed to open log file %s" % log_location)
    logfile = None

def logit(instr):
  if logfile != None:
    logfile.write(instr)

def do_login(sock):
  result_code = 1

  ## This loop tries to assemble complete telnet screens and passes
  ## them to helper methods to handle responses accordingly.
  while result_code:
    try:
      i, mo, txt = sock.expect(regex_list, TELNET_TIMEOUT)
    except socket.error, (errno, msg):
      my_msg = "FENCE: A problem was encountered opening a telnet session with " + address + "\n"
      if verbose:
        logit(my_msg)
        logit("FENCE: Error number: %d -- Message: %s\n" % (errno, msg))

      sys.stderr.write(my_msg)
      sys.stderr.write(("FENCE: Error number: %d -- Message: %s\n" % (errno, msg)))
      sys.exit(1)

    if i == CONTINUE_INDEX: # Capture the rest of the screen...
      sock.write("\r")
      ii,moo,txtt = sock.expect(regex_list, TELNET_TIMEOUT)
      txt = txt + txtt

    ndbuf = sock.read_eager() # Scoop up remainder
    if verbose:
      logit(txt + ndbuf)
    result_code,response = log_in(txt + ndbuf)
    if result_code:
      try:
        sock.write(response)
      except socket.error, (errno, msg):
        if verbose:
          logit("Error #%s" % errno)
          logit(msg)
        sys.stderr.write("Error #%s:  %s" % (errno,msg))
        sys.exit(1)

def log_in(buffer):
  global FIRMWARE_REV
  lines = buffer.splitlines()

  for i in lines:
    if i.find(USERNAME) != (-1):
      if verbose:
        logit("Sending login: %s\n" % login)
      return (NOT_COMPLETE, login + "\r")
    elif i.find(PASSWORD) != (-1):
      if verbose:
        logit("Sending password: %s\n" % passwd)
      return (NOT_COMPLETE, passwd + "\r")
    elif i.find(CONTROL_CONSOLE) != (-1):
      #while we are here, grab the firmware revision
      rev_search_lines = buffer.splitlines()
      for rev_search_line in rev_search_lines: #search screen again
        rev_dex = rev_search_line.find(FIRMWARE_STR)
        if rev_dex != (-1): #found revision line
          scratch_rev = rev_search_line[rev_dex:]
          v_dex = scratch_rev.find("v")
          if v_dex != (-1):
            if scratch_rev[v_dex + 1] == "3": #format is v3.3.4
              FIRMWARE_REV = 3
              break
      return (COMPLETE, "1\r") 

def do_status_check(sock):
  result_code = 1
  while result_code:
    i, mo, txt = sock.expect(regex_list, TELNET_TIMEOUT)
    if i == CONTINUE_INDEX: # Capture the rest of the screen...
      sock.write("\r")
      ii,moo,txtt = sock.expect(regex_list, TELNET_TIMEOUT)
      txt = txt + txtt

    ndbuf = sock.read_eager() # Scoop up remainder
    if verbose:
      logit(txt + ndbuf)
    (result_code,response,statusval) = return_status(txt + ndbuf)
    if result_code:
      try:
        sock.write(response)
      except socket.error, (errno, msg):
        if verbose:
          logit("Status check failed.")
          logit("Error #%s" % errno)
          logit(msg)
        sys.stderr.write("Status check failed.")
        sys.stderr.write("Error #%s:  %s" % (errno,msg))
        sys.exit(1)
  # Back from status check - value should be in status var
  if response == SUCCESS:
    if switchnum == "":
      if verbose:
        logit("Status check successful. Port %s is %s" % (port,statusval))
      print "Status check successful. Port %s is %s" % (port,statusval)
    else:
      if verbose:
        logit("Status check successful. Port %s:%s is %s" % (switchnum, port, statusval))
      print "Status check successful. Port %s:%s is %s" % (switchnum, port, statusval)

    return statusval
  else:
    if verbose:
      logit("Status check failed, unknown reason.")
    sys.stderr.write("Status check failed, unknown reason.\n")
    sock.close()
    sys.exit(1) 

def return_status(buffer):
  global switchnum, port

  lines = buffer.splitlines()

  for i in lines:
    if i.find(CONTROL_CONSOLE) != (-1):
      return (NOT_COMPLETE, "1\r", "Status Unknown")
    elif i.find(DEVICE_MANAGER) != (-1):
      if switchnum != "":
        res = switchnum + "\r"
      else:
        if FIRMWARE_REV == 2:
          res = "3\r"
        elif FIRMWARE_REV == 3:
          res = "2\r1\r"
        else: #placeholder for future revisions 
          res = "3\r"
      return (NOT_COMPLETE, res, "Status Unknown")
    elif i.find(OUTLET_CONTROL) != (-1):
      ls = buffer.splitlines()
      portval = port.strip()
      portval = " " + portval + " "
      portval2 = " " + port.strip() + "- "
      found_portval = False
      for l in ls:
        if l.find(portval) != (-1) or l.find(portval2) != (-1):
          found_portval = True
          linesplit = l.split()
          linelen = len(linesplit)
          return (COMPLETE,SUCCESS,linesplit[linelen - 1])
    elif i.find(MASTER) != (-1):
      try:
        e = int(port.strip())
        portval = port.strip()
        switchval = switchnum.strip()
        portval = switchval + ":" + portval
      except ValueError, e:
        portval = port.strip()
      ls = buffer.splitlines()
      found_portval = False
      for l in ls:
        words = l.split()
        if len(words) > 3:
          if words[2] == portval or words[3] == portval:
            found_portval = True
            linesplit = l.split()
            linelen = len(linesplit)
            return (COMPLETE, SUCCESS, linesplit[linelen - 3])
      return (COMPLETE, FAIL, "Incorrect port number")
  return (NOT_COMPLETE, chr(27), "Status Unknown")

def do_power_switch(sock, status):
  result_code = 1

  while result_code:
    i, mo, txt = sock.expect(regex_list, TELNET_TIMEOUT)
    if i == CONTINUE_INDEX: # Capture the rest of the screen...
      sock.write("\r")
      ii,moo,txtt = sock.expect(regex_list, TELNET_TIMEOUT)
      txt = txt + txtt

    ndbuf = sock.read_eager() # Scoop up remainder
    if verbose:
      logit(txt + ndbuf)

    if status == "off":
      result_code, response = power_off(txt + ndbuf)
    elif status == "on":
      result_code, response = power_on(txt + ndbuf)
    else:
      if verbose:
        logit("Invalid status in do_power_switch() function")
      sys.stderr.write("Invalid status in do_power_switch() function") 
      sys.exit(1)

    if result_code:
      try:
        sock.write(response)
      except socket.error, (errno, msg):
        if verbose:
          logit("Error #%s" % errno)
          logit(msg)
        sys.stderr.write("Error #%s:  %s" % (errno,msg))
        sys.exit(1)
      # FIXME: always returns COMPLETE (0)
    else:
      try:
        sock.write(response)
      except socket.error, (errno, msg):
        if verbose:
          logit("Error #%s" % errno)
          logit(msg)
        sys.stderr.write("Error #%s:  %s" % (errno,msg))
        sys.exit(1)
      return COMPLETE


def power_switch(buffer, escape, control_outlet, control_outlet2):
  # If port is not aliased, then outlet control screen will have the word
  # 'Outlet' in the header. If the name is aliased, it will only have the 
  # alias in the header.

  outlet_search_str1 = "Outlet " + port.strip() + " ------------"
  outlet_search_str2 = port.strip() + " ------------"
  outlet_search_str3 = "Outlet " + switchnum.strip() + ":" + port.strip() + " ------"
  outlet_search_str4 = "        Outlet       : " + port.strip()
  outlet_search_str5 = "        Outlet Name : " + port.strip()
  master_search_str1 = "-------- Master"
  lines = buffer.splitlines()

  for i in lines:
    if i.find(CONTROL_CONSOLE) != (-1):
      return (NOT_COMPLETE,"1\r")

    elif i.find(DEVICE_MANAGER) != (-1):
      if switchnum != "":
        res = switchnum + "\r"
      else:
        if FIRMWARE_REV == 2:
          res = "3\r"
        elif FIRMWARE_REV == 3:
          res = "2\r1\r"
        else: #placeholder for future revisions - sheesh
          res = "3\r"
      return (NOT_COMPLETE, res)
      
    elif (i.find(master_search_str1) != (-1)):
      return (NOT_COMPLETE, port.strip() + "\r")
      
    elif i.find(outlet_search_str1) != (-1) and (switchnum == ""):
      return (NOT_COMPLETE,"1\r")

    elif i.find(outlet_search_str2) != (-1) and (switchnum == ""):
      return (NOT_COMPLETE,"1\r")
    
    elif i.find(outlet_search_str3) != (-1):
      return (NOT_COMPLETE, "1\r")
    
    elif i == outlet_search_str4:
      return (NOT_COMPLETE, "1\r")
    
    elif i == outlet_search_str5:
      return (NOT_COMPLETE, "1\r")
    
    elif i.find(OUTLET_MANAGE) != (-1):
      #return (NOT_COMPLETE, "1\r")
      return (NOT_COMPLETE, "\r")

    #elif i.find(OUTLET_CONTROL) != (-1) or i.find(OUTLET_MANAGE) != (-1):
    elif i.find(OUTLET_CONTROL) != (-1):
      ls = buffer.splitlines()
      portval = port.strip()
      portval = " " + portval + " "
      found_portval = False
      i = 0
      # look for aliased name 
      for l in ls:
        i = i + 1
        if l.find(portval) != (-1):
          found_portval = True
          linesplit = l.split()
          outlet_str = linesplit[0]
          dex = outlet_str.find("-")
          if dex <= (0):
            if verbose:
              logit("Problem identifying outlet\n")
              logit("Looking for %s in string %s\n" % (portval,outlet_str))
            sys.stderr.write("Problem identifying outlet\n")
            sys.stderr.write("Looking for %s in string %s\n" % (portval,outlet_str))
            sys.exit(1)
          normalized_outlet_str = outlet_str[:dex]
          return (NOT_COMPLETE, normalized_outlet_str + "\r")
      # look for portnum
      portval = " " + port.strip() + "-"
      i = 0
      for l in ls:
        i = i + 1
        if l.find(portval) != (-1):
          found_portval = True
          linesplit = l.split()
          outlet_str = linesplit[0]
          dex = outlet_str.find("-")
          if dex <= (0):
            if verbose:
              logit("Problem identifying outlet\n")
              logit("Looking for %s in string %s\n" % (portval,outlet_str))
            sys.stderr.write("Problem identifying outlet\n")
            sys.stderr.write("Looking for %s in string %s\n" % (portval,outlet_str))
            sys.exit(1)
          normalized_outlet_str = outlet_str[:dex]
          return (NOT_COMPLETE, normalized_outlet_str + "\r")
      if found_portval == False:
        if verbose:
          logit("Problem identifying outlet\n")
          logit("Looking for '%s' in string '%s'\n" % (portval, ls))
        sys.stderr.write("Problem identifying outlet\n")
        sys.stderr.write("Looking for '%s' in string '%s'\n" % (portval, ls))
        sys.exit(1)

    elif i.find(MASTER) != (-1):
      ls = buffer.splitlines()
      found_portval = False
      # look for aliased name
      portval = port.strip()
      for l in ls:
        words = l.strip().split()
        if len(words) > 3:
          if '----' not in words[0] and words[3].strip() == portval:
            outlet_str = words[0]
            dex = outlet_str.find("-")
            if dex <= (0):
              if verbose:
                logit("Problem identifying outlet\n")
                logit("Looking for %s in string %s\n" % (portval, outlet_str))
              sys.stderr.write("Problem identifying outlet\n")
              sys.stderr.write("Looking for %s in string %s\n" % (portval, outlet_str))
              sys.exit(1)
            normalized_outlet_str = outlet_str[:dex]
            return (NOT_COMPLETE, (normalized_outlet_str + "\r"))
      # look for portnum
      portval = port.strip()
      portval = switchnum.strip() + ":" + portval + " "
      i = 0
      for l in ls:
        i = i + 1
        if l.find(portval) != (-1):
          found_portval = True
          linesplit = l.split()
          outlet_str = linesplit[0]
          dex = outlet_str.find("-")
          if dex <= (0):
            if verbose:
              logit("Problem identifying outlet\n")
              logit("Looking for %s in string %s\n" % (portval,outlet_str))
            sys.stderr.write("Problem identifying outlet\n")
            sys.stderr.write("Looking for %s in string %s\n" % (portval,outlet_str))
            sys.exit(1)
          normalized_outlet_str = outlet_str[:dex]
          return (NOT_COMPLETE, (normalized_outlet_str + "\r"))
      if found_portval == False:
        if verbose:
          logit("Problem identifying outlet\n")
          logit("Looking for '%s' in string '%s'\n" % (portval, ls))
        sys.stderr.write("Problem identifying outlet\n")
        sys.stderr.write("Looking for '%s' in string '%s'\n" % (portval, ls))
        sys.exit(1)

    elif i.find(CONFIRM) != (-1):
      return (NOT_COMPLETE,"YES\r")

    elif i.find(COMMAND_SUCCESS) != (-1):
      return (COMPLETE,"\r")

    elif i.find(COMMAND_SUCCESS_2) != (-1):
      return (COMPLETE,"\r")

    elif i.find(CONTROL_OUTLET) != (-1):
      return (NOT_COMPLETE, control_outlet + "\r")

    elif i.find(CONTROL_OUTLET_2) != (-1):
      return (NOT_COMPLETE, control_outlet2 + "\r")
  
  if (escape == True):
    return (NOT_COMPLETE, chr(27))
  else:
    raise "unknown screen encountered in \n" + str(lines) + "\n"

def do_power_off(sock):
  x = do_power_switch(sock, "off")
  return x

def power_off(buffer):
  x = power_switch(buffer, False, "2", "3");
  return x

def do_power_on(sock):
  x = do_power_switch(sock, "on")
  return x

def power_on(buffer):
  x = power_switch(buffer, True, "1", "1");
  return x

if __name__ == "__main__":
  main()
