propagate from branch 'i2p.i2p' (head 6706bab853107973d7d0ff28212aae65bd098591)

to branch 'i2p.i2p.str4d.ui' (head 645f60a4d23af4116ae660b09dfff32d19a65c32)
This commit is contained in:
str4d
2016-05-08 21:47:30 +00:00
76 changed files with 1598 additions and 642 deletions

View File

@ -173,6 +173,10 @@ Applications:
Copyright (C) sponge
See licenses/COPYING-BOB.txt
Desktopgui
Copyright (c) Mathias De Maré
See licenses/LICENSE-DesktopGUI.txt
I2PSnark:
Copyright (C) 2003 Mark J. Wielaard
GPLv2 (or any later version)
@ -291,10 +295,6 @@ distributions. See the source package for the additional license information.
Copyright (C) sponge
DWTFYWTPL
Desktopgui
Copyright (c) Mathias De Maré
See apps/desktopgui/LICENSE
SAM C Library:
Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
See apps/sam/c/doc/license.txt

View File

@ -5,7 +5,6 @@
<property name="build" value="build"/>
<property name="dist" location="dist"/>
<property name="jar" value="desktopgui.jar"/>
<property name="resources" value="resources"/>
<property name="javadoc" value="javadoc"/>
<property name="javac.compilerargs" value=""/>
<property name="javac.version" value="1.6" />
@ -17,8 +16,7 @@
<target name="init">
<mkdir dir="${build}"/>
<mkdir dir="${build}/${resources}"/>
<mkdir dir="${build}/${javadoc}"/>
<mkdir dir="${build}/messages-src"/>
<mkdir dir="${dist}"/>
</target>
@ -38,12 +36,9 @@
<pathelement location="../../router/java/build/router.jar" />
</classpath>
</javac>
<copy todir="${build}/desktopgui/${resources}">
<fileset dir="${resources}" />
</copy>
</target>
<target name="bundle" unless="no.bundle">
<target name="bundle" unless="no.bundle" depends="init">
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
<env key="JAVA_HOME" value="${java.home}" />
<arg value="./bundle-messages.sh" />
@ -51,10 +46,14 @@
<exec executable="sh" osfamily="mac" failifexecutionfails="true" failonerror="${require.gettext}" >
<arg value="./bundle-messages.sh" />
</exec>
<!-- multi-lang is optional -->
<exec executable="sh" osfamily="windows" failifexecutionfails="false" >
<arg value="./bundle-messages.sh" />
</exec>
<javac source="${javac.version}" target="${javac.version}"
includeAntRuntime="false"
srcdir="${build}/messages-src" destdir="${build}">
<compilerarg line="${javac.compilerargs}" />
</javac>
</target>
<target name="listChangedFiles" depends="jarUpToDate" if="shouldListChanges" >
@ -74,7 +73,9 @@
<target name="jar" depends="compile, bundle, listChangedFiles" unless="jar.uptodate" >
<!-- set if unset -->
<property name="workspace.changes.tr" value="" />
<jar basedir="${build}" destfile="${dist}/${jar}">
<!-- ideal for linux: 24x24, but transparency doesn't work -->
<copy tofile="${build}/desktopgui/resources/images/logo.png" file="../../installer/resources/themes/console/images/itoopie_xsm.png" />
<jar basedir="${build}" excludes="messages-src/**" destfile="${dist}/${jar}">
<manifest>
<attribute name="Main-Class" value="net.i2p.desktopgui.Main"/>
<attribute name="Build-Date" value="${build.timestamp}" />

View File

@ -105,6 +105,10 @@ do
# only generate for non-source language
echo "Generating ${CLASS}_$LG ResourceBundle..."
msgfmt -V | grep -q '0\.19'
if [ $? -ne 0 ]
then
# slow way
# convert to class files in build
msgfmt --java --statistics -r $CLASS -l $LG -d build $i
if [ $? -ne 0 ]
@ -115,6 +119,27 @@ do
RC=1
break
fi
else
# fast way
# convert to java files in build/messages-src
TD=build/messages-src-tmp
TDX=$TD/net/i2p/desktopgui
TD2=build/messages-src
TDY=$TD2/net/i2p/desktopgui
rm -rf $TD
mkdir -p $TD $TDY
msgfmt --java --statistics --source -r $CLASS -l $LG -d $TD $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
find build -name messages_${LG}.class -exec rm -f {} \;
RC=1
break
fi
mv $TDX/messages_$LG.java $TDY
rm -rf $TD
fi
fi
done
rm -f $TMPFILE

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -6,27 +6,33 @@ import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingWorker;
import net.i2p.I2PAppContext;
import net.i2p.desktopgui.router.RouterManager;
import net.i2p.util.Log;
public class ExternalTrayManager extends TrayManager {
/**
* When started before the router, e.g. with
* java -cp i2p.jar:router.jar:desktopgui.jar net.i2p.desktopgui.Main
*
* No access to context, very limited abilities.
* Not fully supported.
*/
class ExternalTrayManager extends TrayManager {
private final static Log log = new Log(ExternalTrayManager.class);
public ExternalTrayManager(I2PAppContext ctx, Main main, boolean useSwing) {
super(ctx, main, useSwing);
}
protected ExternalTrayManager() {}
@Override
public PopupMenu getMainMenu() {
PopupMenu popup = new PopupMenu();
MenuItem startItem = new MenuItem(_t("Start I2P"));
startItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.start();
@ -41,12 +47,44 @@ public class ExternalTrayManager extends TrayManager {
//since that risks killing the I2P process as well.
tray.remove(trayIcon);
}
}.execute();
}
});
popup.add(startItem);
return popup;
}
public JPopupMenu getSwingMainMenu() {
JPopupMenu popup = new JPopupMenu();
JMenuItem startItem = new JMenuItem(_t("Start I2P"));
startItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.start();
return null;
}
@Override
protected void done() {
trayIcon.displayMessage(_t("Starting"), _t("I2P is starting!"), TrayIcon.MessageType.INFO);
//Hide the tray icon.
//We cannot stop the desktopgui program entirely,
//since that risks killing the I2P process as well.
tray.remove(trayIcon);
}
}.execute();
}
});
popup.add(startItem);
return popup;
}
/**
* Update the menu
* @since 0.9.26
*/
protected void updateMenu() {}
}

View File

@ -1,35 +1,62 @@
package net.i2p.desktopgui;
import java.awt.Desktop;
import java.awt.Desktop.Action;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingWorker;
import net.i2p.desktopgui.gui.DesktopguiConfigurationFrame;
import net.i2p.data.DataHelper;
import net.i2p.desktopgui.router.RouterManager;
import net.i2p.desktopgui.util.BrowseException;
import net.i2p.desktopgui.util.I2PDesktop;
import net.i2p.router.RouterContext;
import net.i2p.util.Log;
import net.i2p.util.PortMapper;
import net.i2p.util.Translate;
public class InternalTrayManager extends TrayManager {
/**
* java -cp i2p.jar:router.jar:desktopgui.jar net.i2p.desktopgui.Main
*
* Full access to router context.
*/
class InternalTrayManager extends TrayManager {
private final static Log log = new Log(InternalTrayManager.class);
private final RouterContext _context;
private final Log log;
private MenuItem _statusItem, _browserItem, _configItem, _restartItem, _stopItem,
_restartHardItem, _stopHardItem, _cancelItem;
private JMenuItem _jstatusItem, _jbrowserItem, _jconfigItem, _jrestartItem, _jstopItem,
_jrestartHardItem, _jstopHardItem, _jcancelItem;
protected InternalTrayManager() {}
private static final boolean CONSOLE_ENABLED = Desktop.isDesktopSupported() &&
Desktop.getDesktop().isSupported(Action.BROWSE);
private static final String CONSOLE_BUNDLE_NAME = "net.i2p.router.web.messages";
@Override
public PopupMenu getMainMenu() {
public InternalTrayManager(RouterContext ctx, Main main, boolean useSwing) {
super(ctx, main, useSwing);
_context = ctx;
log = ctx.logManager().getLog(InternalTrayManager.class);
}
public synchronized PopupMenu getMainMenu() {
PopupMenu popup = new PopupMenu();
MenuItem browserLauncher = new MenuItem(_t("Launch I2P Browser"));
browserLauncher.addActionListener(new ActionListener() {
final MenuItem statusItem = new MenuItem("");
final MenuItem browserLauncher;
if (CONSOLE_ENABLED) {
browserLauncher = new MenuItem(_t("Launch I2P Browser"));
browserLauncher.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
return null;
@ -37,77 +64,397 @@ public class InternalTrayManager extends TrayManager {
@Override
protected void done() {
launchBrowser();
}
}.execute();
}
});
} else {
browserLauncher = null;
}
PopupMenu desktopguiConfigurationLauncher = new PopupMenu(_t("Configure I2P System Tray"));
MenuItem configSubmenu = new MenuItem(_t("Disable"));
configSubmenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
configureDesktopgui(false);
return null;
}
}.execute();
}
});
final MenuItem restartItem;
if (_context.hasWrapper()) {
restartItem = new MenuItem(_t("Restart I2P"));
restartItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.restartGracefully(_context);
return null;
}
}.execute();
}
});
} else {
restartItem = null;
}
final MenuItem stopItem = new MenuItem(_t("Stop I2P"));
stopItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.shutDownGracefully(_context);
return null;
}
}.execute();
}
});
final MenuItem restartItem2;
if (_context.hasWrapper()) {
restartItem2 = new MenuItem(_t("Restart I2P Immediately"));
restartItem2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.restart(_context);
return null;
}
}.execute();
}
});
} else {
restartItem2 = null;
}
final MenuItem stopItem2 = new MenuItem(_t("Stop I2P Immediately"));
stopItem2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.shutDown(_context);
return null;
}
}.execute();
}
});
final MenuItem cancelItem = new MenuItem(_t("Cancel I2P Shutdown"));
cancelItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.cancelShutdown(_context);
return null;
}
}.execute();
}
});
popup.add(statusItem);
popup.addSeparator();
if (CONSOLE_ENABLED) {
popup.add(browserLauncher);
popup.addSeparator();
}
desktopguiConfigurationLauncher.add(configSubmenu);
popup.add(desktopguiConfigurationLauncher);
popup.addSeparator();
if (_context.hasWrapper())
popup.add(restartItem);
popup.add(stopItem);
if (_context.hasWrapper())
popup.add(restartItem2);
popup.add(stopItem2);
popup.add(cancelItem);
_statusItem = statusItem;
_browserItem = browserLauncher;
_configItem = desktopguiConfigurationLauncher;
_restartItem = restartItem;
_stopItem = stopItem;
_restartHardItem = restartItem2;
_stopHardItem = stopItem2;
_cancelItem = cancelItem;
return popup;
}
public synchronized JPopupMenu getSwingMainMenu() {
JPopupMenu popup = new JPopupMenu();
final JMenuItem statusItem = new JMenuItem("");
final JMenuItem browserLauncher;
if (CONSOLE_ENABLED) {
browserLauncher = new JMenuItem(_t("Launch I2P Browser"));
browserLauncher.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
return null;
}
@Override
protected void done() {
launchBrowser();
}
}.execute();
}
});
} else {
browserLauncher = null;
}
JMenu desktopguiConfigurationLauncher = new JMenu(_t("Configure I2P System Tray"));
JMenuItem configSubmenu = new JMenuItem(_t("Disable"));
configSubmenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
configureDesktopgui(false);
return null;
}
}.execute();
}
});
final JMenuItem restartItem;
if (_context.hasWrapper()) {
restartItem = new JMenuItem(_t("Restart I2P"));
restartItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.restartGracefully(_context);
return null;
}
}.execute();
}
});
} else {
restartItem = null;
}
final JMenuItem stopItem = new JMenuItem(_t("Stop I2P"));
stopItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.shutDownGracefully(_context);
return null;
}
}.execute();
}
});
final JMenuItem restartItem2;
if (_context.hasWrapper()) {
restartItem2 = new JMenuItem(_t("Restart I2P Immediately"));
restartItem2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.restart(_context);
return null;
}
}.execute();
}
});
} else {
restartItem2 = null;
}
final JMenuItem stopItem2 = new JMenuItem(_t("Stop I2P Immediately"));
stopItem2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.shutDown(_context);
return null;
}
}.execute();
}
});
final JMenuItem cancelItem = new JMenuItem(_t("Cancel I2P Shutdown"));
cancelItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.cancelShutdown(_context);
return null;
}
}.execute();
}
});
popup.add(statusItem);
popup.addSeparator();
if (CONSOLE_ENABLED) {
popup.add(browserLauncher);
popup.addSeparator();
}
desktopguiConfigurationLauncher.add(configSubmenu);
popup.add(desktopguiConfigurationLauncher);
popup.addSeparator();
if (_context.hasWrapper())
popup.add(restartItem);
popup.add(stopItem);
if (_context.hasWrapper())
popup.add(restartItem2);
popup.add(stopItem2);
popup.add(cancelItem);
_jstatusItem = statusItem;
_jbrowserItem = browserLauncher;
_jconfigItem = desktopguiConfigurationLauncher;
_jrestartItem = restartItem;
_jstopItem = stopItem;
_jrestartHardItem = restartItem2;
_jstopHardItem = stopItem2;
_jcancelItem = cancelItem;
return popup;
}
/**
* Update the menu
* @since 0.9.26
*/
protected synchronized void updateMenu() {
boolean x = RouterManager.isShutdownInProgress(_context);
boolean imminent = false;
String status;
if (x) {
long time = RouterManager.getShutdownTimeRemaining(_context);
if (time > 5000) {
status = _t("Shutdown in {0}", DataHelper.formatDuration2(time).replace("&nbsp;", " "));
} else {
status = _t("Shutdown imminent");
imminent = true;
}
} else {
// status translations are in the console bundle
status = _t("Network") + ": " +
Translate.getString(RouterManager.getStatus(_context), _context, CONSOLE_BUNDLE_NAME);
}
PopupMenu awt = trayIcon.getPopupMenu();
if (awt != null) {
awt.remove(0);
awt.insert(status, 0);
}
if (_browserItem != null)
_browserItem.setEnabled(!imminent);
if (_configItem != null)
_configItem.setEnabled(!imminent);
if (_restartItem != null)
_restartItem.setEnabled(!x);
if (_stopItem != null)
_stopItem.setEnabled(!x);
if (_restartHardItem != null)
_restartHardItem.setEnabled(!imminent);
if (_stopHardItem != null)
_stopHardItem.setEnabled(!imminent);
if (_cancelItem != null)
_cancelItem.setEnabled(x && !imminent);
if (_jstatusItem != null)
_jstatusItem.setText(status);
if (_jbrowserItem != null)
_jbrowserItem.setVisible(!imminent);
if (_jconfigItem != null)
_jconfigItem.setVisible(!imminent);
if (_jrestartItem != null)
_jrestartItem.setVisible(!x);
if (_jstopItem != null)
_jstopItem.setVisible(!x);
if (_jrestartHardItem != null)
_jrestartHardItem.setVisible(!imminent);
if (_jstopHardItem != null)
_jstopHardItem.setVisible(!imminent);
if (_jcancelItem != null)
_jcancelItem.setVisible(x && !imminent);
}
/**
* @since 0.9.26 from removed gui/DesktopguiConfigurationFrame
*/
private void configureDesktopgui(boolean enable) {
String property = Main.PROP_ENABLE;
String value = Boolean.toString(enable);
try {
I2PDesktop.browse("http://localhost:7657");
_context.router().saveConfig(property, value);
if (!enable) {
// TODO popup that explains how to re-enable in console
_main.shutdown(null);
}
} catch (Exception ex) {
log.error("Error saving config", ex);
}
}
/**
* Build the console URL with info from the port mapper,
* and launch the browser at it.
*
* Modified from I2PTunnelHTTPClientBase.
* TODO perhaps move this to a new PortMapper method.
*
* @since 0.9.26
*/
private void launchBrowser() {
String unset = "*unset*";
PortMapper pm = _context.portMapper();
String httpHost = pm.getActualHost(PortMapper.SVC_CONSOLE, unset);
String httpsHost = pm.getActualHost(PortMapper.SVC_HTTPS_CONSOLE, unset);
int httpPort = pm.getPort(PortMapper.SVC_CONSOLE, 7657);
int httpsPort = pm.getPort(PortMapper.SVC_HTTPS_CONSOLE, -1);
boolean httpsOnly = httpsPort > 0 && httpHost.equals(unset) && !httpsHost.equals(unset);
String url;
if (httpsOnly) {
url = "https://" + httpsHost + ':' + httpsPort + '/';
} else {
if (httpHost.equals(unset))
httpHost = "127.0.0.1";
url = "http://" + httpHost + ':' + httpPort + '/';
}
try {
I2PDesktop.browse(url);
} catch (BrowseException e1) {
log.log(Log.WARN, "Failed to open browser!", e1);
}
}
}.execute();
}
});
MenuItem desktopguiConfigurationLauncher = new MenuItem(_t("Configure desktopgui"));
desktopguiConfigurationLauncher.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
new DesktopguiConfigurationFrame().setVisible(true);
return null;
}
}.execute();
}
});
MenuItem restartItem = new MenuItem(_t("Restart I2P"));
restartItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.restart();
return null;
}
}.execute();
}
});
MenuItem stopItem = new MenuItem(_t("Stop I2P"));
stopItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
RouterManager.shutDown();
return null;
}
}.execute();
}
});
popup.add(browserLauncher);
popup.addSeparator();
popup.add(desktopguiConfigurationLauncher);
popup.addSeparator();
popup.add(restartItem);
popup.add(stopItem);
return popup;
}
}

