package org.fnppl.opensdx.file_transfer.trigger; /* * Copyright (C) 2010-2015 * fine people e.V. <opensdx@fnppl.org> * Henning Thieß <ht@fnppl.org> * * http://fnppl.org */ /* * Software license * * As far as this file or parts of this file is/are software, rather than documentation, this software-license applies / shall be applied. * * This file is part of openSDX * openSDX is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * openSDX is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * and GNU General Public License along with openSDX. * If not, see <http://www.gnu.org/licenses/>. * */ /* * Documentation license * * As far as this file or parts of this file is/are documentation, rather than software, this documentation-license applies / shall be applied. * * This file is part of openSDX. * Permission is granted to copy, distribute and/or modify this document * under the terms of the GNU Free Documentation License, Version 1.3 * or any later version published by the Free Software Foundation; * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. * A copy of the license is included in the section entitled "GNU * Free Documentation License" resp. in the file called "FDL.txt". * */ import java.io.BufferedReader; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; import java.util.HashMap; import java.util.Vector; import java.util.Map.Entry; import org.fnppl.opensdx.security.SecurityHelper; import org.fnppl.opensdx.xml.Element; public class SystemExecCall implements FunctionCall { private String[] cmdArray = null; private String[] envp = null; //TODO implement if needed private File dir = null; private boolean sysout = true; private File outputFile = null; private boolean appendToOutputFile = true; private HashMap<Integer,String> placeHolder = new HashMap<Integer, String>(); // <system_exec_call> // <command>ls</command> <!-- direct command (does not resolve wildcards), arguments as param --> // <param>-All</param> // <pwd>~/workspace</pwd> // <sysout>true</sysout> <!-- true (default if not output_file) / false --> // <output_file append="false">/tmp/osdx_outputs.txt</output_file> <!-- optional output to file, default: append = true --> // </system_exec_call> // // <system_exec_call> // <bash>ls -All *.xml</bash> <!-- run with bash (resolves wildcards) --> // <output_file append="false">/tmp/osdx_bash_outputs.txt</output_file> <!-- default: append = true --> // </system_exec_call> private SystemExecCall() { } public static SystemExecCall fromElemet(Element e) { SystemExecCall c = new SystemExecCall(); String bash = e.getChildText("bash"); if (bash!=null) { //bash command c.cmdArray = new String[] {"/bin/bash","-c",bash}; } else { //direct command Vector<Element> params = e.getChildren("param"); int pCount = 0; if (params!=null) { pCount = params.size(); } c.cmdArray = new String[pCount+1]; c.cmdArray[0] = e.getChildText("command"); for (int i=0;i<pCount;i++) { Element ep = params.get(i); String pUse = ep.getAttribute("use"); if (pUse!=null) { c.placeHolder.put(i+1, pUse); c.cmdArray[i+1] = "${"+pUse+"}"; } else { c.cmdArray[i+1] = ep.getText(); } } } //pwd String pwd = e.getChildText("pwd"); if (pwd!=null) { if (pwd.startsWith("~/")) { pwd = System.getProperty("user.home")+pwd.substring(1); } c.dir = new File(pwd); try { System.out.println("pwd: "+c.dir.getCanonicalPath()); } catch (IOException e1) { e1.printStackTrace(); } if (!c.dir.exists() || !c.dir.isDirectory()) { c.dir = null; } } //output String ssysout = e.getChildText("sysout"); Element eOutfile = e.getChild("output_file"); if (eOutfile!=null) { c.outputFile = new File(eOutfile.getText()); try { System.out.println(c.outputFile.getCanonicalPath()); } catch (IOException e1) { e1.printStackTrace(); } String app = eOutfile.getAttribute("append"); if (app!=null) { c.appendToOutputFile = Boolean.parseBoolean(app); } if (ssysout==null) { c.sysout = false; } else { c.sysout = Boolean.parseBoolean(ssysout); } } else { if (ssysout!=null) { c.sysout = Boolean.parseBoolean(ssysout); } } return c; } public void run(boolean async, HashMap<String, Object> context) { //TODO replace cmdArray with context values String[] myCmdArray = prepareCommands(context); if (myCmdArray!=null) { makeSystemExecCall(myCmdArray, envp, dir, async, sysout, outputFile, appendToOutputFile); } } private String[] prepareCommands(HashMap<String, Object> context) { if (placeHolder.isEmpty()) return cmdArray; String[] myCmdArray = new String[cmdArray.length]; for (int i=0;i<cmdArray.length;i++) { myCmdArray[i] = cmdArray[i]; } for (Entry<Integer, String> e : placeHolder.entrySet()) { int i = e.getKey().intValue(); String contextKey = e.getValue(); Object value = context.get(contextKey); if (value==null) { System.out.println("ERROR in API CALL :: MISSING CONTEXT VARIABLE: "+contextKey); return null; } if (value instanceof File) { myCmdArray[i] = ((File)value).getAbsolutePath(); } else if (value instanceof Long) { myCmdArray[i] = SecurityHelper.getFormattedDate(((Long)value).longValue()); } else { myCmdArray[i] = value.toString(); } } return myCmdArray; } public void makeSystemExecCall(String[] cmdArray, String[] envp, File dir, boolean async, final boolean sysout, final File outputFile, final boolean appendToOutputFile) { try { final Process p = Runtime.getRuntime().exec(cmdArray, envp, dir); if (outputFile!=null || sysout) { Thread t = new Thread() { public void run() { BufferedReader read = new BufferedReader(new InputStreamReader(p.getInputStream())); FileWriter writer = null; try { if (outputFile!=null) { writer = new FileWriter(outputFile, appendToOutputFile); } } catch (Exception ex) { System.out.println("Error opening file: "+outputFile.getAbsolutePath()+" for writing"); } String line = null; try { while ((line = read.readLine())!=null) { if (sysout) { System.out.println("> "+line); } try { if (writer!=null) { writer.append(line); writer.append("\n"); } } catch (Exception ex) { System.out.println("Error writing to file: "+outputFile.getAbsolutePath()); } } } catch (IOException ex) { ex.printStackTrace(); } try { if (writer!=null) { writer.close(); } } catch (Exception ex) { System.out.println("Error closing file: "+outputFile.getAbsolutePath()); } } }; t.start(); } if (!async) { int r = p.waitFor(); } } catch(Exception ex) { ex.printStackTrace(); } } public String toString() { return "pwd: "+dir+"\nSystem exec call: "+Arrays.toString(cmdArray); } }