def marshal_params(self, logDir, archOs, output_filename=None, globalvars={}): import sys, subprocess, platform # Find/compute various paths and filename components we'll need later storageDir = globalvars['FbStorage'] timestamp = util.formattime() exeBaseName = os.path.basename(self.executable) # Get our own packaging options (for reference) arch_map = self.package_arches # Figure out which piece to use for marshaling host_archOs = "%s-%s" % (platform.machine(), platform.system()) proxy = arch_map[host_archOs][0] core = arch_map[archOs][1] # Non supported! if proxy is None: return (None, None) # Get files/paths set up for marshaling if output_filename is None: output_filename = os.path.join( logDir, "%s-%s-Marshal.bin" % (exeBaseName, timestamp)) output_path = os.path.dirname(output_filename) try: os.makedirs(output_path) except os.error: assert os.path.isdir( output_path ), "Output path '%s' could not be found/created!" % output_path xml_config_name = os.path.join( logDir, "%s-%s-InConfig.marshal.xml" % (exeBaseName, timestamp)) self.write_interpreted_xml_file(xml_config_name, globalvars=globalvars) # Fire off the DANE config utility to actually create the package. Note that this is strictly # Win32[/64] for now... # (This stuff should be abtracted away form cross-platformness and to avoid hard-coded paths.) proxy_dll = os.path.join(os.path.dirname(self.executable), proxy) assert os.path.isfile( proxy_dll), "Required file '%s' doesn't exist!" % proxy_dll self.io.print_msg("\tUsing '%s' to handle parameter marshaling" % proxy_dll) self.io.print_msg("\tMarshaling the contents of '%s'" % xml_config_name) config_exe = os.path.join(storageDir, 'dvmarshal.exe') assert os.path.isfile( config_exe), "Required program '%s' doesn't exist!" % config_exe subprocess.check_call( [config_exe, proxy_dll, xml_config_name, output_filename]) core_dll = os.path.join(os.path.dirname(self.executable), core) return (core_dll, output_filename)
def set_logdir(self, log_dir=None): """Set the current log directory and create a new log file""" if not log_dir: log_dir = os.path.normpath(self.default_logdir) base_dir = self.get_basedir() self.session.set_dirs(base_dir, log_dir) logname = "fuzzbunch-%s.log" % util.formattime() self.io.setlogfile(os.path.join(log_dir, logname))
def validate(self, dirs, globalvars={}): baseDir, logDir = dirs timestamp = util.formattime() exeBaseName = os.path.basename(self.executable) logName = "%s-%s.log" % (exeBaseName, timestamp) logFile = os.path.join(logDir, logName) try: os.remove(logFile) except: pass inConfName = "%s-%s-InConfig.validate.xml" % (exeBaseName, timestamp) inConfFile = os.path.join(logDir, inConfName) self.write_interpreted_xml_file(inConfFile, globalvars=globalvars) if edfexecution.validate_plugin(self.executable, inConfFile, self.io) == 0: return True else: return False
def execute(self, session, consolemode, interactive, scripted, globalvars={}, runMode=''): self.lastsession = session baseDir, logDir = session.get_dirs() waitmode, newconsole = self.get_runflags(consolemode, interactive, scripted) # save history session.history = self.getParameters() timestamp = util.formattime() exeBaseName = os.path.basename(self.executable) logName = "%s-%s.log" % (exeBaseName, timestamp) logFile = os.path.join(logDir, logName) try: os.remove(logFile) except: pass # Touch the logfile tmpFile = open(logFile, "w") tmpFile.close() # Create InConfig and write to the logdir inConfName = "%s-%s-InConfig.xml" % (exeBaseName, timestamp) inConfFile = os.path.join(logDir, inConfName) self.write_interpreted_xml_file(inConfFile, globalvars=globalvars) # Create the pipe that we will use for the --OutConfig parameter pipeName = edfexecution.generate_pipename() pipe = edfexecution.create_pipe(pipeName) cwd = os.getcwd() os.chdir(logDir) try: # # This is the sneaky bit for the output. We call launch_plugin, # which does two things. First, it passes stdin,stdout, and stderr # to the call to subprocess.Popen so that output is duplicated to # the console. Second, it passes --OutConfig a pipe so that, when we # later call write_outconfig, this contains only the data we want # proc = edfexecution.launch_plugin(self.executable, inConfFile, pipeName, logFile, self.io, newconsole) self.procs.append(proc) except KeyboardInterrupt: self.io.print_error("Stopping plugin") try: self.procs.remove(proc) proc.kill() except: pass # Create the output param for the contract session.contract = [ util.oParam("Status", "Failed", "String", "Scalar"), util.oParam("ReturnCode", "User Abort", "String", "Scalar") ] session.mark_fail() raise exception.CmdErr, "Canceled by User" os.chdir(cwd) try: # Wait for the spawned process to connect to our named pipe pipe = edfexecution.connect_pipe(pipe, pipeName) except edfexecution.PipeError, err: self.io.print_error(str(err)) pipe = None
def execute(self, session, consolemode, interactive, scripted, globalvars={}, runMode='', archOs='x86-Windows', listenPort=0): self.lastsession = session baseDir, logDir = session.get_dirs() waitmode, newconsole = self.get_runflags(consolemode, interactive, scripted) timestamp = util.formattime() # Save history session.history = self.getParameters() # Prompt for run mode if runMode in ("DANE", "DAVE"): # TODO: prompt operator to verify remote callback tunnel exists for localhost comms if runMode == "DANE": # Build package packagePath = self.build_package(logDir, archOs, listenPort, globalvars=globalvars) # Print package info self.io.print_success("DANE Package: %s" % packagePath) # elif runMode == "DAVE": # # Marshal params (and get core module name) # modulePath, inputPath = self.marshal_params(logDir, archOs, globalvars=globalvars) # # Build up DAVE commandline # dvcmds = 'daringveteran -module "%s" -input "%s" -run %s' % ( # modulePath, # inputPath, # 'interactive' if (listenPort) else 'batch') # if listenPort: # dvcmds += " -homeport %d" % listenPort # # Print core module and marshaled data info # self.io.print_success('DAVE Pastable:\n\t' + dvcmds) else: raise NotImplementedError( "No such option '%s'; what happened??" % (runMode)) # Set "DaveProxyPort" hidden parameter in current config if listenPort: #self.set("DaveProxyPort", str(listenPort)) self.io.print_msg("Proxy listening on localhost:%d" % listenPort) else: # Bail right now--gracefully... return newconsole, None elif runMode == 'FB': # Make sure the proxy port is zeroed self.set("DaveProxyPort", "0") else: raise NotImplementedError("No such option '%s'; what happened??" % (runMode)) exeBaseName = os.path.basename(self.executable) logName = "%s-%s.log" % (exeBaseName, timestamp) logFile = os.path.join(logDir, logName) try: os.remove(logFile) except: pass # Touch the logfile tmpFile = open(logFile, "w") tmpFile.close() # Create InConfig and write to the logdir inConfName = "%s-%s-InConfig.xml" % (exeBaseName, timestamp) inConfFile = os.path.join(logDir, inConfName) self.write_interpreted_xml_file(inConfFile, globalvars=globalvars) # Create the pipe that we will use for the --OutConfig parameter pipeName = edfexecution.generate_pipename() pipe = edfexecution.create_pipe(pipeName) cwd = os.getcwd() os.chdir(logDir) try: # # This is the sneaky bit for the output. We call launch_plugin, # which does two things. First, it passes stdin,stdout, and stderr # to the call to subprocess.Popen so that output is duplicated to # the console. Second, it passes --OutConfig a pipe so that, when we # later call write_outconfig, this contains only the data we want # proc = edfexecution.launch_plugin(self.executable, inConfFile, pipeName, logFile, self.io, newconsole) self.procs.append(proc) except KeyboardInterrupt: self.io.print_error("Stopping plugin") try: self.procs.remove(proc) proc.kill() except: pass # Create the output param for the contract session.contract = [ util.oParam("Status", "Failed", "String", "Scalar"), util.oParam("ReturnCode", "User Abort", "String", "Scalar") ] session.mark_fail() raise exception.CmdErr, "Canceled by User" os.chdir(cwd) try: # Wait for the spawned process to connect to our named pipe pipe = edfexecution.connect_pipe(pipe, pipeName) except edfexecution.PipeError, err: self.io.print_error(str(err)) pipe = None
def build_package(self, logDir, archOs, listenPort=None, output_filename=None, globalvars={}): import sys, subprocess, platform # Find/compute various paths and filename components we'll need later storageDir = globalvars['FbStorage'] timestamp = util.formattime() exeBaseName = os.path.basename(self.executable) # Get our own packaging options (for reference) arch_map = self.package_arches # Figure out which architecture/OS to use for each piece host_archOs = "%s-%s" % (platform.machine(), platform.system()) proxy = arch_map[host_archOs][0] core = arch_map[archOs][1] if (proxy is None) or (core is None): # Not supported! return None if output_filename is None: output_filename = os.path.join( logDir, "%s-%s-Package.dll" % (exeBaseName, timestamp)) output_path = os.path.dirname(output_filename) try: os.makedirs(output_path) except os.error: assert os.path.isdir( output_path ), "Output path '%s' could not be found/created!" % output_path xml_config_name = os.path.join( logDir, "%s-%s-InConfig.package.xml" % (exeBaseName, timestamp)) self.write_interpreted_xml_file(xml_config_name, globalvars=globalvars) # Fire off the DANE config utility to actually create the package. Note that this is strictly # Win32[/64] for now... # (This stuff should be abtracted away for cross-platformness and to avoid hard-coded paths.) baseArch = archOs.split('-')[0] dane_dll = os.path.join(storageDir, 'dane_%s.dll' % baseArch) assert os.path.isfile( dane_dll), "Required file '%s' doesn't exist!" % dane_dll self.io.print_msg("\tUsing '%s' as the output template" % dane_dll) proxy_dll = os.path.join(os.path.dirname(self.executable), proxy) assert os.path.isfile( proxy_dll), "Required file '%s' doesn't exist!" % proxy_dll self.io.print_msg("\tUsing '%s' to handle parameter marshaling" % proxy_dll) core_dll = os.path.join(os.path.dirname(self.executable), core) assert os.path.isfile( core_dll), "Required file '%s' doesn't exist!" % core_dll self.io.print_msg("\tUsing '%s' as the input payload" % core_dll) config_exe = os.path.join(storageDir, 'danecfg.exe') assert os.path.isfile( config_exe), "Required program '%s' doesn't exist!" % config_exe subprocess.check_call([ config_exe, dane_dll, proxy_dll, core_dll, xml_config_name, output_filename ]) if listenPort: # Pack in the listen-port as a particular binary resource import ctypes, struct RT_RCDATA = 10 ID_PORTNUM = 101 LANG_ID = 0x0000 BeginUpdateResource = ctypes.windll.kernel32.BeginUpdateResourceA UpdateResource = ctypes.windll.kernel32.UpdateResourceA EndUpdateResource = ctypes.windll.kernel32.EndUpdateResourceA rblob = struct.pack("<H", listenPort) handle = BeginUpdateResource(output_filename, False) if handle is None: raise ctypes.WinError() if not UpdateResource(handle, RT_RCDATA, ID_PORTNUM, LANG_ID, rblob, len(rblob)): raise ctypes.WinError() if not EndUpdateResource(handle, False): raise ctypes.WinError() return output_filename