package com.limegroup.gnutella.browser; import java.io.BufferedOutputStream; import java.io.File; import java.io.IOException; import java.net.Socket; import java.util.Locale; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.limewire.io.ByteReader; import org.limewire.io.IOUtils; import org.limewire.io.NetworkUtils; import org.limewire.util.CommonUtils; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import com.limegroup.gnutella.ActivityCallback; import com.limegroup.gnutella.Constants; @Singleton public class ExternalControl { private static final Log LOG = LogFactory.getLog(ExternalControl.class); private boolean initialized = false; private volatile String enqueuedRequest = null; private final Provider<ActivityCallback> activityCallback; @Inject public ExternalControl(Provider<ActivityCallback> activityCallback) { this.activityCallback = activityCallback; } public static String preprocessArgs(String args[]) { StringBuilder arg = new StringBuilder(); for (int i = 0; i < args.length; i++) { arg.append(args[i]); } return arg.toString(); } public boolean isInitialized() { return initialized; } public void enqueueControlRequest(String arg) { enqueuedRequest = arg; } public void runQueuedControlRequest() { initialized = true; if (enqueuedRequest != null) { String request = enqueuedRequest; enqueuedRequest = null; if (isTorrentRequest(request)) handleTorrentRequest(request); else handleMagnetRequest(request); } } /** * @return true if this is a torrent request. */ public static boolean isTorrentRequest(String arg) { if (arg == null) return false; arg = arg.trim().toLowerCase(Locale.US); // magnets pointing to .torrent files are just magnets for now return arg.endsWith(".torrent") && !arg.startsWith("magnet:"); } // refactored the download logic into a separate method public void handleMagnetRequest(String arg) { LOG.trace("enter handleMagnetRequest"); ActivityCallback callback = restoreApplication(); MagnetOptions options[] = MagnetOptions.parseMagnet(arg); if (options.length == 0) { if (LOG.isWarnEnabled()) LOG.warn("Invalid magnet, ignoring: " + arg); return; } callback.handleMagnets(options); } private ActivityCallback restoreApplication() { activityCallback.get().restoreApplication(); return activityCallback.get(); } private void handleTorrentRequest(String arg) { LOG.trace("enter handleTorrentRequest"); ActivityCallback callback = restoreApplication(); File torrentFile = new File(arg.trim()); callback.handleTorrent(torrentFile); } /** * Handle a Magnet request via a socket (for TCP handling). Deiconify the * application, fire MAGNET request and return true as a sign that LimeWire * is running. */ public void fireControlThread(Socket socket, boolean magnet) { LOG.trace("enter fireControl"); Thread.currentThread().setName("IncomingControlThread"); try { // Only allow control from localhost if (!NetworkUtils.isLocalHost(socket)) { if (LOG.isWarnEnabled()) LOG.warn("Invalid control request from: " + socket.getInetAddress().getHostAddress()); return; } if(LOG.isInfoEnabled()) LOG.info("Request on port " + socket.getLocalPort()); // First read extra parameter socket.setSoTimeout(Constants.TIMEOUT); ByteReader br = new ByteReader(socket.getInputStream()); // read the first line. if null, throw an exception String line = br.readLine(); socket.setSoTimeout(0); BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream()); String s = CommonUtils.getUserName() + "\r\n"; // system internal, so use system encoding byte[] bytes = s.getBytes(); out.write(bytes); out.flush(); if (magnet) handleMagnetRequest(line); else handleTorrentRequest(line); } catch (IOException e) { LOG.warn("Exception while responding to control request", e); } finally { IOUtils.close(socket); } } }