/* * Created on 8 juil. 2003 * Copyright (C) 2003, 2004, 2005, 2006 Aelitis, All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program 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 General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * AELITIS, SAS au capital de 46,603.30 euros * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France. * */ package org.gudy.azureus2.ui.swt; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.LinkedList; import java.util.List; import org.gudy.azureus2.core3.config.COConfigurationManager; import org.gudy.azureus2.core3.logging.LogAlert; import org.gudy.azureus2.core3.logging.LogEvent; import org.gudy.azureus2.core3.logging.LogIDs; import org.gudy.azureus2.core3.logging.Logger; import org.gudy.azureus2.ui.swt.mainwindow.Initializer; import com.aelitis.azureus.core.AzureusCore; import com.aelitis.azureus.core.AzureusCoreException; import com.aelitis.azureus.core.AzureusCoreFactory; import com.aelitis.azureus.launcher.Launcher; import edu.washington.cs.oneswarm.ui.gwt.RemoteAccessConfig; /** * @author Olivier * */ public class Main { private static final LogIDs LOGID = LogIDs.GUI; public static final String PR_MULTI_INSTANCE = "MULTI_INSTANCE"; // values "true" or "false" StartServer startServer; // This method is called by other Main classes via reflection - must be kept public. public Main(String args[]) { try { // this should not be necessary, but since it's public let's play safe if (Launcher.checkAndLaunch(Main.class, args)) return; // This *has* to be done first as it sets system properties that are read and cached by Java COConfigurationManager.preInitialise(); String mi_str = System.getProperty(PR_MULTI_INSTANCE); boolean mi = mi_str != null && mi_str.equalsIgnoreCase("true"); /** * isdal mod, check for autostart flag and set nosplash * * check for configure flag as run configure script */ List<String> newargs = new LinkedList<String>(); boolean autoStart = false; boolean configure = false; System.out.print("args: "); for (String s : args) { System.out.print(s + " "); if ("--autostart".equalsIgnoreCase(s)) { autoStart = true; } else if ("--configure".equalsIgnoreCase(s)) { configure = true; } else { newargs.add(s); } } System.out.println(""); if (autoStart) { System.setProperty("nolaunch_startup", ""); // and continue without the --autostart arg args = newargs.toArray(new String[newargs.size()]); } if (configure) { runConfigure(); System.exit(0); } /** * PIAMOD -- * * Special case the multi instance code here -- by default, we launch with MULTI_INSTANCE since * we wanted to coexist with Azureus. Special case is if we're launching with arguments since, on * windows, that's how URL handlers are invoked, and Azureus uses the start server to transfer passed * URI info to the running process. * * These days, we've just switched the port of the StartServer, so we don't need this anymore. and, we need * to pass arguments to support links */ mi = false; startServer = new StartServer(); boolean debugGUI = Boolean.getBoolean("debug"); if (mi || debugGUI) { // create a MainWindow regardless to the server state AzureusCore core = AzureusCoreFactory.create(); new Initializer(core, startServer, args); return; } if (processParams(args, startServer)) { AzureusCore core = AzureusCoreFactory.create(); startServer.pollForConnections(core); new Initializer(core, startServer, args); } } catch (AzureusCoreException e) { Logger.log(new LogEvent(LOGID, "Start failed", e)); } } private void runConfigure() { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); try { COConfigurationManager.initialise(); System.out.println("===OneSwarm configure==="); System.out.println("Enable remote access? (y/n)"); String line = in.readLine(); if (line.equalsIgnoreCase("yes") || line.equalsIgnoreCase("y")) { System.out.println("Enter the new remote access user name:"); String userName = in.readLine(); Thread eraseThread = new Thread(new Runnable() { public void run() { try { while (true) { Thread.sleep(100); System.out.print("\b*"); } } catch (InterruptedException e) { } } }); eraseThread.start(); String password; String password2; boolean passwordOk = true; do { System.out.println("Enter the new remote access password (min 8 characters):"); password = in.readLine(); System.out.println("Enter the password again: "); password2 = in.readLine(); if (!password2.equals(password)) { passwordOk = false; System.out.println("password does not match"); } else if (password.length() < 8) { passwordOk = false; System.out.println("password to short, min length is 8"); } else { passwordOk = true; } } while (!passwordOk); eraseThread.interrupt(); RemoteAccessConfig.saveRemoteAccessCredentials(userName, password); COConfigurationManager.setParameter("OSGWTUI.RemoteAccess", true); System.out.println("Remote access password saved"); } else { COConfigurationManager.setParameter("OSGWTUI.RemoteAccess", false); } System.out.println("Enter tcp listen port [" + COConfigurationManager.getIntParameter("TCP.Listen.Port") + "]:"); String tcpPort = in.readLine(); if (tcpPort.length() > 0) { COConfigurationManager.setParameter("TCP.Listen.Port", Integer.parseInt(tcpPort)); } boolean pathOk = false; do { System.out.println("Enter default save location[" + COConfigurationManager.getDirectoryParameter("Default save path") + "]:"); String path = in.readLine(); if (path.length() == 0) { pathOk = true; } else { File f = new File(path); if (f.isDirectory()) { File testFile = new File(f, "testing_if_write_is_permitted.txt"); testFile.createNewFile(); if (testFile.isFile()) { testFile.delete(); pathOk = true; } else { System.out.println("directory not writable"); } } else { System.out.println("directory does not exit, create? (y/n)"); line = in.readLine(); if (line.equalsIgnoreCase("yes") || line.equalsIgnoreCase("y")) { boolean ok = f.mkdirs(); if (ok) { pathOk = true; } else { System.out.println("unable to create dir: '" + path + "'"); } } } } if (pathOk) { COConfigurationManager.setParameter("Default save path", path); } } while (!pathOk); COConfigurationManager.save(); System.out.println("Configuration done, the rest can be done using the webpage"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * @param args * @return whether to init the core */ public static boolean processParams(String[] args, StartServer startServer) { boolean closedown = false; boolean another_instance = startServer.getState() != StartServer.STATE_LISTENING; /* if another instance is running then set the property which is checked during * class instantiation by various stuff to to avoid pulling in too much state * from the already running instance */ if (another_instance) System.setProperty("transitory.startup", "1"); // WATCH OUT FOR LOGGING HERE - we don't want to use Logger if this is a secondary instance as // it initialised TOO MUCH of AZ core for (int i = 0; i < args.length; i++) { String arg = args[i]; if (arg.equalsIgnoreCase("--closedown")) { closedown = true; break; } // Sometimes Windows use filename in 8.3 form and cannot // match .torrent extension. To solve this, canonical path // is used to get back the long form String filename = arg; if (filename.toUpperCase().startsWith("HTTP:") || filename.toUpperCase().startsWith("HTTPS:") || filename.toUpperCase().startsWith("MAGNET:")) { if (!another_instance) { Logger.log(new LogEvent(LOGID, "Main::main: args[" + i + "] handling as a URI: " + filename)); } continue; //URIs cannot be checked as a .torrent file } try { File file = new File(filename); if (!file.exists()) { throw (new Exception("File '" + file + "' not found")); } args[i] = file.getCanonicalPath(); // don't use logger if we're not the main instance as we don't want all // the associated core initialisation + debug file moving... if ((!another_instance) && Logger.isEnabled()) { Logger.log(new LogEvent(LOGID, "Main::main: args[" + i + "] exists = " + new File(filename).exists())); } } catch (Throwable e) { if (another_instance) { e.printStackTrace(); } else { Logger.log(new LogAlert(LogAlert.REPEATABLE, LogAlert.AT_ERROR, "Failed to access torrent file '" + filename + "'. Ensure sufficient temporary " + "file space available (check browser cache usage).")); } } } if (another_instance) { //looks like there's already a process listening on 127.0.0.1:6885 //attempt to pass args to existing instance StartSocket ss = new StartSocket(args); if (!ss.sendArgs()) { //arg passing attempt failed, so start core anyway another_instance = false; String msg = "There appears to be another program process already listening on socket [127.0.0.1: 6885].\nLoading of torrents via command line parameter will fail until this is fixed."; System.out.println(msg); Logger.log(new LogAlert(LogAlert.REPEATABLE, LogAlert.AT_WARNING, msg)); } } if (!another_instance) { if (closedown) { // closedown request and no instance running return false; } return true; } return false; } public static void main(String args[]) { System.out.println("OneSwarm custom main"); if (Launcher.checkAndLaunch(Main.class, args)) return; //Debug.dumpThreads("Entry threads"); //Debug.dumpSystemProperties(); if (System.getProperty("ui.temp") == null) { System.setProperty("ui.temp", "az2"); } new Main(args); } }