package ij;

import ij.IJ;
import ij.ImageJ;
import ij.Prefs;

import ij.io.OpenDialog;
import ij.io.Opener;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import java.lang.reflect.Method;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import java.util.Properties;

/*
 * This class tries to contact another instance on the same machine, started
 * by the current user.  If such an instance is found, the arguments are
 * sent to that instance.  If no such an instance is found, listen for clients.
 *
 * No need for extra security, as the stub (and its serialization) contain
 * a hard-to-guess hash code.
 *
 *	@author Johannes Schindelin
 */
public class OtherInstance {
	private static final String DELIMETER = "~!~"; // Separates macro name and argument

	interface ImageJInstance extends Remote {
		void sendArgument(String arg) throws RemoteException;
	}

	static class Implementation implements ImageJInstance {
		int counter = 0;

		public void sendArgument(String cmd) {
			if (IJ.debugMode) IJ.log("SocketServer.sendArgument: \""+ cmd+"\"");
			if (cmd.startsWith("open "))
				(new Opener()).openAndAddToRecent(cmd.substring(5));
			else if (cmd.startsWith("macro ")) {
				String name = cmd.substring(6);
				String name2 = name;
				String arg = null;
				int index = name2.indexOf(DELIMETER);
				if (index!=-1) {
					name = name2.substring(0, index);
					arg = name2.substring(index+DELIMETER.length(), name2.length());
				}
				IJ.runMacroFile(name, arg);
			} else if (cmd.startsWith("run "))
				IJ.run(cmd.substring(4));
			else if (cmd.startsWith("eval ")) {
				String rtn = IJ.runMacro(cmd.substring(5));
				if (rtn!=null)
					System.out.print(rtn);
			} else if (cmd.startsWith("user.dir "))
				OpenDialog.setDefaultDirectory(cmd.substring(9));
		}
	}

	public static String getStubPath() {
		String display = System.getenv("DISPLAY");
		if (display!=null) {
			display = display.replace(':', '_');
			display = display.replace('/', '_');
		}
		String tmpDir = System.getProperty("java.io.tmpdir");
		if (!tmpDir.endsWith(File.separator))
			tmpDir = tmpDir + File.separator;

		return tmpDir + "ImageJ-"
			+ System.getProperty("user.name") + "-"
			+ (display == null ? "" : display + "-")
			+ ImageJ.getPort() + ".stub";
	}

	public static void makeFilePrivate(String path) {
		try {
			File file = new File(path);
			file.deleteOnExit();

			// File.setReadable() is Java 6
			Class[] types = { boolean.class, boolean.class };
			Method m = File.class.getMethod("setReadable", types);
			Object[] arguments = { Boolean.FALSE, Boolean.FALSE };
			m.invoke(file, arguments);
			arguments = new Object[] { Boolean.TRUE, Boolean.TRUE };
			m.invoke(file, arguments);
			types = new Class[] { boolean.class };
			m = File.class.getMethod("setWritable", types);
			arguments = new Object[] { Boolean.FALSE };
			m.invoke(file, arguments);
			return;
		} catch (Exception e) {
			if (IJ.debugMode)
				System.err.println("Java < 6 detected,"
					+ " trying chmod 0600 " + path);
		}
		if (!IJ.isWindows()) {
			try {
				String[] command = {
					"chmod", "0600", path
				};
				Runtime.getRuntime().exec(command);
			} catch (Exception e) {
				if (IJ.debugMode)
					System.err.println("Even chmod failed.");
			}
		}
	}

	public static boolean sendArguments(String[] args) {
		if (!isRMIEnabled())
			return false;
		String file = getStubPath();
		try {
			FileInputStream in = new FileInputStream(file);
			ImageJInstance instance = (ImageJInstance) new ObjectInputStream(in).readObject();
			in.close();
			if (instance==null)
				return false;
			instance.sendArgument("user.dir "+System.getProperty("user.dir"));
			int macros = 0;
			for (int i=0; i 

Ads help maintain this website.