import os
import os.path
import parser
import config
import readsetting
import ftp
import writemessage
import socket
import status
FTP_DISCONNECTED = 0
FTP_CONNECTED = 1
TEMP_FILE = "/tmp/temp_down_file"
class Comm:
SOCK_FILE='/tmp/.update.sock'
def __init__(self):
self.client_s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0)
self.client_s.connect(self.SOCK_FILE)
config.firmware_update_response_code_phrase='\'\''
def destroy(self):
if config.update_debug:print 'snmp pid = ', self.pid
import signal
def recv_packet(self):
try:
c = self.client_s.recv(1)
l = ord(c)
if config.update_debug:print 'l = ', l
msg = ''
while l > 0:
m = self.client_s.recv(l)
l -= len(m)
msg += m
return msg
except:
return ''
def send_packet(self, buf):
try:
import struct
p = struct.pack('B', len(buf))
self.client_s.send(p)
self.client_s.send(buf)
except:
pass
class DOWNLOAD:
def __init__(self):
if config.update_debug:print 'DOWNLOAD INIt'
self.lftp = ftp.LFTP()
self.parser = parser.PARSER()
self.writemessage = writemessage.WRITEMESSAGE()
self.readsetting = readsetting.READSETTING()
self.file_count = 0
def request(self):
self.readsetting.read_identity_record("config.cfg")
if config.update_debug:print self.readsetting.get_l5_protocol_used()
if (self.readsetting.get_l5_protocol_used() == "tftp"):
if config.update_debug:
print "Not supported"
else:
pass
elif (self.readsetting.get_l5_protocol_used() == "ftp"):
self.ftp_request()
elif (self.readsetting.get_l5_protocol_used() == "http"):
if config.update_debug:
print "Not supported"
else:
pass
else:
if config.update_debug:
print "l5 protocol is not decided"
else:
pass
def anal_update_response(self, filename):
f = file(filename, 'r')
for line in f:
self.parser.parser_firmware_update(line)
f.close()
def anal_config_response(self, filename):
f = file(filename, 'r')
for line in f:
self.parser.parser(line)
f.close()
# eicho add 06.05.03
def set_result_anal_config(self):
config.primary_dns_server = self.parser.get_configuration_value('primary_dns_server')
config.secondary_dns_server = self.parser.get_configuration_value('secondary_dns_server')
config.outbound_proxy_sip = self.parser.get_configuration_value('outbound_proxy_sip')
config.outbound_proxy_sip_fqdn = self.parser.get_configuration_value('outbound_proxy_sip_fqdn')
config.outbound_proxy_sip_port = self.parser.get_configuration_value('outbound_proxy_sip_port')
config.outbound_proxy_sip_address = self.parser.get_configuration_value('outbound_proxy_sip_address')
def write_tmp_dns(self):
if config.update_debug:
print 'DEBUG))) DOWNLOAD.write_tmp_dns() // write ADDR info to /tmp/send.acfg'
print 'DEBUG)))) write_tmp_dns in DOWNLOAD.py ==================='
print 'config.primary_dns_server = ', config.primary_dns_server
print 'config.secondary_dns_server = ', config.secondary_dns_server
print 'config.outbound_proxy_sip=', config.outbound_proxy_sip
print 'config.outbound_proxy_sip_fqdn =',config.outbound_proxy_sip_fqdn
print 'config.outbound_proxy_sip_port=',config.outbound_proxy_sip_port
print 'config.outbound_proxy_sip_address=',config.outbound_proxy_sip_address
self.sendfile = file("/tmp/send.acfg", 'w')
self.parser.write_dns_test_record(self.sendfile)
self.sendfile.flush()
self.sendfile.close()
# eicho end.
def check_downloaded_file(self):
pid = os.fork()
if pid:
pid,status = os.wait()
if config.update_debug: print pid, status
#change by elpis to correct wording mistake
# if status == 0:
# config.firmware_file_response_crc.append('\"OK\"')
# if config.update_debug:print "check ok"
# return 1
# else:
# if config.update_debug:print "check error"
# config.firmware_file_response_crc.append('\"FAIL\"')
# return 0
if status == 0:
# config.firmware_file_response_crc.append('\"ok\"') //changed by elpis 20061115
config.firmware_file_response_crc.append('\'ok\'')
if config.update_debug:print "check ok"
return 1
else:
if config.update_debug:print "check error"
# config.firmware_file_response_crc.append('\"error\"') //changed by elpis 20061115
config.firmware_file_response_crc.append('\'error\'')
return 0
else:
os.execl("/usr/local/bin/update-helper", "update-helper", "copy", "/tmp/temp_down_file")
def ftp_connect(self):
if config.update_debug:print 'ftp_connect'
if self.state == FTP_CONNECTED:
if config.update_debug: print "FTP Already Connected !!"
return 1
try:
user_id = config.user_id + "@" + config.device_id + "." + config.vendor_id
#by elpis, change ftp state
if (self.lftp.connection(config.ftpserver, user_id, "")):
if config.update_debug:print "ftp login : ", config.ftpserver, user_id
self.state = FTP_CONNECTED
else:
self.state = FTP_DISCONNECTED
except:
return 0
try:
self.lftp.settransfermode(1)
except:
if config.update_debug:print "Set PASV Error"
return 0
return 1
def ftp_information_request(self, comm):
if os.path.exists(config.firmware_update_request_file):
os.unlink(config.firmware_update_request_file)
if self.ftp_connect():
#information Request
downfile = config.hardware_version + '/' + config.firmware_version + '/' + config.firmware_update_request_file
config.firmware_update_request_arg = downfile
try:
#by elpis, add report feature in firmware update request
#print "elpis debug", self.lftp.getrequest(downfile, config.firmware_update_request_file)
response = self.lftp.getfile(downfile, config.firmware_update_request_file, comm)
config.firmware_update_response_code = int(response[:3])
config.firmware_update_response_code_phrase = "\'" + response[4:] + "\'"
if ((os.path.exists('/usr/local/update/updating')) and (config.firmware_update_response_code == 550)):
try:
self.state = FTP_DISCONNECTED
self.lftp.ftp.quit()
except:
self.state = FTP_DISCONNECTED
pass
return 2
if config.firmware_update_response_code != 226:
#just enter try and except by elpis
try:
self.writemessage.write_update_result()
self.lftp.putfile("ReportRequest.acfg")
if config.update_debug:print 'down file:',downfile
self.state = FTP_DISCONNECTED
self.lftp.ftp.close()
except:
try:
self.writemessage.write_update_result()
self.lftp.putfile("ReportRequest.acfg")
if config.update_debug:print 'down file:',downfile
self.state = FTP_DISCONNECTED
self.lftp.ftp.close()
except:
pass
return 0
# to report firmware_update_response_code and phrase
else:
out = file("inform.res", "w")
out .write("firmware_update_response_code=%d\n" % config.firmware_update_response_code)
out.write("firmware_update_response_code_phrase=%s\n" % config.firmware_update_response_code_phrase)
out.close()
except:
#by elpis, add report feature in firmware update request
#just enter try and except by elpis
import sys
type, value, tb = sys.exc_info()
response = str(value)
config.firmware_update_response_code = int(response[:3])
config.firmware_update_response_code_phrase = "\'" + response[4:] + "\'"
'''
if ((os.path.exists('/usr/local/update/updating')) and (config.firmware_update_response_code == 550)):
try:
self.state = FTP_DISCONNECTED
self.lftp.ftp.quit()
except:
self.state = FTP_DISCONNECTED
pass
return 1
'''
try:
self.writemessage.write_update_result()
self.lftp.putfile("ReportRequest.acfg")
if config.update_debug:print 'down file:',downfile
self.state = FTP_DISCONNECTED
self.lftp.ftp.close()
except:
try:
self.writemessage.write_update_result()
self.lftp.putfile("ReportRequest.acfg")
if config.update_debug:print 'down file:',downfile
self.state = FTP_DISCONNECTED
self.lftp.ftp.close()
except:
pass
return 0
try:
os.unlink(config.firmware_update_request_file)
except OSError:
pass
return 0
#end of Information Request
try:
self.state = FTP_DISCONNECTED
self.lftp.ftp.quit()
except:
self.state = FTP_DISCONNECTED
pass
return 1
else:
if config.update_debug:print "FTP Information Requst : Ftp Connection Fail"
#by elpis, add report feature in firmware update request
self.writemessage.write_update_result()
if self.ftp_connect():
#self.writemessage.write_update_result()
#just enter try and except by elpis
try:
self.lftp.putfile("ReportRequest.acfg")
self.state = FTP_DISCONNECTED
except:
self.state = FTP_DISCONNECTED
self.lftp.ftp.close()
pass
return 0
def ftp_check_firmware_information(self):
import os
try:
if os.path.exists("/tmp/filecheck"):
checkfile = file("/tmp/filecheck", "r")
for line in checkfile:
if line.startswith("firmwares_count"):
temp = line.split("=")
file_count = temp[1]
if line.startswith("firmwares_size"):
temp = line.split("=")
file_size = temp[1]
#elpis to add previous version
if line.startswith("previous_version"):
temp = line.split("=")
previous_version = temp[1].strip()
#end of elpis
if (self.file_count != int(file_count)) or (config.total_download_byte != int(file_size)):
return 0
elif (config.firmware_version != previous_version):
return 1
else:
return 2
else:
return 0
except:
if config.update_debug:print "ftp_check_firmware_information error"
return 0
def ftp_firmware_download_request(self, comm):
if config.update_debug:print 'ftp_firmware_download_request'
# after checking, download task is end, in that case firmware update response code and phrase is gone.
#by elpis 061124
try:
res = open("inform.res", 'r')
for line in res:
if line.startswith("firmware_update_response_code="):
config.firmware_update_response_code = int(line[len("firmware_update_response_code="):])
if line.startswith("firmware_update_response_code_phrase="):
config.firmware_update_response_code_phrase = line[len("firmware_update_response_code_phrase="):].strip()
res.close()
except:
pass
if self.ftp_connect():
try:
config.total_download_byte = 0
self.lftp.totalreceive = 0
index = 0
if config.update_debug:print 'config.download_files:',config.download_files
for file in config.download_files:
downfile = config.download_directory + '/' + file
#add error report when any file is not exist, by elpis 061124
#received_byte = self.lftp.ftp.size(downfile)
#in case of file is not exit, it report error by elpis
try:
received_byte = self.lftp.ftp.size(downfile)
except:
config.firmware_file_request_arg.append(downfile)
import sys
type, value, tb = sys.exc_info()
#return value
#self.lftp.parse_response_message(self.lftp.ftp.response)
self.lftp.parse_response_message(str(value))
#end changing
if config.update_debug:print 'download files are not exist'
#just enter try and except by elpis
try:
self.writemessage.write_update_result()
self.lftp.putfile("ReportRequest.acfg")
except:
pass
if config.update_debug:print 'down file:',downfile
try:
self.state = FTP_DISCONNECTED
self.lftp.ftp.quit()
except:
self.state = FTP_DISCONNECTED
pass
return 0;
#exclude the size of totalsize
if file.endswith(".tar") or file.endswith(".ta2") or file.endswith(".ta3") or file.endswith(".ta4"):
config.total_download_byte = config.total_download_byte + received_byte
self.file_count = self.file_count +1
comm.send_packet("total_file_size")
comm.send_packet(str(config.total_download_byte))
if config.update_debug:print "elpis:total", config.total_download_byte
for file in config.download_files:
downfile = config.download_directory + '/' + file
if config.update_debug:print downfile
config.firmware_file_request_arg.append(downfile)
try:
self.writemessage.write_update_result_temp()
if file.endswith(".tar") or file.endswith(".ta2") or file.endswith(".ta3") or file.endswith(".ta4"):
#to parse error message from ftplib by elpis
#self.lftp.parse_response_message(self.lftp.getfile(downfile, TEMP_FILE,comm))
response = self.lftp.getfile(downfile, TEMP_FILE,comm)
self.lftp.parse_response_message(response)
else:
#to parser error message from ftplib by elpis
#self.lftp.parse_response_message(self.lftp.getfile(downfile, "/tmp/filecheck",comm))
response = self.lftp.getfile(downfile, "/tmp/filecheck",comm)
self.lftp.parse_response_message(response)
if config.firmware_file_response_code[index] == '226':
if (downfile.endswith(".tar") or downfile.endswith(".ta2") or downfile.endswith(".ta3") or downfile.endswith(".ta4")):
if (self.check_downloaded_file() == 0):
#just enter try and except by elpis
try:
self.writemessage.write_update_result()
self.lftp.putfile("ReportRequest.acfg")
if config.update_debug:print 'down file:',downfile
except:
self.state = FTP_DISCONNECTED
self.lftp.ftp.close()
pass
return 0;
else:
# when receive New Document about this issue, must change it again.
# it is just temporary version for testing.
# config.firmware_file_response_crc.append('\"ok\"') //changed by elpis 20061115
config.firmware_file_response_crc.append('\'ok\'')
check = self.ftp_check_firmware_information()
if (check == 2): #everything is O.K
if config.update_debug:print "Firmware Total Count Size Check Is OK"
else:
#add report code when the file size and count are wrong, by elpis 061124
if (check == 0): #File Check Fail
if config.update_debug:print "Firmware Check Fail"
config.firmware_file_response_code[index] = '888'
config.firmware_file_response_crc[index] = '\'fail\''
config.firmware_update_response_phrase[index] = "\'wrong files\'"
else: #wrong version
if config.update_debug:print "Firmware Version Check Fail"
config.firmware_file_response_code[index] = '999'
# config.firmware_file_response_crc[index] = '\"fail\"' //changed by elpis 20061115
config.firmware_file_response_crc[index] = '\'fail\''
# config.firmware_update_response_phrase[index] = "\"wrong version\"" //changed by elpis 20061115
config.firmware_update_response_phrase[index] = "\'wrong version\'"
self.writemessage.write_update_result()
#just enter try and except by elpis
try:
self.lftp.putfile("ReportRequest.acfg")
except:
pass
if config.update_debug:print 'down file:',downfile
try:
self.state = FTP_DISCONNECTED
self.lftp.ftp.quit()
except:
self.state = FTP_DISCONNECTED
pass
return 0;
else:
#in case download fail
#add download fail report, by elpis 061124
self.writemessage.write_update_result()
try:
self.lftp.putfile("ReportRequest.acfg")
except:
pass
if config.update_debug:print 'down file:',downfile
try:
self.state = FTP_DISCONNECTED
self.lftp.ftp.quit()
except:
self.state = FTP_DISCONNECTED
pass
return 0
index = index + 1
except:
#to process error from ftp by elpis
import sys
type, value, tb = sys.exc_info()
#self.lftp.parse_response_message(self.lftp.ftp.response)
self.lftp.parse_response_message(str(value))
try:
self.state = FTP_DISCONNECTED
self.lftp.ftp.quit()
except:
self.state = FTP_DISCONNECTED
pass
self.writemessage.write_update_result()
if self.ftp_connect():
#self.writemessage.write_update_result()
if config.update_debug:print "ReportRequest.acfg"
try:
self.lftp.putfile("ReportRequest.acfg")
except:
pass
if config.update_debug:print 'down file:',downfile
try:
self.state = FTP_DISCONNECTED
self.lftp.ftp.quit()
except:
self.state = FTP_DISCONNECTED
pass
return 0
config.firmware_file_request_arg.append(downfile)
if config.update_debug:print config.firmware_file_request_arg
self.writemessage.write_update_result()
if config.update_debug:print "ReportRequest.acfg"
try:
self.lftp.putfile("ReportRequest.acfg")
except:
#added by elpis, to report the report upload fail
try:
self.state = FTP_DISCONNECTED
self.lftp.ftp.quit()
except:
self.state = FTP_DISCONNECTED
pass
return 0
#end of adding
if config.update_debug:print 'down file:',downfile
try:
self.state = FTP_DISCONNECTED
self.lftp.ftp.quit()
except:
self.state = FTP_DISCONNECTED
pass
except:
if config.update_debug:print "ftp_firmware_download_request Fail"
return 0
else:
if config.update_debug:print "FTP Firmware Download Request : FTP Connection Fail"
#by elpis, add report feature in firmware update request
self.writemessage.write_update_result()
if self.ftp_connect():
#self.writemessage.write_update_result()
try:
self.lftp.putfile("ReportRequest.acfg")
self.lftp.ftp.close()
except:
self.state = FTP_DISCONNECTED
pass
return 0
return 1
def ftp_configuration_request(self):
config.config_response_code = 0
#changed by elpis
#config.config_response_phrase = None
# config.config_response_phrase = "\"\"" //changed by elpis 20061115
config.config_response_phrase = "\'\'"
try:
self.state = FTP_DISCONNECTED
self.lftp.ftp.close()
except:
pass
if self.ftp_connect():
try:
# because of booting
downfile = config.hardware_version + '/' + config.firmware_version + '/' + config.configuration_request_file
if config.update_debug:print downfile
#to process error message from ftp by elpis
#self.lftp.parse_response_message(self.lftp.getrequest(downfile, config.configuration_request_file))
response = self.lftp.getrequest(downfile, config.configuration_request_file)
self.lftp.parse_response_message(response)
config.config_response_code = int(response[:3])
config.config_response_phrase = "\'" + response[4:] + "\'"
# eicho add 06.05.03
if(config.config_response_code == 226):
# read Configuration Information which is from SERVER
self.anal_config_response(config.configuration_request_file)
# set parsed information to this.config class (this.config class is different to original running config class)
self.set_result_anal_config()
# write 'dns-test-record: 'info to /tmp/send.acfg
self.write_tmp_dns()
return 1
else:
self.writemessage.write_config_error_request()
#self.writemessage.write_config_error_request()
try:
self.lftp.putfile("ReportRequest.acfg")
self.lftp.ftp.close()
except:
pass
self.state = FTP_DISCONNECTED
return 0
except:
if config.update_debug:print "ftp_configuration_request() Fail"
#added by elpis, to send configuration error message
self.writemessage.write_config_error_request()
try:
self.lftp.putfile("ReportRequest.acfg")
except:
pass
try:
self.state = FTP_DISCONNECTED
self.lftp.ftp.quit()
except:
self.state = FTP_DISCONNECTED
pass
return 0
else:
#added bye elpis, to send configuration error message
self.writemessage.write_config_error_request()
if self.ftp_connect():
#self.writemessage.write_config_error_request()
try:
self.lftp.putfile("ReportRequest.acfg")
self.lftp.ftp.close()
except:
pass
self.state = FTP_DISCONNECTED
#end
if config.update_debug:print "FTP Configuration Request : FTP Connectin Fail"
return 0
#make_update_response
def ftp_update_response(self):
if self.ftp_connect():
try:
self.readsetting.read_identity_record("config.cfg")
self.readsetting.read_dns_test_record()
config.config_request_arg = config.hardware_version + '/' + config.firmware_version + '/' + config.configuration_request_file
# eicho add debug:: 06.04.26
if config.update_debug:
print 'download::ftp_update_response() call self.writemessage.write_config_request()'
print 'download::ftp_update_response() they call parser.write_dns_test_record(f)'
self.writemessage.write_config_request()
try:
self.lftp.putfile("ReportRequest.acfg")
except:
pass
# configuration_request_file
try:
self.state = FTP_DISCONNECTED
self.lftp.ftp.quit()
except:
self.state = FTP_DISCONNECTED
pass
return 1
except:
if config.update_debug:print "ftp_update_response() Fail"
return 0
else:
if config.update_debug:print "FTP Update Response : FTP Connection Fail"
return 0
def ftp_install_dowloaded_file(self):
pid = os.fork()
if pid:
pid, status = os.wait()
if config.update_debug:print pid, status
if status == 0:
if config.update_debug:print "install success"
try:
os.unlink(config.firmware_update_request_file)
except OSError:
pass
return 1
else:
if config.update_debug:print "install error"
return 0
else:
os.execl("/usr/local/bin/update-helper", "update-helper", "install")
def versionCompare(self):
if config.update_debug:print 'config.firmware_version:',config.firmware_version,' config.firmware_version_available:',config.firmware_version_available
if config.firmware_version != config.firmware_version_available:
return 1
else:
return 0
def ftp_request(self):
if self.ftp_information_request():
self.anal_update_response(config.firmware_update_request_file)
else:
comm.send_packet("FAIL")
if config.update_debug:print "Information Request Fail"
return 0
if config.firmware_version != config.firmware_version_available:
self.ftp_firmware_download_request(comm)
self.ftp_install_dowloaded_file()
self.ftp_configuration_request()
self.ftp_update_response()
def run():
down = DOWNLOAD()
down.state = FTP_DISCONNECTED
down.readsetting.read_identity_record("/usr/local/lgvp/config.cfg")
if config.update_debug:print "download started"
comm.send_packet("connect")
while 1:
try:
receive = comm.recv_packet()
except:
break
if (receive == "firmware_update_request"):
if config.update_debug:print "Downloading firmware_update_request"
result = down.ftp_information_request(comm)
if (result == 1):
config.firmware_version_available = None
down.anal_update_response(config.firmware_update_request_file)
if config.firmware_version != config.firmware_version_available and config.firmware_version_available != None:
comm.send_packet("firmware_update_need")
else:
try:
os.unlink(config.firmware_update_request_file)
except OSError:
pass
comm.send_packet("firmware_update_not_needed")
elif result == 2:
comm.send_packet("firmware_update_not_needed")
else:
comm.send_packet("firmware_update_request_fail")
elif (receive == "firmware_download_request"):
try:
down.anal_update_response(config.firmware_update_request_file)
except:
if config.update_debug: print "FirmwareUpdateRequest.acfg is not exist!!"
if(down.ftp_firmware_download_request(comm)):
comm.send_packet("firmware_download_request_ok")
else:
comm.send_packet("firmware_download_request_fail")
#added by elpis, after download fail, must delete all download files
os.system("rm -f /usr/local/update/files/*")
elif (receive == "install_downloaded_files"):
print '### CHECK DOWNLOAD PRC. -- SHOULD REMOVE UPDATING'
os.system("touch /usr/local/update/updating")
#Roxia Begin smyook 06.06.23
'''
if(down.ftp_install_dowloaded_file()):
comm.send_packet("firmware_download_install_ok")
else:
comm.send_packet("firmware_download_install_fail")
'''
# eicho remove following.. 06.06.09
os.system("touch /usr/local/update/lock")
os.system("sync")
comm.send_packet("firmware_download_install_ok")
#Roxia End smyook
elif (receive == "configuration_download_request"):
#print 'eicho)))) Download:: def run() ==== configuration_download_request! ftp_configuration_request'
if (down.ftp_configuration_request()):
comm.send_packet("configuration_download_request_ok")
else:
comm.send_packet("configuration_download_request_fail")
elif (receive == "send_response"):
#print 'eicho)))) Download:: def run() ==== send_response! do ftp_update_response'
if(down.ftp_update_response()):
comm.send_packet("send_response_ok")
else:
comm.send_packet("send_response_fail")
elif (receive == "exit"):
if config.update_debug:print "exit"
elif (receive == "disconnect"):
if down.state == FTP_CONNECTED:
try:
down.state = FTP_DISCONNECTED
down.lftp.ftp.quit()
except:
down.state = FTP_DISCONNECTED
pass
if __name__ == '__main__':
comm = Comm()
run()