import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
from pexpect import *
import os, sys, commands
from optparse import OptionParser
##exit codes
SPAWNED_BASE_CODE = 100 #exit codes by spawned ssh will be added to 100
MAIN_ERROR = 1 #main program error
TIME_OUT_ERROR = 2 #ssh timeout
SSH_CON_ERROR = 3 #ssh conn error
PASS_ERROR = 4 #ssh pass error
UNKNOWN_ERROR = 5 #ssh unknwon error
#parse options
usage = "pscp [user@]host:srcpath [...] dstpath password\n pscp srcpath [...] [user@]host:destpath password"
parser = OptionParser(usage)
parser.add_option("-t", "--timeout",
type="int", dest="timeout",
help="When execute time exceeds TIMEOUT, force to exit, default value is infinite.")
parser.add_option("-e", "--encrypt-password", action="store_true", dest="encrypt",
help="Use this command with a encrypted password, for DMS only."
)
options, args = parser.parse_args()
if len(args) < 3:
print parser.format_help()
sys.exit(MAIN_ERROR)
scparg = ""
for arg in args[0:-1]:
scparg += " " + arg
timeout = None
if options.timeout:
timeout = options.timeout
password = args[-1]
#find out host
host = ""
for x in args:
splits = x.split(':')
if len(splits) > 1:
host = splits[0]
break
encrypt = False
if options.encrypt:
encrypt = options.encrypt
password = password
#expect keys
keys = [ 'authenticity',
'assword:',
TIMEOUT,
EOF,
'pssh_exit',#a little chance, ssh don't echo EOF, while remote cmd exiting.
'@@@@@@@@@@@@@@@@@@@@' #key failed
]
def clear_ssh_key():
hostname = host.split('@')[-1]
keyfile = os.environ['HOME'] + "/.ssh/known_hosts"
tmpfile = os.environ['HOME'] + "/.ssh/known_hosts.tmp"
cmd = "sed '/%s/d' %s > %s; mv %s %s" % (hostname, keyfile, tmpfile, tmpfile, keyfile)
os.system(cmd)
clear_ssh_key()
#build command to spawn
#when build command as scp -r %s; echo $?pssh_exit,
#it doesn't work, so create a wrapper script.
#a litte dirty but work.
scp_wrapper = '/root/scp_echo'
command = "%s -r %s" % (scp_wrapper, scparg)
#spawn it
try:
child = spawn(command, [], timeout)
except Exception, inst:
print inst
sys.exit(MAIN_ERROR)
index = child.expect(keys)
##ssh key failed
if index == 5 or index == 3 :
clear_ssh_key()
child.close()
#respawn it
try:
child = spawn(command, [], timeout)
except Exception, inst:
print inst
sys.exit(MAIN_ERROR)
index = child.expect(keys)
#ssh connect failed
if index == 5 or index == 3:
print child.before.strip()
sys.exit(SSH_CON_ERROR)
#new connection need authenticity
if index == 0:
child.sendline('yes')
index = child.expect(keys)
#got 'assword:', and send it.
if index == 1:
child.sendline(password)
index = child.expect(keys)
#got 'TIMEOUT'
if index == 2:
print 'run command timeout.'
child.close()
sys.exit(TIME_OUT_ERROR)
#got 'assword'
elif index == 1:
print 'wrong password.'
sys.exit(PASS_ERROR)
#complete
elif index == 4:
output = child.before.strip()
output = output.replace('\r','')
exitval = output.split('\n')[-1]
s = output.split('\n')[0:-1]
for line in s:
print line
sys.exit(int(exitval) + SPAWNED_BASE_CODE) #exit value what command exit
#Unknown
print 'unknown error'
sys.exit(UNKNOWN_ERROR)