openers now more or less work, tested on Linux :-)

git-svn-id: https://ipscan.svn.sourceforge.net/svnroot/ipscan/ipscan@22 375186e5-ef17-0410-b0b6-91563547dcda
This commit is contained in:
angryziber 2006-09-18 20:25:09 +00:00
parent 8483e9466b
commit e802ac8c4e
12 changed files with 312 additions and 87 deletions

View File

@ -46,6 +46,7 @@ state.waitForThreads=Wait for all threads to terminate...
state.killingThreads=Killing all threads...
state.saving=Exporting results...
state.searching=Searching...
state.opening=Opening
title.about=About
title.options=Options
title.options.scanning=Scanning
@ -151,9 +152,10 @@ exception.ExporterException.exporter.unknown=Unknown file type, please specify c
exception.ExporterException.xml.noAppend=Appending to XML files is not supported.
exception.ExporterException.fetcher.notFound=Not enough data in the scanning results to export to this file type.
exception.UserErrorException.openURL.failed=Unable to launch your default browser, sorry.\nURL:
exception.UserErrorException.openTerminal.failed=Unable to launch the terminal, sorry\n
exception.UserErrorException.opener.failed=Unable to launch an external process, sorry.\nCommand-line:
exception.UserErrorException.opener.unknownFetcher=The referenced fetcher cannot be resolved in the current scanning result:
exception.UserErrorException.opener.nullFetcherValue=The replacement value of the fetcher is empty in the scanning results:
exception.UserErrorException.opener.unknownFetcher=The referenced fetcher cannot be resolved in the current scanning result. Cannot execute the opener with parameter:
exception.UserErrorException.opener.nullFetcherValue=The replacement value of the fetcher is empty in the scanning results. Cannot execute the opener with parameter:
exception.UserErrorException.commands.noSelection=No IP address selected
exception.UserErrorException.commands.noResults=No scanning results available yet, please perform a scan first
exception.UserErrorException.favorite.alreadyExists=A favorite with the same name already exists, please try a different one

View File

