/*************************************************************************************
* Copyright (c) 2015 Red Hat, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* JBoss by Red Hat - Initial implementation.
************************************************************************************/
package org.jboss.tools.common.jdt.debug.internal;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.jboss.tools.common.jdt.debug.RemoteDebugActivator;
import org.jboss.tools.common.jdt.debug.VmModel;
public class VmModelCommandUtility {
private static boolean loggedWarning = false;
private static String[] WIN_CMD_ARRAY = { "netstat", "-ona", "-p", "tcp" };
private static String[] MAC_CMD_ARRAY = { "lsof", "-i", "-P" };
private static String[] LINUX_CMD_ARRAY = { "netstat", "-nlt", "-p", "" };
public static VmModel getVmModelUsingOsCommand(Integer vmPid, IProgressMonitor monitor) {
if (vmPid == null) {
return null;
}
if (monitor == null) {
monitor = new NullProgressMonitor();
}
if (monitor.isCanceled()) {
return null;
}
String vmPidStr = String.valueOf(vmPid);
String[] cmdarray = getOsCommand(vmPidStr);
if (cmdarray == null) {
return null;
}
InputStream is = null;
BufferedReader reader = null;
try {
Process process = Runtime.getRuntime().exec(cmdarray);
if (monitor.isCanceled()) {
return null;
}
is = process.getInputStream();
reader = new BufferedReader(new InputStreamReader(is));
String line = reader.readLine();
while (line != null) {
if (line.contains("LISTEN")) {
line = clearWhiteSpace(line);
VmModel model = processLine(line, vmPidStr);
if (model != null) {
return model;
}
}
if (monitor.isCanceled()) {
return null;
}
line = reader.readLine();
}
} catch (IOException e) {
if( !loggedWarning ) {
RemoteDebugActivator.pluginLog().logWarning(e);
loggedWarning = true;
}
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
// ignore
}
}
if (is != null) {
try {
is.close();
} catch (IOException e1) {
// ignore
}
}
}
return null;
}
private static String[] getOsCommand(String pid) {
if (Platform.OS_WIN32.equals(Platform.getOS())) {
return WIN_CMD_ARRAY;
} else if (Platform.OS_MACOSX.equals(Platform.getOS())) {
return MAC_CMD_ARRAY;
} else if (Platform.OS_LINUX.equals(Platform.getOS())) {
String[] cmdarray = LINUX_CMD_ARRAY;
cmdarray[cmdarray.length-1] = pid;
return cmdarray;
}
return null;
}
private static VmModel processLine(String line, String vmPidStr) {
if (Platform.OS_WIN32.equals(Platform.getOS())) {
return processWinLine(line, vmPidStr);
} else if (Platform.OS_MACOSX.equals(Platform.getOS())) {
return processMacLine(line, vmPidStr);
} else if (Platform.OS_LINUX.equals(Platform.getOS())) {
return processLinuxLine(line, vmPidStr);
}
return null;
}
private static VmModel processLinuxLine(String line, String vmPidStr) {
String[] elements = line.split(" ", 7);
if (elements.length >= 7 &&
elements[0] != null && elements[0].equals("tcp")) {
if (elements[6] != null) {
String[] pids = elements[6].split("/");
String pid;
if (pids.length == 2) {
pid = pids[0];
if (pid != null && pid.equals(vmPidStr)) {
if (elements[3] != null) {
String port = getPort(elements[3]);
if (port != null) {
VmModel model = new VmModel();
model.setPid(vmPidStr);
model.setMainClass(RemoteDebugActivator.UNKNOWN);
model.setPort(port);
model.setTransport(RemoteDebugActivator.DT_SOCKET);
return model;
}
}
}
}
}
}
return null;
}
private static VmModel processWinLine(String line, String vmPidStr) {
String[] elements = line.split(" ", 5);
if (elements.length == 5 && elements[4] != null && elements[4].equals(vmPidStr)) {
if (elements[1] != null) {
String port = getPort(elements[1]);
if (port != null && !port.isEmpty()) {
VmModel model = new VmModel();
model.setPid(vmPidStr);
model.setMainClass(RemoteDebugActivator.UNKNOWN);
model.setPort(port);
model.setTransport(RemoteDebugActivator.DT_SOCKET);
return model;
}
}
}
return null;
}
private static VmModel processMacLine(String line, String vmPidStr) {
String[] elements = line.split(" ", 10);
if (elements.length >= 10 &&
elements[1] != null && elements[1].equals(vmPidStr) &&
elements[7] != null && elements[7].equals("TCP")) {
if (elements[8] != null) {
String port = getPort(elements[8]);
if (port != null && !port.isEmpty()) {
VmModel model = new VmModel();
model.setPid(vmPidStr);
model.setMainClass(RemoteDebugActivator.UNKNOWN);
model.setPort(port);
model.setTransport(RemoteDebugActivator.DT_SOCKET);
return model;
}
}
}
return null;
}
private static String getPort(String element) {
String[] ports = element.split(":");
String port;
if (ports.length == 2) {
port = ports[1];
} else {
port = ports[0];
}
return port;
}
private static String clearWhiteSpace(String line) {
line = line.trim();
while (line.contains("\t")) {
line = line.replace(" ", "\t");
}
while (line.contains(" ")) {
line = line.replace(" ", " ");
}
return line;
}
}