View File

@ -5,91 +5,121 @@ package net.i2p.desktopgui;
*/
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import net.i2p.I2PAppContext;
import net.i2p.app.ClientAppManager;
import net.i2p.app.ClientAppState;
import static net.i2p.app.ClientAppState.*;
import net.i2p.desktopgui.router.RouterManager;
import net.i2p.desktopgui.util.*;
import net.i2p.router.RouterContext;
import net.i2p.router.app.RouterApp;
import net.i2p.util.Log;
import net.i2p.util.SystemVersion;
import net.i2p.util.Translate;
import net.i2p.util.I2PProperties.I2PPropertyCallback;
/**
* The main class of the application.
*/
public class Main {
public class Main implements RouterApp {
///Manages the lifetime of the tray icon.
private TrayManager trayManager = null;
private final static Log log = new Log(Main.class);
private final I2PAppContext _appContext;
private final RouterContext _context;
private final ClientAppManager _mgr;
private final Log log;
private ClientAppState _state = UNINITIALIZED;
private TrayManager _trayManager;
public static final String PROP_ENABLE = "desktopgui.enabled";
private static final String PROP_SWING = "desktopgui.swing";
/**
* @since 0.9.26
*/
public Main(RouterContext ctx, ClientAppManager mgr, String args[]) {
_appContext = _context = ctx;
_mgr = mgr;
log = _appContext.logManager().getLog(Main.class);
_state = INITIALIZED;
}
/**
* @since 0.9.26
*/
public Main() {
_appContext = I2PAppContext.getGlobalContext();
if (_appContext instanceof RouterContext)
_context = (RouterContext) _appContext;
else
_context = null;
_mgr = null;
log = _appContext.logManager().getLog(Main.class);
_state = INITIALIZED;
}
/**
* Start the tray icon code (loads tray icon in the tray area).
* @throws Exception
* @throws AWTException on startup error, including systray not supported
*/
public void startUp() throws Exception {
trayManager = TrayManager.getInstance();
private synchronized void startUp() throws Exception {
final TrayManager trayManager;
boolean useSwing = _appContext.getProperty(PROP_SWING, !SystemVersion.isWindows());
if (_context != null)
trayManager = new InternalTrayManager(_context, this, useSwing);
else
trayManager = new ExternalTrayManager(_appContext, this, useSwing);
trayManager.startManager();
_trayManager = trayManager;
changeState(RUNNING);
if (_mgr != null)
_mgr.register(this);
if(RouterManager.inI2P()) {
RouterManager.getRouterContext().addPropertyCallback(new I2PPropertyCallback() {
if (_context != null) {
_context.addPropertyCallback(new I2PPropertyCallback() {
@Override
public void propertyChanged(String arg0, String arg1) {
if(arg0.equals(Translate.PROP_LANG)) {
trayManager.languageChanged();
}
}
});
}
}
public static void main(String[] args) {
beginStartup(args);
Main main = new Main();
main.beginStartup(args);
}
/**
* Main method launching the application.
*
* @param args unused
*/
public static void beginStartup(String[] args) {
try {
private void beginStartup(String[] args) {
changeState(STARTING);
String headless = System.getProperty("java.awt.headless");
boolean isHeadless = Boolean.parseBoolean(headless);
if (isHeadless) {
log.warn("Headless environment: not starting desktopgui!");
changeState(START_FAILED, "Headless environment: not starting desktopgui!", null);
return;
}
}
catch(Exception e) {
return;
}
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
log.log(Log.ERROR, null, ex);
} catch (InstantiationException ex) {
log.log(Log.ERROR, null, ex);
} catch (IllegalAccessException ex) {
log.log(Log.ERROR, null, ex);
} catch (UnsupportedLookAndFeelException ex) {
log.log(Log.ERROR, null, ex);
}
ConfigurationManager.getInstance().loadArguments(args);
// TODO process args with getopt if needed
final Main main = new Main();
main.launchForeverLoop();
if (_context == null)
launchForeverLoop();
//We'll be doing GUI work, so let's stay in the event dispatcher thread.
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
main.startUp();
}
catch(Exception e) {
startUp();
} catch(Exception e) {
log.error("Failed while running desktopgui!", e);
changeState(START_FAILED, "Failed while running desktopgui!", e);
}
}
@ -102,7 +132,7 @@ public class Main {
* Avoids the app terminating because no Window is opened anymore.
* More info: http://java.sun.com/javase/6/docs/api/java/awt/doc-files/AWTThreadIssues.html#Autoshutdown
*/
public void launchForeverLoop() {
private static void launchForeverLoop() {
Runnable r = new Runnable() {
public void run() {
try {
@ -114,9 +144,60 @@ public class Main {
}
}
};
Thread t = new Thread(r);
Thread t = new Thread(r, "DesktopGUI spinner");
t.setDaemon(false);
t.start();
}
/////// ClientApp methods
/** @since 0.9.26 */
public synchronized void startup() {
beginStartup(null);
}
/** @since 0.9.26 */
public synchronized void shutdown(String[] args) {
if (_state == STOPPED)
return;
changeState(STOPPING);
if (_trayManager != null)
_trayManager.stopManager();
changeState(STOPPED);
}
/** @since 0.9.26 */
public synchronized ClientAppState getState() {
return _state;
}
/** @since 0.9.26 */
public String getName() {
return "desktopgui";
}
/** @since 0.9.26 */
public String getDisplayName() {
return "Desktop GUI";
}
/////// end ClientApp methods
/** @since 0.9.26 */
private void changeState(ClientAppState state) {
changeState(state, null, null);
}
/** @since 0.9.26 */
private synchronized void changeState(ClientAppState state, String msg, Exception e) {
_state = state;
if (_mgr != null)
_mgr.notify(this, state, msg, e);
if (_context == null) {
if (msg != null)
System.out.println(state + ": " + msg);
if (e != null)
e.printStackTrace();
}
}
}

View File

@ -1,65 +1,160 @@
package net.i2p.desktopgui;
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Image;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.URL;
import javax.swing.JFrame;
import javax.swing.JPopupMenu;
import javax.swing.event.MenuKeyEvent;
import javax.swing.event.MenuKeyListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import net.i2p.I2PAppContext;
import net.i2p.desktopgui.i18n.DesktopguiTranslator;
import net.i2p.desktopgui.router.RouterManager;
import net.i2p.util.Log;
import net.i2p.util.SystemVersion;
/**
* Manages the tray icon life.
*/
public abstract class TrayManager {
abstract class TrayManager {
private static TrayManager instance = null;
protected final I2PAppContext _appContext;
protected final Main _main;
protected final boolean _useSwing;
///The tray area, or null if unsupported
protected SystemTray tray = null;
protected SystemTray tray;
///Our tray icon, or null if unsupported
protected TrayIcon trayIcon = null;
private final static Log log = new Log(TrayManager.class);
protected TrayIcon trayIcon;
/**
* Instantiate tray manager.
*/
protected TrayManager() {}
protected static TrayManager getInstance() {
if(instance == null) {
boolean inI2P = RouterManager.inI2P();
if(inI2P) {
instance = new InternalTrayManager();
}
else {
instance = new ExternalTrayManager();
}
}
return instance;
protected TrayManager(I2PAppContext ctx, Main main, boolean useSwing) {
_appContext = ctx;
_main = main;
_useSwing = useSwing;
}
/**
* Add the tray icon to the system tray and start everything up.
*/
protected void startManager() {
if(SystemTray.isSupported()) {
public synchronized void startManager() throws AWTException {
if (!SystemTray.isSupported())
throw new AWTException("SystemTray not supported");
tray = SystemTray.getSystemTray();
trayIcon = new TrayIcon(getTrayImage(), "I2P", getMainMenu());
trayIcon.setImageAutoSize(true); //Resize image to fit the system tray
try {
tray.add(trayIcon);
} catch (AWTException e) {
log.log(Log.WARN, "Problem creating system tray icon!", e);
// Windows typically has tooltips; Linux (at least Ubuntu) doesn't
String tooltip = SystemVersion.isWindows() ? _t("I2P: Right-click for menu") : null;
TrayIcon ti;
if (_useSwing)
ti = getSwingTrayIcon(tooltip);
else
ti = getAWTTrayIcon(tooltip);
ti.setImageAutoSize(true); //Resize image to fit the system tray
tray.add(ti);
trayIcon = ti;
}
private TrayIcon getAWTTrayIcon(String tooltip) throws AWTException {
PopupMenu menu = getMainMenu();
if (!SystemVersion.isWindows())
menu.setFont(new Font("Arial", Font.BOLD, 14));
TrayIcon ti = new TrayIcon(getTrayImage(), tooltip, menu);
ti.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent m) {}
public void mouseEntered(MouseEvent m) {}
public void mouseExited(MouseEvent m) {}
public void mousePressed(MouseEvent m) { updateMenu(); }
public void mouseReleased(MouseEvent m) { updateMenu(); }
});
return ti;
}
private TrayIcon getSwingTrayIcon(String tooltip) throws AWTException {
// A JPopupMenu by itself is hard to get rid of,
// so we hang it off a zero-size, undecorated JFrame.
// http://stackoverflow.com/questions/1498789/jpopupmenu-behavior
// http://stackoverflow.com/questions/2581314/how-do-you-hide-a-swing-popup-when-you-click-somewhere-else
final JFrame frame = new JFrame();
// http://stackoverflow.com/questions/2011601/jframe-without-frame-border-maximum-button-minimum-button-and-frame-icon
frame.setUndecorated(true);
frame.setMinimumSize(new Dimension(0, 0));
frame.setSize(0, 0);
final JPopupMenu menu = getSwingMainMenu();
menu.setFocusable(true);
frame.add(menu);
TrayIcon ti = new TrayIcon(getTrayImage(), tooltip, null);
ti.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) { handle(e); }
public void mouseReleased(MouseEvent e) { handle(e); }
private void handle(MouseEvent e) {
// http://stackoverflow.com/questions/17258250/changing-the-laf-of-a-popupmenu-for-a-trayicon-in-java
// menu visible check is failsafe, for when menu gets cancelled
if (!frame.isVisible() || !menu.isVisible()) {
frame.setLocation(e.getX(), e.getY());
frame.setVisible(true);
menu.show(frame, 0, 0);
}
updateMenu();
}
});
menu.addPopupMenuListener(new PopupMenuListener() {
public void popupMenuCanceled(PopupMenuEvent e) { frame.setVisible(false); }
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
});
// this is to make it go away when we click elsewhere
// doesn't do anything
menu.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {}
public void focusLost(FocusEvent e) { frame.setVisible(false); }
});
// this is to make it go away when we hit escape
// doesn't do anything
menu.addMenuKeyListener(new MenuKeyListener() {
public void menuKeyPressed(MenuKeyEvent e) {}
public void menuKeyReleased(MenuKeyEvent e) {}
public void menuKeyTyped(MenuKeyEvent e) {
if (e.getKeyChar() == (char) 0x1b)
frame.setVisible(false);
}
});
return ti;
}
/**
* Remove the tray icon from the system tray
*
* @since 0.9.26
*/
public synchronized void stopManager() {
if (tray != null && trayIcon != null) {
tray.remove(trayIcon);
tray = null;
trayIcon = null;
}
}
protected void languageChanged() {
public synchronized void languageChanged() {
if (trayIcon != null) {
if (!_useSwing)
trayIcon.setPopupMenu(getMainMenu());
// else TODO
}
}
/**
@ -68,17 +163,40 @@ public abstract class TrayManager {
*/
protected abstract PopupMenu getMainMenu();
/**
* Build a popup menu, adding callbacks to the different items.
* @return popup menu
* @since 0.9.26
*/
protected abstract JPopupMenu getSwingMainMenu();
/**
* Update the menu
* @since 0.9.26
*/
protected abstract void updateMenu();
/**
* Get tray icon image from the desktopgui resources in the jar file.
* @return image used for the tray icon
* @throws AWTException if image not found
*/
private Image getTrayImage() {
private Image getTrayImage() throws AWTException {
URL url = getClass().getResource("/desktopgui/resources/images/logo.png");
if (url == null)
throw new AWTException("cannot load tray image");
Image image = Toolkit.getDefaultToolkit().getImage(url);
return image;
}
protected static String _t(String s) {
return DesktopguiTranslator._t(s);
protected String _t(String s) {
return DesktopguiTranslator._t(_appContext, s);
}
/**
* @since 0.9.26
*/
protected String _t(String s, Object o) {
return DesktopguiTranslator._t(_appContext, s, o);
}
}

View File

@ -1,131 +0,0 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/*
* ConfigurationFrame.java
*
* Created on Feb 16, 2011, 8:03:14 AM
*/
package net.i2p.desktopgui.gui;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.i2p.desktopgui.i18n.DesktopguiTranslator;
import net.i2p.desktopgui.router.RouterManager;
/**
*
* @author mathias
*/
public class DesktopguiConfigurationFrame extends javax.swing.JFrame {
/** Creates new form ConfigurationFrame */
public DesktopguiConfigurationFrame() {
initComponents();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
desktopguiEnabled = new javax.swing.JCheckBox();
okButton = new javax.swing.JButton();
cancelButton = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle(_t("Tray icon configuration"));
desktopguiEnabled.setSelected(true);
desktopguiEnabled.setText(_t("Should tray icon be enabled?"));
desktopguiEnabled.setActionCommand("shouldDesktopguiBeEnabled");
okButton.setText("OK");
okButton.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseReleased(java.awt.event.MouseEvent evt) {
okButtonMouseReleased(evt);
}
});
cancelButton.setText("Cancel");
cancelButton.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseReleased(java.awt.event.MouseEvent evt) {
cancelButtonMouseReleased(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(desktopguiEnabled)
.addGroup(layout.createSequentialGroup()
.addComponent(okButton)
.addGap(18, 18, 18)
.addComponent(cancelButton)))
.addContainerGap(237, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(desktopguiEnabled)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(okButton)
.addComponent(cancelButton))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void cancelButtonMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_cancelButtonMouseReleased
System.out.println("Cancelling configuration change.");
this.dispose();
}//GEN-LAST:event_cancelButtonMouseReleased
private void okButtonMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_okButtonMouseReleased
configureDesktopgui();
}//GEN-LAST:event_okButtonMouseReleased
protected static String _t(String s) {
return DesktopguiTranslator._t(s);
}
private void configureDesktopgui() {
String property = "desktopgui.enabled";
String value;
if(!desktopguiEnabled.isSelected()) {
value = "false";
System.out.println("Disabling desktopgui");
}
else {
value = "true";
System.out.println("Enabling desktopgui");
}
try {
RouterManager.getRouterContext().router().saveConfig(property, value);
} catch (Exception ex) {
Logger.getLogger(DesktopguiConfigurationFrame.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Applying desktopgui configuration!");
this.dispose();
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton cancelButton;
private javax.swing.JCheckBox desktopguiEnabled;
private javax.swing.JButton okButton;
// End of variables declaration//GEN-END:variables
}

View File

@ -7,20 +7,11 @@ public class DesktopguiTranslator {
private static final String BUNDLE_NAME = "net.i2p.desktopgui.messages";
private static I2PAppContext ctx;
private static I2PAppContext getRouterContext() {
if(ctx == null) {
ctx = I2PAppContext.getCurrentContext();
}
return ctx;
public static String _t(I2PAppContext ctx, String s) {
return Translate.getString(s, ctx, BUNDLE_NAME);
}
public static String _t(String s) {
return Translate.getString(s, getRouterContext(), BUNDLE_NAME);
}
public static String _t(String s, Object o) {
return Translate.getString(s, o, getRouterContext(), BUNDLE_NAME);
public static String _t(I2PAppContext ctx, String s, Object o) {
return Translate.getString(s, o, ctx, BUNDLE_NAME);
}
}

View File

@ -2,43 +2,26 @@ package net.i2p.desktopgui.router;
import java.io.IOException;
import org.tanukisoftware.wrapper.WrapperManager;
import net.i2p.I2PAppContext;
import net.i2p.router.Router;
import net.i2p.router.RouterContext;
//import net.i2p.router.web.ConfigServiceHandler;
import net.i2p.util.Log;
/**
* Handle communications with the router instance.
*
* See ConfigServiceHandler for best practices on stopping the router.
* We don't bother notifying any Wrapper instance here.
*
* @author mathias
*
*/
public class RouterManager {
private final static Log log = new Log(RouterManager.class);
private static I2PAppContext context = I2PAppContext.getCurrentContext();
public static I2PAppContext getAppContext() {
return context;
}
public static RouterContext getRouterContext() throws Exception {
if(context.isRouterContext()) {
return (RouterContext) context;
}
else {
throw new Exception("No RouterContext available!");
}
}
private static Router getRouter() {
try {
return getRouterContext().router();
} catch (Exception e) {
log.error("Failed to get router. Why did we request it if no RouterContext is available?", e);
return null;
}
/** @return non-null */
private static I2PAppContext getAppContext() {
return I2PAppContext.getGlobalContext();
}
/**
@ -53,9 +36,10 @@ public class RouterManager {
//TODO: set/get PID
String separator = System.getProperty("file.separator");
String location = getAppContext().getBaseDir().getAbsolutePath();
Runtime.getRuntime().exec(location + separator + "i2psvc " + location + separator + "wrapper.config");
String[] args = new String[] { location + separator + "i2psvc", location + separator + "wrapper.config" };
Runtime.getRuntime().exec(args);
} catch (IOException e) {
Log log = getAppContext().logManager().getLog(RouterManager.class);
log.log(Log.WARN, "Failed to start I2P", e);
}
}
@ -63,34 +47,71 @@ public class RouterManager {
/**
* Restart the running I2P instance.
*/
public static void restart() {
if(inI2P()) {
getRouter().restart();
}
public static void restart(RouterContext ctx) {
//if (ctx.hasWrapper())
// ConfigServiceHandler.registerWrapperNotifier(ctx, Router.EXIT_HARD_RESTART, false);
ctx.router().shutdownGracefully(Router.EXIT_HARD_RESTART);
}
/**
* Stop the running I2P instance.
*/
public static void shutDown() {
if(inI2P()) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
WrapperManager.signalStopped(Router.EXIT_HARD);
}
});
t.start();
getRouter().shutdown(Router.EXIT_HARD);
}
public static void shutDown(RouterContext ctx) {
//if (ctx.hasWrapper())
// ConfigServiceHandler.registerWrapperNotifier(ctx, Router.EXIT_HARD, false);
ctx.router().shutdownGracefully(Router.EXIT_HARD);
}
/**
* Check if we are running inside I2P.
* Restart the running I2P instance.
* @since 0.9.26
*/
public static boolean inI2P() {
return context.isRouterContext();
public static void restartGracefully(RouterContext ctx) {
//if (ctx.hasWrapper())
// ConfigServiceHandler.registerWrapperNotifier(ctx, Router.EXIT_GRACEFUL_RESTART, false);
ctx.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART);
}
/**
* Stop the running I2P instance.
* @since 0.9.26
*/
public static void shutDownGracefully(RouterContext ctx) {
//if (ctx.hasWrapper())
// ConfigServiceHandler.registerWrapperNotifier(ctx, Router.EXIT_GRACEFUL, false);
ctx.router().shutdownGracefully();
}
/**
* Cancel a graceful shutdown or restart
* @since 0.9.26
*/
public static void cancelShutdown(RouterContext ctx) {
ctx.router().cancelGracefulShutdown();
}
/**
* Is a graceful shutdown or restart in progress?
* @since 0.9.26
*/
public static boolean isShutdownInProgress(RouterContext ctx) {
return ctx.router().scheduledGracefulExitCode() > 0;
}
/**
* Get time until shutdown
* @return -1 if no shutdown in progress.
* @since 0.9.26
*/
public static long getShutdownTimeRemaining(RouterContext ctx) {
return ctx.router().getShutdownTimeRemaining();
}
/**
* Get network status, untranslated
* @since 0.9.26
*/
public static String getStatus(RouterContext ctx) {
return ctx.commSystem().getStatus().toStatusString();
}
}

View File

@ -1,103 +0,0 @@
package net.i2p.desktopgui.util;
import java.util.HashMap;
import java.util.Map;
/**
* Manage the configuration of desktopgui.
* @author mathias
*
*/
public class ConfigurationManager {
private static ConfigurationManager instance;
///Configurations with a String as value
private Map<String, String> stringConfigurations = new HashMap<String, String>();
///Configurations with a Boolean as value
private Map<String, Boolean> booleanConfigurations = new HashMap<String, Boolean>();
private ConfigurationManager() {}
public static ConfigurationManager getInstance() {
if(instance == null) {
instance = new ConfigurationManager();
}
return instance;
}
/**
* Collects arguments of the form --word, --word=otherword and -blah
* to determine user parameters.
* @param args Command line arguments to the application
*/
public void loadArguments(String[] args) {
for(int i=0; i<args.length; i++) {
String arg = args[i];
if(arg.startsWith("--")) {
arg = arg.substring(2);
if(arg.length() < 1) {
continue;
}
int equals = arg.indexOf('=');
if(equals != -1 && equals < arg.length() - 1) { //String configuration
loadStringConfiguration(arg, equals);
}
else { //Boolean configuration
loadBooleanConfiguration(arg);
}
}
else if(arg.startsWith("-")) { //Boolean configuration
loadBooleanConfiguration(arg);
}
}
}
/**
* Add a boolean configuration.
* @param arg The key we wish to add as a configuration.
*/
public void loadBooleanConfiguration(String arg) {
booleanConfigurations.put(arg, Boolean.TRUE);
}
/**
* Add a String configuration which consists a key and a value.
* @param arg String of the form substring1=substring2.
* @param equalsPosition Position of the '=' element.
*/
public void loadStringConfiguration(String arg, int equalsPosition) {
String key = arg.substring(0, equalsPosition);
String value = arg.substring(equalsPosition+1);
stringConfigurations.put(key, value);
}
/**
* Check if a specific boolean configuration exists.
* @param arg The key for the configuration.
* @param defaultValue If the configuration is not found, we use a default value.
* @return The value of a configuration: true if found, defaultValue if not found.
*/
public boolean getBooleanConfiguration(String arg, boolean defaultValue) {
Boolean value = booleanConfigurations.get("startWithI2P");
System.out.println(value);
if(value != null) {
return value;
}
return defaultValue;
}
/**
* Get a specific String configuration.
* @param arg The key for the configuration.
* @param defaultValue If the configuration is not found, we use a default value.
* @return The value of the configuration, or the defaultValue.
*/
public String getStringConfiguration(String arg, String defaultValue) {
String value = stringConfigurations.get(arg);
System.out.println(value);
if(value != null) {
return value;
}
return defaultValue;
}
}

View File

@ -3,12 +3,9 @@ package net.i2p.desktopgui.util;
import java.awt.Desktop;
import java.awt.Desktop.Action;
import java.net.URI;
import net.i2p.util.Log;
public class I2PDesktop {
private final static Log log = new Log(I2PDesktop.class);
public static void browse(String url) throws BrowseException {
if(Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();

View File

@ -137,6 +137,7 @@
</target>
<target name="bundle" depends="compile" unless="no.bundle">
<mkdir dir="build/messages-src" />
<!-- Update the messages_*.po files.
We need to supply the bat file for windows, and then change the fail property to true -->
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
@ -150,6 +151,11 @@
<exec executable="sh" osfamily="windows" failifexecutionfails="false" >
<arg value="./bundle-messages.sh" />
</exec>
<javac source="${javac.version}" target="${javac.version}"
includeAntRuntime="false"
srcdir="build/messages-src" destdir="build/obj">
<compilerarg line="${javac.compilerargs}" />
</javac>
</target>
<target name="poupdate" depends="builddep, compile">

View File

@ -96,9 +96,31 @@ do
# only generate for non-source language
echo "Generating ${CLASS}_$LG ResourceBundle..."
msgfmt -V | grep -q '0\.19'
if [ $? -ne 0 ]
then
# slow way
# convert to class files in build/obj
msgfmt --java --statistics -r $CLASS -l $LG -d build/obj $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
find build -name messages_${LG}.class -exec rm -f {} \;
RC=1
break
fi
else
# fast way
# convert to java files in build/messages-src
TD=build/messages-src-tmp
TDX=$TD/org/klomp/snark/web
TD2=build/messages-src
TDY=$TD2/org/klomp/snark/web
rm -rf $TD
mkdir -p $TD $TDY
msgfmt --java --statistics --source -r $CLASS -l $LG -d $TD $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
@ -106,6 +128,9 @@ do
RC=1
break
fi
mv $TDX/messages_$LG.java $TDY
rm -rf $TD
fi
fi
done
rm -f $TMPFILE

View File

@ -123,6 +123,7 @@
<!-- servlet translations go in the war, not the jar -->
<target name="bundle" depends="compile, precompilejsp" unless="no.bundle">
<mkdir dir="build/messages-src" />
<!-- Update the messages_*.po files.
We need to supply the bat file for windows, and then change the fail property to true -->
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
@ -136,6 +137,11 @@
<exec executable="sh" osfamily="windows" failifexecutionfails="false" >
<arg value="./bundle-messages.sh" />
</exec>
<javac source="${javac.version}" target="${javac.version}"
includeAntRuntime="false"
srcdir="build/messages-src" destdir="../jsp/WEB-INF/classes">
<compilerarg line="${javac.compilerargs}" />
</javac>
</target>
<target name="poupdate" depends="compile, precompilejsp">
@ -156,6 +162,7 @@
<!-- proxy error page translations go in the jar, not the war -->
<target name="bundle-proxy" unless="no.bundle">
<mkdir dir="build/messages-proxy-src" />
<!-- Update the messages_*.po files.
We need to supply the bat file for windows, and then change the fail property to true -->
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
@ -169,6 +176,11 @@
<exec executable="sh" osfamily="windows" failifexecutionfails="false" >
<arg value="./bundle-messages-proxy.sh" />
</exec>
<javac source="${javac.version}" target="${javac.version}"
includeAntRuntime="false"
srcdir="build/messages-proxy-src" destdir="build/obj">
<compilerarg line="${javac.compilerargs}" />
</javac>
</target>
<target name="extractProxyTags">

View File

@ -98,9 +98,31 @@ do
# only generate for non-source language
echo "Generating ${CLASS}_$LG ResourceBundle..."
msgfmt -V | grep -q '0\.19'
if [ $? -ne 0 ]
then
# slow way
# convert to class files in build/obj
msgfmt --java --statistics -r $CLASS -l $LG -d build/obj $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
find build -name messages_${LG}.class -exec rm -f {} \;
RC=1
break
fi
else
# fast way
# convert to java files in build/messages-proxy-src
TD=build/messages-proxy-src-tmp
TDX=$TD/net/i2p/i2ptunnel/proxy
TD2=build/messages-proxy-src
TDY=$TD2/net/i2p/i2ptunnel/proxy
rm -rf $TD
mkdir -p $TD $TDY
msgfmt --java --statistics --source -r $CLASS -l $LG -d $TD $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
@ -108,6 +130,9 @@ do
RC=1
break
fi
mv $TDX/messages_$LG.java $TDY
rm -rf $TD
fi
fi
done
rm -f $TMPFILE

View File

@ -97,9 +97,31 @@ do
# only generate for non-source language
echo "Generating ${CLASS}_$LG ResourceBundle..."
# convert to class files in build/obj
msgfmt -V | grep -q '0\.19'
if [ $? -ne 0 ]
then
# slow way
# convert to class files in jsp/WEB-INF/classes
msgfmt --java --statistics -r $CLASS -l $LG -d ../jsp/WEB-INF/classes $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
find build -name messages_${LG}.class -exec rm -f {} \;
RC=1
break
fi
else
# fast way
# convert to java files in build/messages-src
TD=build/messages-src-tmp
TDX=$TD/net/i2p/i2ptunnel/web
TD2=build/messages-src
TDY=$TD2/net/i2p/i2ptunnel/web
rm -rf $TD
mkdir -p $TD $TDY
msgfmt --java --statistics --source -r $CLASS -l $LG -d $TD $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
@ -107,6 +129,9 @@ do
RC=1
break
fi
mv $TDX/messages_$LG.java $TDY
rm -rf $TD
fi
fi
done
rm -f $TMPFILE

View File

@ -100,6 +100,7 @@
</target>
<target name="bundle" depends="compile" unless="no.bundle">
<mkdir dir="build/messages-src" />
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
<env key="JAVA_HOME" value="${java.home}" />
<arg value="./bundle-messages.sh" />
@ -110,6 +111,11 @@
<exec executable="sh" osfamily="windows" failifexecutionfails="false" >
<arg value="./bundle-messages.sh" />
</exec>
<javac source="${javac.version}" target="${javac.version}"
includeAntRuntime="false"
srcdir="build/messages-src" destdir="build/obj">
<compilerarg line="${javac.compilerargs}" />
</javac>
</target>
<target name="poupdate" depends="builddep, compile">

View File

@ -96,9 +96,31 @@ do
# only generate for non-source language
echo "Generating ${CLASS}_$LG ResourceBundle..."
msgfmt -V | grep -q '0\.19'
if [ $? -ne 0 ]
then
# slow way
# convert to class files in build/obj
msgfmt --java --statistics -r $CLASS -l $LG -d build/obj $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
find build -name messages_${LG}.class -exec rm -f {} \;
RC=1
break
fi
else
# fast way
# convert to java files in build/messages-src
TD=build/messages-src-tmp
TDX=$TD/net/i2p/client/streaming
TD2=build/messages-src
TDY=$TD2/net/i2p/client/streaming
rm -rf $TD
mkdir -p $TD $TDY
msgfmt --java --statistics --source -r $CLASS -l $LG -d $TD $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
@ -106,6 +128,9 @@ do
RC=1
break
fi
mv $TDX/messages_$LG.java $TDY
rm -rf $TD
fi
fi
done
rm -f $TMPFILE

View File

@ -145,6 +145,7 @@
<!-- this is tricky because the message classes go in the jar, not in the war -->
<target name="bundle" depends="jar1, precompilejsp" unless="no.bundle">
<mkdir dir="build/messages-src" />
<!-- Update the messages_*.po files.
We need to supply the bat file for windows, and then change the fail property to true -->
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
@ -158,6 +159,11 @@
<exec executable="sh" osfamily="windows" failifexecutionfails="false" >
<arg value="./bundle-messages.sh" />
</exec>
<javac source="${javac.version}" target="${javac.version}"
includeAntRuntime="false"
srcdir="build/messages-src" destdir="build/obj">
<compilerarg line="${javac.compilerargs}" />
</javac>
<!-- jar again to get the latest messages_*.class files -->
<jar destfile="./build/routerconsole.jar" basedir="./build/obj" includes="**/*.class" update="true" />
</target>
@ -194,6 +200,7 @@
</target>
<target name="bundle-news" unless="no.bundle">
<mkdir dir="build/messages-news-src" />
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
<env key="JAVA_HOME" value="${java.home}" />
<arg value="./bundle-messages-news.sh" />
@ -204,9 +211,15 @@
<exec executable="sh" osfamily="windows" failifexecutionfails="false" >
<arg value="./bundle-messages-news.sh" />
</exec>
<javac source="${javac.version}" target="${javac.version}"
includeAntRuntime="false"
srcdir="build/messages-news-src" destdir="build/obj">
<compilerarg line="${javac.compilerargs}" />
</javac>
</target>
<target name="bundle-countries" unless="no.bundle">
<mkdir dir="build/messages-countries-src" />
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
<env key="JAVA_HOME" value="${java.home}" />
<arg value="./bundle-messages-countries.sh" />
@ -217,6 +230,11 @@
<exec executable="sh" osfamily="windows" failifexecutionfails="false" >
<arg value="./bundle-messages-countries.sh" />
</exec>
<javac source="${javac.version}" target="${javac.version}"
includeAntRuntime="false"
srcdir="build/messages-countries-src" destdir="build/obj">
<compilerarg line="${javac.compilerargs}" />
</javac>
</target>
<target name="extractProxyTags">

View File

@ -112,9 +112,31 @@ do
# only generate for non-source language
echo "Generating ${CLASS}_$LG ResourceBundle..."
msgfmt -V | grep -q '0\.19'
if [ $? -ne 0 ]
then
# slow way
# convert to class files in build/obj
msgfmt --java --statistics -r $CLASS -l $LG -d build/obj $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
find build -name messages_${LG}.class -exec rm -f {} \;
RC=1
break
fi
else
# fast way
# convert to java files in build/messages-countries-src
TD=build/messages-countries-src-tmp
TDX=$TD/net/i2p/router/countries
TD2=build/messages-countries-src
TDY=$TD2/net/i2p/router/countries
rm -rf $TD
mkdir -p $TD $TDY
msgfmt --java --statistics --source -r $CLASS -l $LG -d $TD $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
@ -122,6 +144,9 @@ do
RC=1
break
fi
mv $TDX/messages_$LG.java $TDY
rm -rf $TD
fi
fi
done
rm -f $TMPFILE

View File

@ -98,9 +98,31 @@ do
# only generate for non-source language
echo "Generating ${CLASS}_$LG ResourceBundle..."
msgfmt -V | grep -q '0\.19'
if [ $? -ne 0 ]
then
# slow way
# convert to class files in build/obj
msgfmt --java --statistics -r $CLASS -l $LG -d build/obj $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
find build -name messages_${LG}.class -exec rm -f {} \;
RC=1
break
fi
else
# fast way
# convert to java files in build/messages-news-src
TD=build/messages-news-src-tmp
TDX=$TD/net/i2p/router/news
TD2=build/messages-news-src
TDY=$TD2/net/i2p/router/news
rm -rf $TD
mkdir -p $TD $TDY
msgfmt --java --statistics --source -r $CLASS -l $LG -d $TD $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
@ -108,6 +130,9 @@ do
RC=1
break
fi
mv $TDX/messages_$LG.java $TDY
rm -rf $TD
fi
fi
done
rm -f $TMPFILE

View File

@ -125,9 +125,31 @@ do
# only generate for non-source language
echo "Generating ${CLASS}_$LG ResourceBundle..."
msgfmt -V | grep -q '0\.19'
if [ $? -ne 0 ]
then
# slow way
# convert to class files in build/obj
msgfmt --java --statistics -r $CLASS -l $LG -d build/obj $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
find build -name messages_${LG}.class -exec rm -f {} \;
RC=1
break
fi
else
# fast way
# convert to java files in build/messages-src
TD=build/messages-src-tmp
TDX=$TD/net/i2p/router/web
TD2=build/messages-src
TDY=$TD2/net/i2p/router/web
rm -rf $TD
mkdir -p $TD $TDY
msgfmt --java --statistics --source -r $CLASS -l $LG -d $TD $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
@ -135,6 +157,9 @@ do
RC=1
break
fi
mv $TDX/messages_$LG.java $TDY
rm -rf $TD
fi
fi
done
rm -f $TMPFILE

View File

@ -5,6 +5,9 @@ import java.io.IOException;
import java.util.List;
import java.util.Properties;
import net.i2p.app.ClientApp;
import net.i2p.app.ClientAppManager;
import net.i2p.app.ClientAppState;
import net.i2p.apps.systray.UrlLauncher;
import net.i2p.router.Router;
import net.i2p.router.RouterContext;
@ -191,6 +194,26 @@ public class ConfigServiceHandler extends FormHandler {
return _context.router().gracefulShutdownInProgress();
}
/**
* Should we show the systray controls?
*
* @since 0.9.26
*/
public boolean shouldShowSystray() {
return !
(RouterConsoleRunner.DAEMON_USER.equals(System.getProperty("user.name")) ||
(SystemVersion.isWindows() && _context.hasWrapper() && WrapperManager.isLaunchedAsService()));
}
/**
* Is the systray enabled?
*
* @since 0.9.26
*/
public boolean isSystrayEnabled() {
return _context.getBooleanProperty(RouterConsoleRunner.PROP_DTG_ENABLED);
}
@Override
protected void processForm() {
if (_action == null) return;
@ -249,6 +272,10 @@ public class ConfigServiceHandler extends FormHandler {
} else if (_t("Force GC").equals(_action)) {
Runtime.getRuntime().gc();
addFormNotice(_t("Full garbage collection requested"));
} else if (_t("Show systray icon").equals(_action)) {
changeSystray(true);
} else if (_t("Hide systray icon").equals(_action)) {
changeSystray(false);
} else {
//addFormNotice("Blah blah blah. whatever. I'm not going to " + _action);
}
@ -292,4 +319,41 @@ public class ConfigServiceHandler extends FormHandler {
}
ClientAppConfig.writeClientAppConfig(_context, clients);
}
/**
* Enable/disable and start/stop systray
*
* @since 0.9.26
*/
private void changeSystray(boolean enable) {
ClientAppManager mgr = _context.clientAppManager();
if (mgr != null) {
try {
ClientApp dtg = mgr.getRegisteredApp("desktopgui");
if (dtg != null) {
if (enable) {
if (dtg.getState() == ClientAppState.STOPPED)
dtg.startup();
} else {
if (dtg.getState() == ClientAppState.RUNNING)
dtg.shutdown(null);
}
} else if (enable) {
dtg = new net.i2p.desktopgui.Main(_context, mgr, null);
dtg.startup();
}
} catch (Throwable t) {
if (enable)
addFormError(_t("Failed to start systray") + ": " + t);
else
addFormError(_t("Failed to stop systray") + ": " + t);
}
}
boolean saved = _context.router().saveConfig(RouterConsoleRunner.PROP_DTG_ENABLED, Boolean.toString(enable));
if (saved)
addFormNotice(_t("Configuration saved successfully"));
else
addFormError(_t("Error saving the configuration (applied but not saved) - please see the error logs"));
}
}

View File

@ -39,6 +39,7 @@ import net.i2p.util.PortMapper;
import net.i2p.util.SecureDirectory;
import net.i2p.util.I2PSSLSocketFactory;
import net.i2p.util.SystemVersion;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
@ -69,6 +70,8 @@ import org.eclipse.jetty.util.thread.ExecutorThreadPool;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ThreadPool;
import org.tanukisoftware.wrapper.WrapperManager;
/**
* Start the router console.
*/
@ -128,6 +131,8 @@ public class RouterConsoleRunner implements RouterApp {
private static final int MAX_THREADS = 24;
private static final int MAX_IDLE_TIME = 90*1000;
private static final String THREAD_NAME = "RouterConsole Jetty";
public static final String DAEMON_USER = "i2psvc";
public static final String PROP_DTG_ENABLED = "desktopgui.enabled";
/**
* <pre>
@ -213,7 +218,7 @@ public class RouterConsoleRunner implements RouterApp {
public synchronized void startup() {
changeState(STARTING);
checkJavaVersion();
startTrayApp(_context);
startTrayApp();
startConsole();
}
@ -265,18 +270,23 @@ public class RouterConsoleRunner implements RouterApp {
return _server;
}
private static void startTrayApp(I2PAppContext ctx) {
private void startTrayApp() {
// if no permissions, don't even try
// isLaunchedAsService() always returns true on Linux
if (DAEMON_USER.equals(System.getProperty("user.name")) ||
(SystemVersion.isWindows() && _context.hasWrapper() && WrapperManager.isLaunchedAsService())) {
// required true for jrobin to work
System.setProperty("java.awt.headless", "true");
return;
}
try {
//TODO: move away from routerconsole into a separate application.
//ApplicationManager?
boolean recentJava = SystemVersion.isJava6();
// default false for now
boolean desktopguiEnabled = ctx.getBooleanProperty("desktopgui.enabled");
if (recentJava && desktopguiEnabled) {
boolean desktopguiEnabled = _context.getBooleanProperty(PROP_DTG_ENABLED);
if (desktopguiEnabled) {
//Check if we are in a headless environment, set properties accordingly
System.setProperty("java.awt.headless", Boolean.toString(GraphicsEnvironment.isHeadless()));
String[] args = new String[0];
net.i2p.desktopgui.Main.beginStartup(args);
net.i2p.desktopgui.Main dtg = new net.i2p.desktopgui.Main(_context, _mgr, null);
dtg.startup();
} else {
// required true for jrobin to work
System.setProperty("java.awt.headless", "true");

View File

@ -41,24 +41,28 @@
<input type="submit" class="reload" name="action" value="<%=intl._t("Hard restart")%>" >
<% } %></div>
<% if ( (System.getProperty("os.name") != null) && (System.getProperty("os.name").startsWith("Win")) ) { %>
<% if (formhandler.shouldShowSystray()) { %>
<h3 class="ptitle" id="systray"><%=intl._t("Systray integration")%></h3>
<p class="infohelp">
<%=intl._t("On the windows platform, there is a small application to sit in the system tray, allowing you to view the router's status")%>
<%=intl._t("(later on, I2P client applications will be able to integrate their own functionality into the system tray as well).")%>
<%=intl._t("If you are on windows, you can either enable or disable that icon here.")%></p>
<p class="infohelp"><%=intl._t("Control the system tray icon")%></p>
<hr><div class="formaction" id="systray">
<input type="submit" name="action" value="<%=intl._t("Show systray icon")%>" >
<input type="submit" name="action" value="<%=intl._t("Hide systray icon")%>" >
<% if (!formhandler.isSystrayEnabled()) { %>
<input type="submit" name="action" class="accept" value="<%=intl._t("Show systray icon")%>" >
<% } else {%>
<input type="submit" name="action" class="cancel" value="<%=intl._t("Hide systray icon")%>" >
<% } %>
</div>
<%
}
if ( (System.getProperty("os.name") != null) && (System.getProperty("os.name").startsWith("Win")) ) { %>
%>
<h3 class="ptitle" id="runonstartup"><%=intl._t("Run on startup")%></h3>
<p class="infohelp">
<%=intl._t("You can control whether I2P is run on startup or not by selecting one of the following options - I2P will install (or remove) a service accordingly.")%>
<%=intl._t("If you prefer the command line, you can also run the ")%> <code>install_i2p_service_winnt.bat</code> (<%=intl._t("or")%>
<code>uninstall_i2p_service_winnt.bat</code>).</p>
<hr><div class="formaction" id="runonstart">
<input type="submit" name="action" value="<%=intl._t("Run I2P on startup")%>" >
<input type="submit" name="action" value="<%=intl._t("Don't run I2P on startup")%>" ></div>
<input type="submit" name="action" class="accept" value="<%=intl._t("Run I2P on startup")%>" >
<input type="submit" name="action" class="cancel" value="<%=intl._t("Don't run I2P on startup")%>" ></div>
<p class="infohelp" id="winfoservice"><b>
<%=intl._t("Note")%>:</b> <%=intl._t("If you are running I2P as service right now, removing it will shut down your router immediately.")%>
<%=intl._t("You may want to consider shutting down gracefully, as above, then running uninstall_i2p_service_winnt.bat.")%></p>

View File

@ -136,6 +136,7 @@
</target>
<target name="bundle" depends="compile, precompilejsp" unless="no.bundle">
<mkdir dir="build/messages-src" />
<!-- Update the messages_*.po files.
We need to supply the bat file for windows, and then change the fail property to true -->
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
@ -149,6 +150,11 @@
<exec executable="sh" osfamily="windows" failifexecutionfails="false" >
<arg value="./bundle-messages.sh" />
</exec>
<javac source="${javac.version}" target="${javac.version}"
includeAntRuntime="false"
srcdir="build/messages-src" destdir="${bin}">
<compilerarg line="${javac.compilerargs}" />
</javac>
</target>
<target name="poupdate" depends="compile, precompilejsp">
@ -171,7 +177,7 @@
<delete file="susidns.war" />
<delete>
<fileset dir="." includes="**/*.class" />
<fileset dir="." includes="tmp" />
<fileset dir="." includes="tmp, build" />
<fileset dir="WEB-INF" includes="web-fragment.xml, web-out.xml" />
</delete>
<delete dir="${bin}" />

View File

@ -98,9 +98,31 @@ do
# only generate for non-source language
echo "Generating ${CLASS}_$LG ResourceBundle..."
# convert to class files in build/obj
msgfmt -V | grep -q '0\.19'
if [ $? -ne 0 ]
then
# slow way
# convert to class files in WEB-INF/classes
msgfmt --java --statistics -r $CLASS -l $LG -d WEB-INF/classes $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
find src/WEB-INF/classes -name messages_${LG}.class -exec rm -f {} \;
RC=1
break
fi
else
# fast way
# convert to java files in build/messages-src
TD=build/messages-src-tmp
TDX=$TD/i2p/susi/dns
TD2=build/messages-src
TDY=$TD2/i2p/susi/dns
rm -rf $TD
mkdir -p $TD $TDY
msgfmt --java --statistics --source -r $CLASS -l $LG -d $TD $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
@ -108,6 +130,9 @@ do
RC=1
break
fi
mv $TDX/messages_$LG.java $TDY
rm -rf $TD
fi
fi
done
rm -f $TMPFILE

View File

@ -100,6 +100,7 @@
</target>
<target name="bundle" depends="compile" unless="no.bundle">
<mkdir dir="build/messages-src" />
<!-- Update the messages_*.po files.
We need to supply the bat file for windows, and then change the fail property to true -->
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
@ -113,6 +114,11 @@
<exec executable="sh" osfamily="windows" failifexecutionfails="false" >
<arg value="./bundle-messages.sh" />
</exec>
<javac source="${javac.version}" target="${javac.version}"
includeAntRuntime="false"
srcdir="build/messages-src" destdir="src/WEB-INF/classes">
<compilerarg line="${javac.compilerargs}" />
</javac>
</target>
<target name="poupdate" depends="builddep, compile">

View File

@ -96,7 +96,11 @@ do
# only generate for non-source language
echo "Generating ${CLASS}_$LG ResourceBundle..."
# convert to class files in build/obj
msgfmt -V | grep -q '0\.19'
if [ $? -ne 0 ]
then
# slow way
# convert to class files in src/WEB-INF/classes
msgfmt --java --statistics -r $CLASS -l $LG -d src/WEB-INF/classes $i
if [ $? -ne 0 ]
then
@ -106,6 +110,27 @@ do
RC=1
break
fi
else
# fast way
# convert to java files in build/messages-src
TD=build/messages-src-tmp
TDX=$TD/i2p/susi/webmail
TD2=build/messages-src
TDY=$TD2/i2p/susi/webmail
rm -rf $TD
mkdir -p $TD $TDY
msgfmt --java --statistics --source -r $CLASS -l $LG -d $TD $i
if [ $? -ne 0 ]
then
echo "ERROR - msgfmt failed on ${i}, not updating translations"
# msgfmt leaves the class file there so the build would work the next time
find src/WEB-INF/classes -name messages_${LG}.class -exec rm -f {} \;
RC=1
break
fi
mv $TDX/messages_$LG.java $TDY
rm -rf $TD
fi
fi
done
rm -f $TMPFILE

View File

@ -9,8 +9,8 @@
# Javadocs
# Note: Include the trailing slash! Don't surround the URL in quotes!
javasedocs.url=http://docs.oracle.com/javase/6/docs/api/
javaeedocs.url=http://docs.oracle.com/javaee/6/api/
javasedocs.url=http://docs.oracle.com/javase/7/docs/api/
javaeedocs.url=http://docs.oracle.com/javaee/7/api/
# The following link is dead, perhaps temporarily,
# perhaps not, as they move 7 and 8 to unsupported status.
#jettydocs.url=http://download.eclipse.org/jetty/stable-8/apidocs/
@ -134,4 +134,8 @@ javac.version=1.6
# Don't compile gnu.getopt classes, we will use libgetopt-java package
#with-libgetopt-java=true
# Don't compile org.apache.http classes, we will use libhttpclient-java and libhttpcore-java packages
# 2 MB of dependencies vs. 20 KB of copied source
# Requires 4.4 or higher.
# Debian: Not in wheezy/jessie
# Ubuntu: Only in wily and later
#with-libhttpclient-java=true

View File

@ -133,7 +133,7 @@
<attribute name="infile" />
<attribute name="outfile" />
<sequential>
<input message="Enter private signing key file:" addproperty="release.privkey" />
<input message="Enter sud/su2 private signing key file:" addproperty="release.privkey" />
<fail message="You must enter an existing file path." >
<condition>
<or>
@ -197,13 +197,13 @@
</or>
</condition>
</fail>
<input message="Enter key name (you@mail.i2p):" addproperty="release.signer.su3" />
<input message="Enter su3 key name (you@mail.i2p):" addproperty="release.signer.su3" />
<fail message="You must enter a name." >
<condition>
<equals arg1="${release.signer.su3}" arg2=""/>
</condition>
</fail>
<input message="Enter key password for ${release.signer.su3}:" addproperty="release.password.su3" />
<input message="Enter su3 key password for ${release.signer.su3}:" addproperty="release.password.su3" />
<fail message="You must enter a password." >
<condition>
<equals arg1="${release.password.su3}" arg2=""/>
@ -297,7 +297,7 @@
</target>
<target name="buildImagegen" depends="buildCore, buildJetty" >
<ant dir="apps/imagegen" target="all" />
<ant dir="apps/imagegen" target="build" />
<copy file="apps/imagegen/imagegen/build/imagegen.war" todir="build/" />
</target>
@ -760,6 +760,9 @@
<pathelement location="apps/systray/java/lib/systray4j.jar" />
<pathelement location="apps/jrobin/jrobin-1.5.9.1.jar" />
<pathelement location="installer/lib/wrapper/all/wrapper.jar" />
<!-- following are only for debian builds -->
<pathelement location="core/java/build/libintl.jar" />
<pathelement location="core/java/build/gnu-getopt.jar" />
</classpath>
<!-- These variables are stored in build.properties.
End-users can override by creating the file override.properties -->
@ -1035,6 +1038,12 @@
<copy todir="pkg-temp/lib/wrapper/solaris/">
<fileset dir="installer/lib/wrapper/solaris/" excludes="*.txt" />
</copy>
<!-- Force using the new wrapper.jar.
The new jar with the old windows binaries will output a warning on windows.
We do not generate release files from this target.
See preppkg-windows-only target below.
-->
<copy overwrite="true" file="installer/lib/wrapper/all/wrapper.jar" todir="pkg-temp/lib" />
</target>
<target name="preppkg-nowindows" depends="preppkg-linux, preppkg-freebsd, preppkg-osx, jbigi-nowindows">
@ -1139,7 +1148,6 @@
<copy file="installer/resources/install_i2p_service_winnt.bat" todir="pkg-temp/" />
<copy file="installer/resources/set_config_dir_for_nt_service.bat" todir="pkg-temp/" />
<copy file="installer/resources/uninstall_i2p_service_winnt.bat" todir="pkg-temp/" />
<copy file="installer/lib/wrapper/all/wrapper.jar" todir="pkg-temp/lib" />
<copy file="build/utility.jar" todir="pkg-temp" />
<copy todir="pkg-temp/lib/wrapper/win32/">
<fileset dir="installer/lib/wrapper/win32/" excludes="*.txt" />
@ -1151,7 +1159,13 @@
<target name="preppkg-windows-only" depends="preppkg-windows, jbigi-windows-only">
<copy file="build/jbigi.jar" todir="pkg-temp/lib" />
<!-- Win binaries are down-rev from the others, so use the old jar.
This will not overwrite, so preppkg (for all OSes) will get the new jar with
the old binaries, which will probably work but will output a warning.
The windows-only installer will get the correct jar.
<copy file="installer/lib/wrapper/all/wrapper.jar" todir="pkg-temp/lib" />
-->
<copy overwrite="true" file="installer/lib/wrapper/win-all/wrapper.jar" todir="pkg-temp/lib" />
</target>
<!-- see targets below for conditional copying -->
@ -1246,9 +1260,10 @@
<fileset dir="licenses/" />
</copy>
<copy file="apps/imagegen/identicon/README.md" tofile="pkg-temp/licenses/LICENSE-Identicon.txt" />
<copy file="apps/desktopgui/LICENSE" tofile="pkg-temp/licenses/LICENSE-DesktopGUI.txt" />
</target>
<target name="preplicenses-unlesspkg" unless="${with-libjetty8-java}" >
<target name="preplicenses-unlesspkg" unless="${with-libtomcat7-java}" >
<copy file="apps/jetty/apache-tomcat-deployer/NOTICE" tofile="pkg-temp/licenses/NOTICE-Tomcat.txt" />
</target>
@ -1465,15 +1480,16 @@
<copy file="build/i2psnark.jar" todir="pkg-temp/lib" />
<!-- include systray changes in 0.7.5 -->
<copy file="build/systray.jar" todir="pkg-temp/lib/" />
<!-- removed from updater in 0.9
<!-- removed from updater in 0.9, added back in 0.9.26 -->
<copy file="build/desktopgui.jar" todir="pkg-temp/lib/" />
-->
<copy file="build/susimail.war" todir="pkg-temp/webapps/" />
<copy file="build/susidns.war" todir="pkg-temp/webapps/" />
<copy file="build/imagegen.war" todir="pkg-temp/webapps/" />
<!-- as of 0.7.12; someday, we can remove these from the updater -->
<!-- as of 0.7.12; last changed in 0.9; removed from update in 0.9.26 -->
<!--
<copy file="apps/susidns/src/lib/jstl.jar" todir="pkg-temp/lib/" />
<copy file="apps/susidns/src/lib/standard.jar" todir="pkg-temp/lib/" />
-->
<copy file="build/i2psnark.war" todir="pkg-temp/webapps/" />
<copy file="history.txt" todir="pkg-temp/" />
<!-- the following overwrites history.txt on unix to shrink the update file -->
@ -2032,7 +2048,9 @@
<!-- libgetopt-java -->
<fileset dir="../i2p-${Extended.Version}/core/java/src/gnu/getopt" />
<!-- libhttpclient-java and libhttpcore-java -->
<!--
<fileset dir="../i2p-${Extended.Version}/core/java/src/org/apache/http" />
-->
<!-- systray4j -->
<fileset dir="../i2p-${Extended.Version}/apps/systray/java/lib" />
<file name="../i2p-${Extended.Version}/apps/systray/java/src/net/i2p/apps/systray/SysTrayImpl.java" />
@ -2103,7 +2121,9 @@
<fileset dir="../i2p-${Extended.Version}/_MTN" />
<fileset dir="../i2p-${Extended.Version}/core/java/src/gnu/gettext" />
<fileset dir="../i2p-${Extended.Version}/core/java/src/gnu/getopt" />
<!--
<fileset dir="../i2p-${Extended.Version}/core/java/src/org/apache/http" />
-->
<fileset dir="../i2p-${Extended.Version}/apps/systray/java/lib" />
<file name="../i2p-${Extended.Version}/apps/systray/java/src/net/i2p/apps/systray/SysTrayImpl.java" />
<file name="../i2p-${Extended.Version}/installer/resources/geoip.txt" />

View File

@ -4,6 +4,31 @@
# When executed in OSX: Produces a libjbigi.jnilib
[ -z "$CC" ] && CC="gcc"
if [ -z $BITS ]; then
UNAME="$(uname -a)"
if test "${UNAME#*x86_64}" != "x86_&4"; then
BITS=64
elif test "${UNAME#*i386}" != "i386"; then
BITS=32
elif test "${UNAME#*i686}" != "i686"; then
BITS=32
elif test "${UNAME#*armv6}" != "armv6"; then
BITS=32
elif test "${UNAME#*armv7}" != "armv7"; then
BITS=32
elif test "${UNAME#*aarch32}" != "aarch32"; then
BITS=32
elif test "${UNAME#*aarch64}" != "aarch64"; then
BITS=64
else
echo "Unable to detect default setting for BITS variable"
exit
fi
printf "\aBITS variable not set, $BITS bit system detected\n\a" >&2
fi
# If JAVA_HOME isn't set we'll try to figure it out
[ -z $JAVA_HOME ] && . `dirname $0`/../find-java-home
if [ ! -f "$JAVA_HOME/include/jni.h" ]; then

View File

@ -86,10 +86,31 @@ fi
if [ -z $BITS ]; then
UNAME="$(uname -a)"
if test "${UNAME#*x86_64}" != "x86_&4"; then
BITS=64
elif test "${UNAME#*i386}" != "i386"; then
BITS=32
printf "\aBITS variable not set, defaulting to $BITS\n\a" >&2
elif test "${UNAME#*i686}" != "i686"; then
BITS=32
elif test "${UNAME#*armv6}" != "armv6"; then
BITS=32
elif test "${UNAME#*armv7}" != "armv7"; then
BITS=32
elif test "${UNAME#*aarch32}" != "aarch32"; then
BITS=32
elif test "${UNAME#*aarch64}" != "aarch64"; then
BITS=64
else
echo "Unable to detect default setting for BITS variable"
exit
fi
printf "\aBITS variable not set, $BITS bit system detected\n\a" >&2
fi
if [ -z $CC ]; then
export CC="gcc"
printf "\aCC variable not set, defaulting to $CC\n\a" >&2

View File

@ -24,10 +24,31 @@ esac
if [ -z $BITS ]; then
UNAME="$(uname -a)"
if test "${UNAME#*x86_64}" != "x86_&4"; then
BITS=64
printf "\aBITS variable not set, defaulting to $BITS\n\a" >&2
elif test "${UNAME#*i386}" != "i386"; then
BITS=32
elif test "${UNAME#*i686}" != "i686"; then
BITS=32
elif test "${UNAME#*armv6}" != "armv6"; then
BITS=32
elif test "${UNAME#*armv7}" != "armv7"; then
BITS=32
elif test "${UNAME#*aarch32}" != "aarch32"; then
BITS=32
elif test "${UNAME#*aarch64}" != "aarch64"; then
BITS=64
else
echo "Unable to detect default setting for BITS variable"
exit
fi
printf "\aBITS variable not set, $BITS bit system detected\n\a" >&2
fi
if [ -z $CC ]; then
export CC="gcc"
printf "\aCC variable not set, defaulting to $CC\n\a" >&2

View File

@ -253,7 +253,7 @@ public class SimpleTimer2 {
// ... and I expect cancelling this way is more efficient
/** state of the current event. All access should be under lock. */
private TimedEventState _state;
protected TimedEventState _state;
/** absolute time this event should run next time. LOCKING: this */
private long _nextRun;
/** whether this was scheduled during RUNNING state. LOCKING: this */
@ -338,8 +338,8 @@ public class SimpleTimer2 {
*/
public synchronized void reschedule(long timeoutMs, boolean useEarliestTime) {
if (timeoutMs <= 0) {
if (timeoutMs < 0 && _log.shouldWarn())
_log.warn("Resched. timeout < 0: " + this + " timeout = " + timeoutMs + " state: " + _state);
if (timeoutMs < 0 && _log.shouldInfo())
_log.info("Resched. timeout < 0: " + this + " timeout = " + timeoutMs + " state: " + _state);
timeoutMs = 1;
}
final long now = System.currentTimeMillis();
@ -423,6 +423,7 @@ public class SimpleTimer2 {
long delay = 0;
synchronized(this) {
if (Thread.currentThread().isInterrupted()) {
if (_log.shouldWarn())
_log.warn("I was interrupted in run, state "+_state+" event "+this);
return;
}
@ -431,6 +432,8 @@ public class SimpleTimer2 {
switch(_state) {
case CANCELLED:
if (_log.shouldInfo())
_log.info("Not actually running: CANCELLED " + this);
return; // goodbye
case IDLE: // fall through
case RUNNING:
@ -444,6 +447,8 @@ public class SimpleTimer2 {
if (difference > _fuzz) {
// proceed, switch to IDLE to reschedule
_state = TimedEventState.IDLE;
if (_log.shouldInfo())
_log.info("Early execution, Rescheduling for " + difference + " later: " + this);
schedule(difference);
return;
}
@ -485,6 +490,8 @@ public class SimpleTimer2 {
// do we need to reschedule?
if (_rescheduleAfterRun) {
_rescheduleAfterRun = false;
if (_log.shouldInfo())
_log.info("Reschedule after run: " + this);
schedule(_nextRun - System.currentTimeMillis());
}
}
@ -494,6 +501,8 @@ public class SimpleTimer2 {
long time = System.currentTimeMillis() - before;
if (time > 500 && _log.shouldLog(Log.WARN))
_log.warn(_pool + " event execution took " + time + ": " + this);
else if (_log.shouldDebug())
_log.debug("Execution finished in " + time + ": " + this);
if (_log.shouldLog(Log.INFO)) {
// this call is slow - iterates through a HashMap -
// would be better to have a local AtomicLong if we care
@ -537,7 +546,7 @@ public class SimpleTimer2 {
* @since 0.9.20
*/
private static abstract class PeriodicTimedEvent extends TimedEvent {
private long _timeoutMs;
private final long _timeoutMs;
/**
* Schedule periodic event
@ -556,8 +565,14 @@ public class SimpleTimer2 {
@Override
public void run() {
super.run();
synchronized(this) {
// Task may have rescheduled itself without actually running.
// If we schedule again, it will be stuck in a scheduling loop.
// This happens after a backwards clock shift.
if (_state == TimedEventState.IDLE)
schedule(_timeoutMs);
}
}
}
}

2
debian/control vendored
View File

@ -15,7 +15,6 @@ Build-Depends: debhelper (>= 7.0.50~)
,dh-apparmor
,gettext
,libgetopt-java
,libhttpclient-java, libhttpcore-java
,libgmp-dev (>= 2:5.0.5)
,libservice-wrapper-java
,hardening-wrapper
@ -79,7 +78,6 @@ Depends: ${misc:Depends}, ${java:Depends}, ${shlibs:Depends},
geoip-database,
gettext-base,
libgetopt-java,
libhttpclient-java, libhttpcore-java,
libjetty8-java, libservlet3.0-java,
glassfish-javaee
Replaces: i2p ( << 0.8.6-5)

View File

@ -92,6 +92,9 @@ usr/share/java/gnu-getopt.jar usr/share/i2p/lib/gnu-getopt.jar
# comment out if not building with libhttpclient-java and libhttpcore-java
# ubuntu and debian: everywhere
usr/share/java/httpclient.jar usr/share/i2p/lib/httpclient.jar
usr/share/java/httpcore.jar usr/share/i2p/lib/httpcore.jar
# 2 MB of dependencies vs. 20 KB of copied source
# Requires 4.4 or higher.
# Debian: Not in wheezy/jessie
# Ubuntu: Only in wily and later
#usr/share/java/httpclient.jar usr/share/i2p/lib/httpclient.jar
#usr/share/java/httpcore.jar usr/share/i2p/lib/httpcore.jar

View File

@ -71,7 +71,7 @@ Debian wrapper.config to try to prevent confusion.
# Priority at which to run the wrapper. See "man nice" for valid priorities.
# nice is only used if a priority is specified.
@@ -177,75 +168,8 @@
@@ -177,77 +168,8 @@
exit 1
fi
@ -104,13 +104,15 @@ Debian wrapper.config to try to prevent confusion.
-
-freebsd10() {
- echo
- echo "The current version of the Tanuki wrapper does not"
- echo "support FreeBSD 10."
- echo "The current version of the Tanuki wrapper that is bundled"
- echo "with I2P does not support FreeBSD 10."
- echo
- echo "See https://trac.i2p2.de/ticket/1118 for more information"
- echo "and a workaround for this issue."
- echo "See http://trac.i2p2.de/ticket/1118#comment:13 for a work-around."
- echo "After applying the work-around, as a normal user or a dedicated"
- echo "i2p user, you can then run:"
- echo "$ ./i2prouter start"
- echo
- echo "In the meantime, you may start I2P by running the script"
- echo "Or, you may also start I2P by running the script:"
- echo "${I2P}/runplain.sh"
- echo
-}
@ -125,11 +127,11 @@ Debian wrapper.config to try to prevent confusion.
- ;;
- *)
- # We should never get here on recent versions of FreeBSD
- if ! $(pkg_info -E 'libiconv*' > /dev/null 2>&1); then
- if ! $(pkg info -E 'libiconv*' > /dev/null 2>&1); then
- echo
- echo "The wrapper requires libiconv."
- echo
- echo "It can be installed with pkg_add -r libiconv"
- echo "It can be installed with pkg install libiconv"
- echo
- fi
- ;;
@ -147,7 +149,7 @@ Debian wrapper.config to try to prevent confusion.
if [ -n "$FIXED_COMMAND" ]
then
COMMAND="$FIXED_COMMAND"
@@ -1058,7 +982,6 @@
@@ -1068,7 +982,6 @@
if [ "X$pid" = "X" ]
then
eval echo " `gettext 'WARNING: $APP_LONG_NAME may have failed to start.'`"
@ -155,7 +157,7 @@ Debian wrapper.config to try to prevent confusion.
else
eval echo ' running: PID:$pid'
fi
@@ -1861,7 +1784,7 @@
@@ -1871,7 +1784,7 @@
}
showsetusermesg() {
@ -164,7 +166,7 @@ Debian wrapper.config to try to prevent confusion.
}
checkifstartingasroot() {
@@ -1869,7 +1792,7 @@
@@ -1879,7 +1792,7 @@
echo "`gettext 'Running I2P as the root user is *not* recommended.'`"
showsetusermesg
echo
@ -173,7 +175,7 @@ Debian wrapper.config to try to prevent confusion.
exit 1
fi
}
@@ -1934,24 +1857,10 @@
@@ -1944,24 +1857,10 @@
status
;;

View File

@ -13,7 +13,7 @@ diff --git a/core/c/jbigi/build_jbigi.sh b/core/c/jbigi/build_jbigi.sh
index 1521392..6a89c92 100755
--- a/core/c/jbigi/build_jbigi.sh
+++ b/core/c/jbigi/build_jbigi.sh
@@ -43,7 +43,7 @@
@@ -68,7 +68,7 @@
BUILD_OS="linux"
fi
COMPILEFLAGS="-fPIC -Wall $CFLAGS"
@ -22,7 +22,7 @@ index 1521392..6a89c92 100755
LINKFLAGS="-shared -Wl,-soname,libjbigi.so"
LIBFILE="libjbigi.so";;
*)
@@ -64,8 +64,8 @@
@@ -89,8 +89,8 @@
[ $BITS -eq 64 ] && COMPILEFLAGS="-m64 $COMPILEFLAGS" && LINKFLAGS="-m64 $LINKFLAGS"
echo "Compiling C code..."

View File

@ -10,7 +10,7 @@ diff --git a/core/c/jcpuid/build.sh b/core/c/jcpuid/build.sh
index 5b63c6c..f39148d 100755
--- a/core/c/jcpuid/build.sh
+++ b/core/c/jcpuid/build.sh
@@ -104,12 +104,8 @@
@@ -125,12 +125,8 @@
exit 1
fi

13
debian/rules vendored
View File

@ -149,11 +149,14 @@ endif
@mkdir -p $(CURDIR)/core/java/build
ln -sf /usr/share/java/gnu-getopt.jar $(CURDIR)/core/java/build/gnu-getopt.jar
@# debian and ubuntu: everywhere
@/bin/echo -e "with-libhttpclient-java=true" >> $(CURDIR)/override.properties
@mkdir -p $(CURDIR)/core/java/build
ln -sf /usr/share/java/httpclient.jar $(CURDIR)/core/java/build/httpclient.jar
ln -sf /usr/share/java/httpcore.jar $(CURDIR)/core/java/build/httpcore.jar
@# 2 MB of dependencies vs. 20 KB of copied source
@# Requires 4.4 or higher.
@# Debian: Not in wheezy/jessie
@# Ubuntu: Only in wily and later
@#/bin/echo -e "with-libhttpclient-java=true" >> $(CURDIR)/override.properties
@#mkdir -p $(CURDIR)/core/java/build
@#ln -sf /usr/share/java/httpclient.jar $(CURDIR)/core/java/build/httpclient.jar
@#ln -sf /usr/share/java/httpcore.jar $(CURDIR)/core/java/build/httpcore.jar
TZ=UTC JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8 ant preppkg-unix javadoc
echo router.updateDisabled=true > $(I2P)/router.config

View File

@ -1,3 +1,65 @@
2016-05-07 zzz
* Build:
- Add DTG to updater
- Fix and bundle DTG license info
- Remove jstl.jar and standard.jar from updater,
last changed in 0.9
- Fix bundling of Tomcat license info
- Add back the old way to build bundles for gettext < 0.19
* Console:
- Change to new DTG constructor
- Don't attempt to start systray or DTG when running as a service
- Show systray controls for all OSes on /configservice
- Implement backend for systray control
* DesktopGui:
- Implement second TrayManager menu implementation in Swing.
- Use Swing except on Windows
- Hide restart menu items if no wrapper
- Add graceful restart and shutdown menu items
- Add basic adjustment of menu based on shutdown state
- Disable wrapper notification for now
- Remove Swing DesktopguiConfigurationFrame,
move to a submenu.
- Remove LookAndFeel setting
- Make Main class a RouterApp
- Remove all static log, context, and instance fields
- Remove unused ConfigurationManager class
- Translate tooltip, disable tooltip on linux
- Use safer exec call to start i2p
- Remove all images, use itoopie
- Don't start spinner thread in router context
- Handle various startup errors better
- Synchs, finals, javadocs, cleanups
2016-05-04 zzz
* i2prouter: Set JAVA_HOME correctly on Mac OS X 10.5 and later (ticket #1783)
* Utils: Fix bug in periodic timers triggered by
a backwards clock shift, caused graphs to be blank
and various router, streaming, and i2ptunnel
degradations over time (tickets #1702, #1776)
* Wrapper: Update to wrapper 3.5.29, except for Windows.
Fixes wrapper failure on FreeBSD 10 (ticket #1118)
2016-05-01 zzz
* Build: Compile resource bundles from ant, not msgfmt,
speeding up builds with translations by 20x
* Debian: Back out libhttpclient-java dependency,
requires 4.4 which is too recent for most distros
2016-04-30 zzz
* Blocklist: Add RFC 6598 addresses
* Console:
- Only display cpuid information on x86
- Readme page link fixes (tickets #1789, #1790)
* Data: Fix NPE calculating the hash of a RI of unknown sig type
* Debian:
- Add runtime dependency on libhttpclient-java,
link to /usr/share/java/httpclient.jar and httpcore.jar
* Eepsite: comment out gzip filtering in cgi context,
causes hung threads, root cause unknown
* Router: Reduce log level of RI sig failure
* SAM: Log tweaks (ticket #1778)
2016-04-29 zzz
* Debian:
- Add runtime dependency on gettext-base,

Binary file not shown.

View File

@ -1,7 +1,13 @@
Wrapper build instructions (Ubuntu or Raspbian):
apt-get install default-jdk ant
export JAVA_HOME=/usr/lib/jvm/default-java
ant -Dbits=32 compile-c-unix
mv bin/wrapper bin/i2psvc
strip --strip-unneeded bin/i2psvc lib/libwrapper.so
cp bin/i2psvc $I2P
cp lib/libwrapper.so $I2P/lib
cp /path/to/wrapper-delta-pack-3.5.xx/lib/wrapper.jar $I2P/lib
(test it)
cp bin/i2psvc lib/libwrapper.so /path/to/installer/lib/wrapper/linux-armv6
chmod -x i2psvc librapper.so

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -206,13 +206,15 @@ unsupported() {
freebsd10() {
echo
echo "The current version of the Tanuki wrapper does not"
echo "support FreeBSD 10."
echo "The current version of the Tanuki wrapper that is bundled"
echo "with I2P does not support FreeBSD 10."
echo
echo "See https://trac.i2p2.de/ticket/1118 for more information"
echo "and a workaround for this issue."
echo "See http://trac.i2p2.de/ticket/1118#comment:13 for a work-around."
echo "After applying the work-around, as a normal user or a dedicated"
echo "i2p user, you can then run:"
echo "$ ./i2prouter start"
echo
echo "In the meantime, you may start I2P by running the script"
echo "Or, you may also start I2P by running the script:"
echo "${I2P}/runplain.sh"
echo
}
@ -227,11 +229,11 @@ failed() {
;;
*)
# We should never get here on recent versions of FreeBSD
if ! $(pkg_info -E 'libiconv*' > /dev/null 2>&1); then
if ! $(pkg info -E 'libiconv*' > /dev/null 2>&1); then
echo
echo "The wrapper requires libiconv."
echo
echo "It can be installed with pkg_add -r libiconv"
echo "It can be installed with pkg install libiconv"
echo
fi
;;
@ -486,11 +488,19 @@ else
esac
fi
# OSX always places Java in the same location so we can reliably set JAVA_HOME
# Through Java 6, OSX always places Java in the same location so we can reliably set JAVA_HOME
# As of OSX 10.5 / Java 7, call /usr/libexec/java_home to find it
# https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ "$DIST_OS" = "macosx" ]
then
if [ -z "$JAVA_HOME" ]; then
JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
if [ -x "/usr/libexec/java_home" ]; then
JAVA_HOME=`/usr/libexec/java_home`
fi
if [ -z "$JAVA_HOME" ]; then
JAVA_HOME="/Library/Java/Home"
fi
export JAVA_HOME
fi
fi

View File

@ -17,6 +17,7 @@ java.io
java.lang
java.lang.annotation
java.lang.instrument
java.lang.invoke
java.lang.management
java.lang.ref
java.lang.reflect
@ -27,6 +28,9 @@ java.nio.channels
java.nio.channels.spi
java.nio.charset
java.nio.charset.spi
java.nio.file
java.nio.file.attribute
java.nio.file.spi
java.rmi
java.rmi.activation
java.rmi.dgc
@ -120,6 +124,7 @@ javax.swing.plaf
javax.swing.plaf.basic
javax.swing.plaf.metal
javax.swing.plaf.multi
javax.swing.plaf.nimbus
javax.swing.plaf.synth
javax.swing.table
javax.swing.text
@ -163,6 +168,7 @@ javax.xml.ws.handler.soap
javax.xml.ws.http
javax.xml.ws.soap
javax.xml.ws.spi
javax.xml.ws.spi.http
javax.xml.ws.wsaddressing
javax.xml.xpath
org.ietf.jgss

View File

@ -1,11 +1,20 @@
javax.annotation
javax.annotation.security
javax.annotation.sql
javax.batch.api
javax.batch.api.chunk
javax.batch.api.chunk.listener
javax.batch.api.listener
javax.batch.api.partition
javax.batch.operations
javax.batch.runtime
javax.batch.runtime.context
javax.decorator
javax.ejb
javax.ejb.embeddable
javax.ejb.spi
javax.el
javax.enterprise.concurrent
javax.enterprise.context
javax.enterprise.context.spi
javax.enterprise.deploy.model
@ -31,6 +40,8 @@ javax.faces.context
javax.faces.convert
javax.faces.el
javax.faces.event
javax.faces.flow
javax.faces.flow.builder
javax.faces.lifecycle
javax.faces.model
javax.faces.render
@ -41,6 +52,9 @@ javax.faces.webapp
javax.inject
javax.interceptor
javax.jms
javax.json
javax.json.spi
javax.json.stream
javax.jws
javax.jws.soap
javax.mail
@ -81,10 +95,16 @@ javax.transaction.xa
javax.validation
javax.validation.bootstrap
javax.validation.constraints
javax.validation.constraintvalidation
javax.validation.executable
javax.validation.groups
javax.validation.metadata
javax.validation.spi
javax.websocket
javax.websocket.server
javax.ws.rs
javax.ws.rs.client
javax.ws.rs.container
javax.ws.rs.core
javax.ws.rs.ext
javax.xml.bind
@ -102,6 +122,7 @@ javax.xml.rpc.handler.soap
javax.xml.rpc.holders
javax.xml.rpc.server
javax.xml.rpc.soap
javax.xml.soap
javax.xml.ws
javax.xml.ws.handler
javax.xml.ws.handler.soap

View File

@ -13,6 +13,7 @@ org.eclipse.jetty.deploy.jmx
org.eclipse.jetty.deploy.providers
org.eclipse.jetty.deploy.util
org.eclipse.jetty.embedded
org.eclipse.jetty.example.asyncrest
org.eclipse.jetty.http
org.eclipse.jetty.http.gzip
org.eclipse.jetty.http.spi
@ -34,20 +35,17 @@ org.eclipse.jetty.nested
org.eclipse.jetty.nosql
org.eclipse.jetty.nosql.mongodb
org.eclipse.jetty.nosql.mongodb.jmx
org.eclipse.jetty.osgi.annotations
org.eclipse.jetty.osgi.boot
org.eclipse.jetty.osgi.boot.internal.jsp
org.eclipse.jetty.osgi.boot.internal.serverfactory
org.eclipse.jetty.osgi.boot.internal.webapp
org.eclipse.jetty.osgi.boot.jasper
org.eclipse.jetty.osgi.boot.jsp
org.eclipse.jetty.osgi.boot.logback
org.eclipse.jetty.osgi.boot.logback.internal
org.eclipse.jetty.osgi.boot.utils
org.eclipse.jetty.osgi.boot.utils.internal
org.eclipse.jetty.osgi.boot.warurl
org.eclipse.jetty.osgi.boot.warurl.internal
org.eclipse.jetty.osgi.equinoxtools
org.eclipse.jetty.osgi.equinoxtools.console
org.eclipse.jetty.osgi.httpservice
org.eclipse.jetty.osgi.nested
org.eclipse.jetty.overlays
@ -78,7 +76,6 @@ org.eclipse.jetty.server.session
org.eclipse.jetty.server.session.jmx
org.eclipse.jetty.server.ssl
org.eclipse.jetty.servlet
org.eclipse.jetty.servlet.api
org.eclipse.jetty.servlet.jmx
org.eclipse.jetty.servlet.listener
org.eclipse.jetty.servlets

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */
public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 8;
public final static long BUILD = 11;
/** for example "-test" */
public final static String EXTRA = "";