@ -67,10 +67,12 @@ public class DimensionsConfig {
* @param isMaximized
*/
public void setWindowBounds(Rectangle bounds, boolean isMaximized) {
windowTop = bounds.y;
windowLeft = bounds.x;
windowHeight = bounds.height;
windowWidth = bounds.width;
if (!isMaximized) {
windowTop = bounds.y;
windowLeft = bounds.x;
windowHeight = bounds.height;
windowWidth = bounds.width;
}
isWindowMaximized = isMaximized;
}

View File

@ -11,15 +11,15 @@ import java.util.prefs.Preferences;
/**
* This is a generic named list config.
* Can be used for storing favorites, openers, and other
* user-defined configuration.
* user-defined configurations.
*
* @author anton
*/
public class NamedListConfig {
private String preferenceName;
private Preferences preferences = Config.getPreferences();
private Map namedList = new LinkedHashMap();
protected String preferenceName;
protected Preferences preferences = Config.getPreferences();
protected Map namedList = new LinkedHashMap();
// package local constructor
NamedListConfig(String preferenceName) {
@ -48,11 +48,15 @@ public class NamedListConfig {
String[] namedListPrefs = preferences.get(preferenceName, "").split("###");
for (int i = 0; i < namedListPrefs.length; i += 2) {
if (namedListPrefs[i].length() > 0) {
namedList.put(namedListPrefs[i], namedListPrefs[i+1]);
namedList.put(namedListPrefs[i], serializeValue(namedListPrefs[i+1]));
}
}
}
Object serializeValue(String value) {
return value;
}
/**
* Stores the currently available named list
*/
@ -72,12 +76,12 @@ public class NamedListConfig {
* @param name displayed to the user
* @param value to store according to the name
*/
public void add(String name, String value) {
public void add(String name, Object value) {
namedList.put(name, value);
}
/**
* @param name favorite name
* @param name name
* @return stored value
*/
public String get(String name) {
@ -85,7 +89,7 @@ public class NamedListConfig {
}
/**
* @return an Iterator for iterating names of available favorites
* @return an Iterator for iterating names of available items
*/
public Iterator iterateNames() {
return namedList.keySet().iterator();

View File

@ -3,6 +3,9 @@
*/
package net.azib.ipscan.config;
import java.io.File;
import java.util.prefs.Preferences;
/**
* OpenersConfig
*
@ -14,18 +17,64 @@ public class OpenersConfig extends NamedListConfig {
super("openers");
if (size() == 0) {
boolean isWindows = System.getProperty("os.name").startsWith("Windows");
Labels labels = Labels.getInstance();
// add default openers
add(labels.getString("opener.web"), "http://${fetcher.ip}/");
add(labels.getString("opener.netbios"), "\\\\${fetcher.ip}");
add(labels.getString("opener.ftp"), "ftp://${fetcher.ip}/");
add(labels.getString("opener.telnet"), "telnet ${fetcher.ip}");
add(labels.getString("opener.ssh"), "ssh ${fetcher.ip}");
add(labels.getString("opener.web"), new Opener("http://${fetcher.ip}/", false, null));
if (isWindows) add(labels.getString("opener.netbios"), new Opener("\\\\${fetcher.ip}", false, null));
add(labels.getString("opener.ftp"), new Opener("ftp://${fetcher.ip}/", false, null));
add(labels.getString("opener.telnet"), new Opener("telnet ${fetcher.ip}", true, null));
if (!isWindows) add(labels.getString("opener.ssh"), new Opener("ssh ${fetcher.ip}", true, null));
add(labels.getString("opener.email"), new Opener("mailto:somebody@example.com?subject=IP: ${fetcher.ip}", true, null));
}
}
/**
* This constructor is for tests
* @param preferences
*/
OpenersConfig(Preferences preferences) {
super(preferences, "openers");
}
Object serializeValue(String value) {
return new Opener(value);
}
public void add(String name, Object value) {
if (value instanceof Opener)
super.add(name, value);
else
// ensure only Openers are allowed here
throw new IllegalArgumentException();
}
public Opener getOpener(String name) {
return (Opener)namedList.get(name);
}
public static class Opener {
public String execString;
public boolean inTerminal;
public File workingDir;
Opener(String serialized) {
String[] parts = serialized.split("@@@");
execString = parts[0];
inTerminal = parts[1].charAt(0) == '1';
workingDir = parts.length >= 3 && parts[2].length() > 0 ? new File(parts[2]) : null;
}
public Opener(String execString, boolean inTerminal, File workingDir) {
this.execString = execString;
this.inTerminal = inTerminal;
this.workingDir = workingDir;
}
public String toString() {
return execString + "@@@" + (inTerminal ? '1' : '0') + "@@@" + (workingDir != null ? workingDir.toString() : "");
}
}
}

View File

@ -3,11 +3,13 @@
*/
package net.azib.ipscan.gui;
import java.io.File;
import java.util.Iterator;
import net.azib.ipscan.config.Config;
import net.azib.ipscan.config.Labels;
import net.azib.ipscan.config.OpenersConfig;
import net.azib.ipscan.config.OpenersConfig.Opener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
@ -35,6 +37,8 @@ public class EditOpenersDialog extends AbstractModalDialog {
private Text openerNameText;
private Text openerStringText;
private Text openerDirText;
private Button isCommandlineCheckbox;
private SaveButtonListener saveButtonListener;
public EditOpenersDialog() {
@ -126,9 +130,9 @@ public class EditOpenersDialog extends AbstractModalDialog {
openerDirText = new Text(editGroup, SWT.BORDER);
openerDirText.setSize(SWT.DEFAULT, 22);
Button isCommanLineCheckbox = new Button(editGroup, SWT.CHECK);
isCommanLineCheckbox.setText(Labels.getInstance().getString("text.openers.isCommandLine"));
isCommanLineCheckbox.setSize(SWT.DEFAULT, 18);
isCommandlineCheckbox = new Button(editGroup, SWT.CHECK);
isCommandlineCheckbox.setText(Labels.getInstance().getString("text.openers.isCommandLine"));
isCommandlineCheckbox.setSize(SWT.DEFAULT, 18);
editGroup.layout();
@ -214,8 +218,7 @@ public class EditOpenersDialog extends AbstractModalDialog {
public void handleEvent(Event event) {
String openerName = openerNameText.getText();
String openerValue = openerStringText.getText();
Config.getOpenersConfig().add(openerName, openerValue);
Config.getOpenersConfig().add(openerName, new OpenersConfig.Opener(openerStringText.getText(), isCommandlineCheckbox.getSelection(), new File(openerDirText.getText())));
openersList.setItem(openersList.getSelectionIndex(), openerName);
}
}
@ -238,10 +241,11 @@ public class EditOpenersDialog extends AbstractModalDialog {
int selectionIndex = openersList.getSelectionIndex();
String openerName = openersList.getItem(selectionIndex);
editGroup.setText(openerName);
String openerValue = Config.getOpenersConfig().get(openerName);
Opener opener = Config.getOpenersConfig().getOpener(openerName);
openerNameText.setText(openerName);
openerStringText.setText(openerValue);
// TODO: load other stuff too
openerStringText.setText(opener.execString);
openerDirText.setText(opener.workingDir != null ? opener.workingDir.toString() : "");
isCommandlineCheckbox.setSelection(opener.inTerminal);
}
}

View File

@ -8,7 +8,7 @@ import java.lang.reflect.Method;
import net.azib.ipscan.gui.UserErrorException;
/**
* BrowserLauncher
* The cross-platform browser launcher
*
* @author anton
*/

View File

@ -4,11 +4,10 @@
package net.azib.ipscan.gui.actions;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.azib.ipscan.config.Config;
import net.azib.ipscan.fetchers.FetcherRegistry;
import net.azib.ipscan.config.Labels;
import net.azib.ipscan.config.OpenersConfig.Opener;
import net.azib.ipscan.gui.DetailsWindow;
import net.azib.ipscan.gui.EditOpenersDialog;
import net.azib.ipscan.gui.MainWindow;
@ -105,9 +104,11 @@ public class CommandsActions {
public static class SelectOpener implements Listener {
private MainWindow mainWindow;
private OpenerLauncher openerLauncher;
public SelectOpener(MainWindow mainWindow) {
this.mainWindow = mainWindow;
this.openerLauncher = new OpenerLauncher(mainWindow);
}
public void handleEvent(Event event) {
@ -117,52 +118,18 @@ public class CommandsActions {
if (indexOf >= 0) {
name = name.substring(0, indexOf);
}
String openerString = Config.getOpenersConfig().get(name);
Opener opener = Config.getOpenersConfig().getOpener(name);
int selectedItem = mainWindow.getResultTable().getSelectionIndex();
if (selectedItem < 0) {
throw new UserErrorException("commands.noSelection");
}
openerString = prepareOpenerStringForItem(openerString, selectedItem);
new OpenerLauncher().launch(openerString);
mainWindow.setStatusText(Labels.getInstance().getString("state.opening") + name);
openerLauncher.launch(opener, selectedItem);
mainWindow.setStatusText(null);
}
/**
* Replaces references to scanned values in an opener string.
* Refefernces look like ${fetcher_label}
* @param openerString
* @return opener string with values replaced
*/
String prepareOpenerStringForItem(String openerString, int selectedItem) {
Pattern paramsPattern = Pattern.compile("\\$\\{(.+?)\\}");
Matcher matcher = paramsPattern.matcher(openerString);
StringBuffer sb = new StringBuffer(64);
while (matcher.find()) {
// resolve the required fetcher
String fetcherName = matcher.group(1);
int fetcherIndex = FetcherRegistry.getInstance().getSelectedFetcherIndex(fetcherName);
if (fetcherIndex < 0) {
throw new UserErrorException("opener.unknownFetcher", fetcherName);
}
// retrieve the scanned value
String scannedValue = getScannedValue(selectedItem, fetcherIndex);
if (scannedValue == null) {
throw new UserErrorException("opener.nullFetcherValue", fetcherName);
}
matcher.appendReplacement(sb, scannedValue);
}
matcher.appendTail(sb);
return sb.toString();
}
String getScannedValue(int selectedItem, int fetcherIndex) {
return (String) mainWindow.getResultTable().getScanningResults().getResult(selectedItem).getValues().get(fetcherIndex);
}
}
}

View File

@ -3,8 +3,12 @@
*/
package net.azib.ipscan.gui.actions;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.azib.ipscan.config.OpenersConfig.Opener;
import net.azib.ipscan.fetchers.FetcherRegistry;
import net.azib.ipscan.gui.MainWindow;
import net.azib.ipscan.gui.UserErrorException;
/**
@ -14,7 +18,15 @@ import net.azib.ipscan.gui.UserErrorException;
*/
public class OpenerLauncher {
public void launch(String openerString) {
private MainWindow mainWindow;
public OpenerLauncher(MainWindow mainWindow) {
this.mainWindow = mainWindow;
}
public void launch(Opener opener, int selectedItem) {
String openerString = prepareOpenerStringForItem(opener.execString, selectedItem);
// check for URLs
if (openerString.startsWith("http:") || openerString.startsWith("https:") || openerString.startsWith("ftp:") || openerString.startsWith("mailto:")) {
BrowserLauncher.openURL(openerString);
@ -22,14 +34,52 @@ public class OpenerLauncher {
else {
// run a process here
try {
// TODO: we probably need to support shell patterns, etc
Runtime.getRuntime().exec(openerString);
if (opener.inTerminal) {
TerminalLauncher.launchInTerminal(openerString, opener.workingDir);
}
else {
// TODO: we probably need to support shell patterns, etc
Runtime.getRuntime().exec(openerString, null, opener.workingDir);
}
}
catch (IOException e) {
catch (Exception e) {
throw new UserErrorException("opener.failed", openerString);
}
}
}
/**
* Replaces references to scanned values in an opener string.
* Refefernces look like ${fetcher_label}
* @param openerString
* @return opener string with values replaced
*/
String prepareOpenerStringForItem(String openerString, int selectedItem) {
Pattern paramsPattern = Pattern.compile("\\$\\{(.+?)\\}");
Matcher matcher = paramsPattern.matcher(openerString);
StringBuffer sb = new StringBuffer(64);
while (matcher.find()) {
// resolve the required fetcher
String fetcherName = matcher.group(1);
int fetcherIndex = FetcherRegistry.getInstance().getSelectedFetcherIndex(fetcherName);
if (fetcherIndex < 0) {
throw new UserErrorException("opener.unknownFetcher", fetcherName);
}
// retrieve the scanned value
try {
String scannedValue = getScannedValue(selectedItem, fetcherIndex);
matcher.appendReplacement(sb, scannedValue);
}
catch (Exception e) {
throw new UserErrorException("opener.nullFetcherValue", fetcherName);
}
}
matcher.appendTail(sb);
return sb.toString();
}
String getScannedValue(int selectedItem, int fetcherIndex) {
return (String) mainWindow.getResultTable().getScanningResults().getResult(selectedItem).getValues().get(fetcherIndex);
}
}

View File

@ -0,0 +1,50 @@
/**
*
*/
package net.azib.ipscan.gui.actions;
import java.io.File;
import java.io.FileWriter;
import net.azib.ipscan.gui.UserErrorException;
/**
* The cross-platform terminal launcher
*
* @author anton
*/
public class TerminalLauncher {
/**
* Launches the execString in the terminal.
* Supports Linux/Unix, MacOS, and Windows
* @param execString the command to launch
* @param workingDir the working directory (or null)
*/
public static void launchInTerminal(String execString, File workingDir) {
String osName = System.getProperty("os.name");
try {
if (osName.startsWith("Windows")) {
// generate a bat file :-)
File batFile = File.createTempFile("launch", ".bat");
batFile.deleteOnExit();
FileWriter writer = new FileWriter(batFile);
writer.write("@rem This is a temporary file generated by Angry IP Scanner\n\n" +
execString + "\npause > nul\n");
writer.close();
// TODO: test this on Windows!!!
Runtime.getRuntime().exec(batFile.getAbsolutePath(), null, workingDir);
}
else { // assume Linux or other Unix
// TODO: test this on MacOS!!!
// TODO: maybe gnome-terminal, konsole, and MacOS-specific terminal should be tried as well...
Runtime.getRuntime().exec(new String[] {"xterm", "-e", "bash", "-c", execString + ";bash"}, null, workingDir);
}
}
catch (Exception e) {
throw new UserErrorException("openTerminal.failed", execString);
}
}
}

View File

@ -56,8 +56,6 @@ public class NamedListConfigTest extends TestCase {
}
public void testStore() throws Exception {
NamedListConfig config = new NamedListConfig(preferences, PREFERENCE_NAME);
config.add("x", "y");
config.add("Buga muga x,1,2,3,4,5", "opopo op : , . l ; - # | @@");
config.add("127.0.0.1", "192.168.2.25");

View File

@ -0,0 +1,100 @@
/**
*
*/
package net.azib.ipscan.config;
import java.io.File;
import java.util.Iterator;
import java.util.prefs.Preferences;
import junit.framework.TestCase;
/**
* OpenersConfigTest
*
* @author anton
*/
public class OpenersConfigTest extends TestCase {
private static final String PREFERENCE_NAME = "openers";
private Preferences preferences;
private OpenersConfig config;
protected void setUp() throws Exception {
preferences = Preferences.userRoot().node("ipscan-test");
config = new OpenersConfig(preferences);
}
protected void tearDown() throws Exception {
preferences.removeNode();
}
public void testAddNoStrings() {
try {
config.add("aa", "b");
fail();
}
catch (IllegalArgumentException e) {}
}
public void testAdd() {
config.add("Mega favorite", new OpenersConfig.Opener("a@@@0@@@c"));
assertEquals("a", config.getOpener("Mega favorite").execString);
assertEquals(false, config.getOpener("Mega favorite").inTerminal);
assertEquals("c", config.getOpener("Mega favorite").workingDir.getName());
assertEquals(1, config.size());
}
public void testOpenerDeserialize() {
OpenersConfig.Opener o = new OpenersConfig.Opener("uu@@uu@@@1@@@");
assertEquals("uu@@uu", o.execString);
assertEquals(true, o.inTerminal);
assertEquals(null, o.workingDir);
o = new OpenersConfig.Opener("c:\\program files\\mega app\\app.exe@@@0@@@c:\\windoze system");
assertEquals("c:\\program files\\mega app\\app.exe", o.execString);
assertEquals(false, o.inTerminal);
assertEquals("c:\\windoze system", o.workingDir.getName());
}
public void testLoad() throws Exception {
preferences.put(PREFERENCE_NAME, "aa###aaa@@@1@@@###bb###bbb@@@1@@@");
OpenersConfig config = new OpenersConfig(preferences);
assertEquals("aaa", config.getOpener("aa").execString);
assertEquals("bbb", config.getOpener("bb").execString);
assertEquals(2, config.size());
}
public void testOrder() throws Exception {
preferences.put(PREFERENCE_NAME, "aa###aaa@@@1@@@###bb###bbb@@@1@@@");
OpenersConfig config = new OpenersConfig(preferences);
Iterator namesIterator = config.iterateNames();
assertEquals("aa", namesIterator.next());
assertEquals("bb", namesIterator.next());
assertFalse(namesIterator.hasNext());
}
public void testStore() throws Exception {
config.add("x", new OpenersConfig.Opener("aa", true, null));
config.add("x y z", new OpenersConfig.Opener("a a", true, new File("zzz z")));
config.store();
assertEquals("x###aa@@@1@@@###x y z###a a@@@1@@@zzz z", preferences.get(PREFERENCE_NAME, ""));
}
public void testUpdate() {
config.add("x", new OpenersConfig.Opener("aa", true, null));
config.add("y", new OpenersConfig.Opener("bb", false, null));
config.add("z", new OpenersConfig.Opener("ccc", false, null));
config.update(new String[] {"x", "z"});
Iterator i = config.iterateNames();
assertEquals("x", (String)i.next());
assertEquals("z", (String)i.next());
assertFalse(i.hasNext());
}
}

View File

@ -6,19 +6,18 @@ package net.azib.ipscan.gui.actions;
import net.azib.ipscan.config.Config;
import net.azib.ipscan.config.Labels;
import net.azib.ipscan.gui.UserErrorException;
import net.azib.ipscan.gui.actions.CommandsActions.SelectOpener;
import junit.framework.TestCase;
/**
* CommandsActionsTest
* OpenerLauncherTest
*
* @author anton
*/
public class CommandsActionsTest extends TestCase {
public class OpenerLauncherTest extends TestCase {
public void testReplaceValues() {
Config.initialize();
CommandsActions.SelectOpener so = new SelectOpener(null) {
OpenerLauncher ol = new OpenerLauncher(null) {
String getScannedValue(int selectedItem, int fetcherIndex) {
switch (fetcherIndex) {
case 0:
@ -31,12 +30,12 @@ public class CommandsActionsTest extends TestCase {
}
};
assertEquals("\\\\127.0.0.1", so.prepareOpenerStringForItem("\\\\${fetcher.ip}", 0));
assertEquals("PING$$$127.0.0.1xxx${}", so.prepareOpenerStringForItem("${fetcher.ping}$$$${fetcher.ip}xxx${}", 0));
assertEquals("http://127.0.0.1:80/www", so.prepareOpenerStringForItem("http://${fetcher.ip}:80/www", 0));
assertEquals("\\\\127.0.0.1", ol.prepareOpenerStringForItem("\\\\${fetcher.ip}", 0));
assertEquals("PING$$$127.0.0.1xxx${}", ol.prepareOpenerStringForItem("${fetcher.ping}$$$${fetcher.ip}xxx${}", 0));
assertEquals("http://127.0.0.1:80/www", ol.prepareOpenerStringForItem("http://${fetcher.ip}:80/www", 0));
try {
so.prepareOpenerStringForItem("${noSuchFetcher}", 0);
ol.prepareOpenerStringForItem("${noSuchFetcher}", 0);
fail();
}
catch (UserErrorException e) {
@ -44,7 +43,7 @@ public class CommandsActionsTest extends TestCase {
}
try {
so.prepareOpenerStringForItem("${fetcher.ping.ttl}", 0);
ol.prepareOpenerStringForItem("${fetcher.ping.ttl}", 0);
fail();
}
catch (UserErrorException e) {