package run; import java.net.*; import java.io.*; /** *

Title: run a program from anywhere in the world

*

Description: java -jar run.jar [-clean] * or: run [-clean] * The program can be a jar file, a binary executable, a batch, a shell script.

* @author vpatryshev * @version 1.1 08/21/2006 (Enforced overwriting of previous version of the file it loads) * @version 1.2 09/19/2006 (Overwriting of previous version optional - based on timestamp) * */ public class Run { static final int BLOCK_SIZE = 256000; // bytes - should grow according t Moore law static byte[] buf = new byte[BLOCK_SIZE]; static final int SLEEP_UNIT = 333; // msec static final String TMP_DIR = "/tmp/runjar"; static private abstract class FileLoader { protected File loadFile(String urlString, URLConnection connection, File programFile) { if (programFile.exists()) { programFile.delete(); } if (programFile.exists()) { System.err.println("Could not delete file " + programFile); System.exit( -1); } try { InputStream is = new BufferedInputStream(connection.getInputStream()); OutputStream os = new BufferedOutputStream(new FileOutputStream(programFile)); pipe(is, os, true); os.close(); is.close(); } catch (Exception e) { System.err.println(urlString + ": " + e.getMessage()); System.exit(-1); } return programFile; } File getLocalFile(String urlString) { String filename = urlString.substring(urlString.lastIndexOf('/') + 1); return new File(filename); } File findFile(String urlString) { File programFile = getLocalFile(urlString); if (!programFile.exists()) { try { programFile = getTempFile(urlString); } catch (IOException e) { // Just ignore it, and load a new one. } } return programFile; } static File getTempFile(String urlString) throws IOException { String filename = urlString.substring(urlString.lastIndexOf('/') + 1); File here = new File("."); File root = new File(here.getAbsolutePath()); // is not it something? while (root.getParent() != null && root.getParent() != root.getCanonicalPath()) { root = new File(root.getParent()); // that's the way to find the root } File tmpdir = new File(root, TMP_DIR); if (!tmpdir.exists()) tmpdir.mkdirs(); return tmpdir.exists() ? new File(tmpdir, filename) : File.createTempFile("", filename, tmpdir); } public abstract File load(String urlString); }; static final FileLoader KEEP = new FileLoader() { public File load(String urlString) { File programFile = findFile(urlString); try { if (!programFile.exists()) { loadFile(urlString, new URL(urlString).openConnection(), programFile); } } catch (Exception e) { System.err.println(urlString + ": " + e.getMessage()); System.exit(-1); } return programFile; } }; static final FileLoader OVERWRITE = new FileLoader() { public File load(String urlString) { File programFile = getLocalFile(urlString); if (programFile.exists()) { programFile.delete(); } if (programFile.exists()) { try { programFile = getTempFile(urlString); } catch (Exception e) { System.err.println(urlString + ": " + e.getMessage()); System.exit(-1); } } try { loadFile(urlString, new URL(urlString).openConnection(), programFile); } catch (Exception e) { System.err.println(urlString + ": " + e.getMessage()); System.exit(-1); } return programFile; } }; static final FileLoader OVERWRITE_IF_NEWER = new FileLoader() { public File load(String urlString){ long localTime = 0L; File programFile = findFile(urlString); if (programFile.exists()) { localTime = programFile.lastModified(); } try { URLConnection connection = new URL(urlString).openConnection(); long remoteTime = connection.getHeaderFieldDate("Date", 0l); if (remoteTime > localTime) { programFile = loadFile(urlString, connection, programFile); } } catch (Exception e) { System.err.println(urlString + ": " + e.getMessage()); System.exit(-1); } return programFile; } } ; public static void main(String[] args) { try { FileLoader loader = KEEP; if (args.length > 0) { int argpos = 0; if (args[0].equals("-clean") || args[0].equals("-overwrite")) { argpos++; loader = OVERWRITE; } else if (args[0].equals("-newer")) { argpos++; loader = OVERWRITE_IF_NEWER; } else if (args[0].equals("-help")) { System.out.println("run.java (url) - downloads and executes a file\n" + " options:\n" + " -newer download only if the remote file is newer than the one on your machine\n" + " -overwrite download every time, overwriting the one you have."); } String urlString = args[argpos++]; // jar url string File programFile = loader.load(urlString); String cmd = getCommand(programFile) + programFile.getAbsolutePath(); for (int i = argpos; i < args.length; i++) { cmd += " \"" + args[i] + "\""; } File here = new File("."); Process process = Runtime.getRuntime().exec(cmd, null, here); int result = 0; for (boolean isRunning = true; isRunning;) { Thread.sleep(SLEEP_UNIT); try { result = process.exitValue(); isRunning = false; } catch (IllegalThreadStateException ie) {} try { pipe(System.in, process.getOutputStream(), false); pipe(process.getErrorStream(), System.err, false); pipe(process.getInputStream(), System.out, false); } catch(Exception e) {} } System.exit(result); } } catch (Exception e) { System.err.println(e); } } static void pipe(InputStream in, OutputStream out, boolean isBlocking) throws IOException { int nread; int navailable; while((navailable = isBlocking ? Integer.MAX_VALUE : in.available()) > 0 && (nread = in.read(buf, 0, Math.min(buf.length, navailable))) >= 0) { out.write(buf, 0, nread); } out.flush(); } static String getCommand(File programFile) { String name = programFile.getName(); String cmd = ""; if (name.endsWith(".jar")) { cmd = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java -jar "; } else if (name.endsWith(".bat")){ cmd = "cmd /c "; } else if (name.endsWith(".sh")){ cmd = "sh "; } else if (name.endsWith(".pl")){ cmd = "perl "; } else { byte[] buf = new byte[10]; try { String head = new String(buf, 0, (new FileInputStream(programFile)).read(buf)); if (head.equals("#!/bin/sh")) { cmd = "sh "; } else if (head.equals("#!/bin/sh")){ cmd = "perl "; } else if (head.startsWith("MZ")) { // it is .exe } } catch (IOException ex) {} } return cmd; } }