diff --git a/revpipyload/revpipyload.py b/revpipyload/revpipyload.py index a4627f8..35c18f4 100755 --- a/revpipyload/revpipyload.py +++ b/revpipyload/revpipyload.py @@ -15,7 +15,7 @@ import subprocess import tarfile import zipfile from concurrent import futures -from shutil import rmtree, copyfile +from shutil import rmtree from tempfile import mktemp from threading import Thread, Event from time import sleep, asctime @@ -224,7 +224,9 @@ class RevPiPlc(Thread): # Prozess beenden count = 0 proginit.logger.info("term plc program {}".format(self._program)) + # TODO: Prüfen ob es überhautp noch läuft + self._procplc.terminate() while self._procplc.poll() is None and count < 10: count += 1 @@ -293,18 +295,22 @@ class RevPiPyLoad(proginit.ProgInit): # Konfiguration verarbeiten self.autoreload = \ int(self.globalconfig["DEFAULT"].get("autoreload", 1)) - self.autostart = int(self.globalconfig["DEFAULT"].get("autostart", 0)) - self.plcprog = self.globalconfig["DEFAULT"].get("plcprogram", None) - self.plcworkdir = self.globalconfig["DEFAULT"].get( - "plcworkdir", "/var/lib/revpipyload") - self.plcslave = int(self.globalconfig["DEFAULT"].get("plcslave", 0)) - self.pythonver = int( - self.globalconfig["DEFAULT"].get("pythonversion", 3)) - self.xmlrpc = int(self.globalconfig["DEFAULT"].get("xmlrpc", 1)) - self.zerooneerror = int( - self.globalconfig["DEFAULT"].get("zeroonerror", 1)) - self.zeroonexit = int( - self.globalconfig["DEFAULT"].get("zeroonexit", 1)) + self.autostart = \ + int(self.globalconfig["DEFAULT"].get("autostart", 0)) + self.plcprog = \ + self.globalconfig["DEFAULT"].get("plcprogram", None) + self.plcworkdir = \ + self.globalconfig["DEFAULT"].get("plcworkdir","/var/lib/revpipyload") + self.plcslave = \ + int(self.globalconfig["DEFAULT"].get("plcslave", 0)) + self.pythonver = \ + int(self.globalconfig["DEFAULT"].get("pythonversion", 3)) + self.xmlrpc = \ + int(self.globalconfig["DEFAULT"].get("xmlrpc", 1)) + self.zerooneerror = \ + int(self.globalconfig["DEFAULT"].get("zeroonerror", 1)) + self.zeroonexit = \ + int(self.globalconfig["DEFAULT"].get("zeroonexit", 1)) # Workdirectory wechseln os.chdir(self.plcworkdir) @@ -332,8 +338,7 @@ class RevPiPyLoad(proginit.ProgInit): self.xsrv.register_function(self.xml_getconfig, "get_config") self.xsrv.register_function(self.xml_getfilelist, "get_filelist") - self.xsrv.register_function( - self.xml_getpictoryrsc, "get_pictoryrsc") + self.xsrv.register_function(self.xml_getpictoryrsc, "get_pictoryrsc") self.xsrv.register_function(self.xml_getprocimg, "get_procimg") self.xsrv.register_function(self.xml_plcdownload, "plcdownload") self.xsrv.register_function(self.xml_plcexitcode, "plcexitcode") @@ -341,12 +346,11 @@ class RevPiPyLoad(proginit.ProgInit): self.xsrv.register_function(self.xml_plcstart, "plcstart") self.xsrv.register_function(self.xml_plcstop, "plcstop") self.xsrv.register_function(self.xml_plcupload, "plcupload") - self.xsrv.register_function( - self.xml_plcuploadclean, "plcuploadclean") + self.xsrv.register_function(self.xml_plcuploadclean, "plcuploadclean") self.xsrv.register_function(self.xml_reload, "reload") self.xsrv.register_function(self.xml_setconfig, "set_config") - self.xsrv.register_function( - self.xml_setpictoryrsc, "set_pictoryrsc") + self.xsrv.register_function(self.xml_setpictoryrsc, "set_pictoryrsc") + self.xsrv.register_function(lambda: pyloadverion, "version") proginit.logger.debug("created xmlrpc server") @@ -391,7 +395,9 @@ class RevPiPyLoad(proginit.ProgInit): @param mode: Packart 'tar' oder 'zip' @param pictory: piCtory Konfiguration mit einpacken""" filename = mktemp(suffix=".packed", prefix="plc") + # TODO: Fehlerabfang + if mode == "zip": fh_pack = zipfile.ZipFile(filename, mode="w") wd = os.walk("./") @@ -492,7 +498,9 @@ class RevPiPyLoad(proginit.ProgInit): def xml_plcdownload(self, mode="tar", pictory=False): proginit.logger.debug("xmlrpc call plcdownload") + # TODO: Daten blockweise übertragen + file = self.packapp(mode, pictory) if os.path.exists(file): fh = open(file, "rb") @@ -535,13 +543,90 @@ class RevPiPyLoad(proginit.ProgInit): else: return -1 - def xml_plcupload(self, filedata, pictory=False, reset=False): + + + def modtarfile(self, fh_pack): + rootdir = [] + rootfile = [] + for ittar in fh_pack.getmembers(): + fname = ittar.name + + # Illegale Zeichen finden + if fname.find("/") == 0 or fname.find("..") >= 0: + return False + + # Führendes ./ entfernen + ittar.name = fname.replace("./", "") + + # root Elemente finden + if ittar.isdir() and fname.count("/") == 0: + if fname not in rootdir: + rootdir.append(fname + "/") + else: + rootfile.append(fname) + + # Prüfung fertig + if len(rootdir) == 1: + if len(rootfile) == 1 and len(rootfile[0]) > 4 \ + and rootfile[0][-4:].lower() == ".rsc": + + # Config.rsc gefunden + # TODO: config.rsc iwie übergeben + pass + + # Rootdir abschneiden + for ittar in fh_pack.getmembers(): + ittar.name = ittar.name.replace(rootdir[0], "") + proginit.logger.error(ittar.name) + + proginit.logger.error(rootdir) + return True + + def modzipfile(self, fh_pack): + # Datei untersuchen + rootdir = [] + rootfile = [] + for itzip in fh_pack.filelist: + fname = itzip.filename + + # Illegale Zeichen finden + if fname.find("/") == 0 or fname.find("..") >= 0: + return False + + # Führendes ./ entfernen + itzip.filename = fname.replace("./", "") + + # root Elemente finden + if fname.count("/") > 0: + rootname = fname[:fname.find("/") + 1] + if rootname not in rootdir: + rootdir.append(rootname) + else: + rootfile.append(fname) + + # Prüfung fertig + if len(rootdir) == 1 and len(rootfile) >= 1: + pass + + + + proginit.logger.error(rootdir) + return True + + + + + def xml_plcupload(self, filedata): proginit.logger.debug("xmlrpc call plcupload") + noerr = True + # TODO: Daten blockweise annehmen + if filedata is None: return False filename = mktemp(prefix="upl") + # Daten in tmp-file schreiben fh = open(filename, "wb") fh.write(filedata.data) @@ -551,37 +636,23 @@ class RevPiPyLoad(proginit.ProgInit): fh_pack = None if tarfile.is_tarfile(filename): fh_pack = tarfile.open(filename) + noerr = self.modtarfile(fh_pack) + elif zipfile.is_zipfile(filename): - fh_pack = zipfile.ZipFile.open(filename) + fh_pack = zipfile.ZipFile(filename) + noerr = self.modzipfile(fh_pack) + # Datei entpacken und schließen if fh_pack is not None: - fh_pack.extractall(".") + if noerr: + fh_pack.extractall("./") + fh_pack.close() - os.remove(filename) - if pictory and os.path.exists("./config.rsc"): - try: - # Nur Daten kopieren damit Eigenschaften gleich bleiben - copyfile("./config.rsc", configrsc) - os.remove("./config.rsc") - except: - return -3 - else: - if reset: - return os.system(picontrolreset) - else: - return 0 - - elif pictory: - return -2 - - else: - # Sauber - return 0 - - # Kein Archiv + # Tempdatei löschen os.remove(filename) - return -1 + + return noerr def xml_plcuploadclean(self): proginit.logger.debug("xmlrpc call plcuploadclean") @@ -633,6 +704,9 @@ class RevPiPyLoad(proginit.ProgInit): """ proginit.logger.debug("xmlrpc call setpictoryrsc") + + # TODO: Prüfen ob es wirklich eine piCtory Datei ist + try: with open(configrsc, "wb") as fh: fh.write(filebytes.data)