diff --git a/.tx/config b/.tx/config index abb8a7a04..0456353e5 100644 --- a/.tx/config +++ b/.tx/config @@ -78,6 +78,7 @@ trans.ar = apps/routerconsole/locale-news/messages_ar.po trans.de = apps/routerconsole/locale-news/messages_de.po trans.es = apps/routerconsole/locale-news/messages_es.po trans.fr = apps/routerconsole/locale-news/messages_fr.po +trans.he = apps/routerconsole/locale-news/messages_he.po trans.ja = apps/routerconsole/locale-news/messages_ja.po trans.it = apps/routerconsole/locale-news/messages_it.po trans.nl = apps/routerconsole/locale-news/messages_nl.po @@ -214,6 +215,8 @@ trans.es = debian/po/es.po trans.fr = debian/po/fr.po trans.it = debian/po/it.po trans.hu = debian/po/hu.po +trans.ja = debian/po/ja.po +trans.ko = debian/po/ko.po trans.pl = debian/po/pl.po trans.pt = debian/po/pt.po trans.ro = debian/po/ro.po @@ -230,6 +233,7 @@ trans.de = installer/resources/locale/po/messages_de.po trans.es = installer/resources/locale/po/messages_es.po trans.fr = installer/resources/locale/po/messages_fr.po trans.it = installer/resources/locale/po/messages_it.po +trans.pl = installer/resources/locale/po/messages_pl.po trans.pt = installer/resources/locale/po/messages_pt.po trans.pt_BR = installer/resources/locale/po/messages_pt_BR.po trans.ro = installer/resources/locale/po/messages_ro.po @@ -238,6 +242,23 @@ trans.ru_RU = installer/resources/locale/po/messages_ru.po trans.tr_TR = installer/resources/locale/po/messages_tr.po trans.zh_CN = installer/resources/locale/po/messages_zh.po +[I2P.getopt] +source_file = core/java/src/gnu/getopt/MessagesBundle.properties +source_lang = en +type = PROPERTIES +trans.cs = core/java/src/gnu/getopt/MessagesBundle_cs.properties +trans.de = core/java/src/gnu/getopt/MessagesBundle_de.properties +trans.es = core/java/src/gnu/getopt/MessagesBundle_es.properties +trans.fr = core/java/src/gnu/getopt/MessagesBundle_fr.properties +trans.hu = core/java/src/gnu/getopt/MessagesBundle_hu.properties +trans.it = core/java/src/gnu/getopt/MessagesBundle_it.properties +trans.ja = core/java/src/gnu/getopt/MessagesBundle_ja.properties +trans.nl = core/java/src/gnu/getopt/MessagesBundle_nl.properties +trans.nb = core/java/src/gnu/getopt/MessagesBundle_nb.properties +trans.pl = core/java/src/gnu/getopt/MessagesBundle_pl.properties +trans.ro = core/java/src/gnu/getopt/MessagesBundle_ro.properties +trans.zh_CN = core/java/src/gnu/getopt/MessagesBundle_zh.properties + [main] host = https://www.transifex.com diff --git a/INSTALL-headless.txt b/INSTALL-headless.txt index c5044307c..6f5457580 100644 --- a/INSTALL-headless.txt +++ b/INSTALL-headless.txt @@ -12,7 +12,7 @@ you may use: to configure the router. If you're having trouble, swing by http://forum.i2p/, check the -website at http://www.i2p2.de/, or get on irc://irc.freenode.net/#i2p +website at https://geti2p.net/, or get on irc://irc.freenode.net/#i2p I2P will create and store files and configuration data in the user directory ~/.i2p/ on Linux and %APPDATA%\I2P\ on Windows. This directory is created diff --git a/LICENSE.txt b/LICENSE.txt index 9ea9f333c..23509334c 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -36,7 +36,7 @@ Public domain except as listed below: Copyright (c) 2003, TheCrypto See licenses/LICENSE-ElGamalDSA.txt - SHA256 and HMAC-SHA256: + SHA256 and HMAC: Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle See licenses/LICENSE-SHA256.txt @@ -76,6 +76,11 @@ Public domain except as listed below: Copyright 2012 Hiroshi Nakamura See licenses/LICENSE-Apache2.0.txt + Getopt: + Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com) + See licenses/LICENSE-LGPLv2.1.txt + + Router (router.jar): Public domain except as listed below: UPnP.java: diff --git a/README.txt b/README.txt index fad70c410..d115a6dbf 100644 --- a/README.txt +++ b/README.txt @@ -15,20 +15,20 @@ To build: ant installer-osx Run 'ant' with no arguments to see other build options. - See INSTALL.txt or http://www.i2p2.de/download.html for installation instructions. + See INSTALL.txt or https://geti2p.net/download for installation instructions. Documentation: - http://www.i2p2.de/how + https://geti2p.net/how API: run 'ant javadoc' then start at build/javadoc/index.html Latest release: - http://www.i2p2.de/download + https://geti2p.net/download To get development branch from source control: - http://www.i2p2.de/newdevelopers + https://geti2p.net/newdevelopers FAQ: - http://www.i2p2.de/faq + https://geti2p.net/faq Need help? IRC irc.freenode.net #i2p diff --git a/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java b/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java index e6e5eefab..47e9bb0fb 100644 --- a/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java +++ b/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java @@ -91,7 +91,7 @@ class ConfigParser { String inputLine; inputLine = input.readLine(); while (inputLine != null) { - inputLine = ConfigParser.stripComments(inputLine); + inputLine = stripComments(inputLine); String[] splitLine = inputLine.split("="); if (splitLine.length == 2) { result.put(splitLine[0].trim().toLowerCase(Locale.US), splitLine[1].trim()); @@ -116,7 +116,7 @@ class ConfigParser { FileInputStream fileStream = new FileInputStream(file); BufferedReader input = new BufferedReader(new InputStreamReader( fileStream)); - Map rv = ConfigParser.parse(input); + Map rv = parse(input); try { fileStream.close(); } catch (IOException ioe) {} @@ -136,7 +136,7 @@ class ConfigParser { public static Map parse(String string) throws IOException { StringReader stringReader = new StringReader(string); BufferedReader input = new BufferedReader(stringReader); - return ConfigParser.parse(input); + return parse(input); } /** @@ -153,7 +153,7 @@ class ConfigParser { public static Map parse(File file, Map map) { Map result; try { - result = ConfigParser.parse(file); + result = parse(file); for (Map.Entry entry : map.entrySet()) { if (!result.containsKey(entry.getKey())) result.put(entry.getKey(), entry.getValue()); @@ -161,7 +161,7 @@ class ConfigParser { } catch (IOException exp) { result = map; try { - ConfigParser.write(result, file); + write(result, file); } catch (IOException exp2) { } } @@ -182,7 +182,7 @@ class ConfigParser { List result = new LinkedList(); String inputLine = input.readLine(); while (inputLine != null) { - inputLine = ConfigParser.stripComments(inputLine).trim(); + inputLine = stripComments(inputLine).trim(); if (inputLine.length() > 0) { result.add(inputLine); } @@ -205,7 +205,7 @@ class ConfigParser { FileInputStream fileStream = new FileInputStream(file); BufferedReader input = new BufferedReader(new InputStreamReader( fileStream)); - List rv = ConfigParser.parseSubscriptions(input); + List rv = parseSubscriptions(input); try { fileStream.close(); } catch (IOException ioe) {} @@ -224,7 +224,7 @@ class ConfigParser { public static List parseSubscriptions(String string) throws IOException { StringReader stringReader = new StringReader(string); BufferedReader input = new BufferedReader(stringReader); - return ConfigParser.parseSubscriptions(input); + return parseSubscriptions(input); } /** @@ -234,18 +234,30 @@ class ConfigParser { * * @param file * A File to attempt to parse. - * @param list list of files to parse + * @param list The default subscriptions to be saved and returned if the file cannot be read * @return A List consisting of one element for each line in file, or if * file cannot be read, list. */ public static List parseSubscriptions(File file, List list) { List result; try { - result = ConfigParser.parseSubscriptions(file); + result = parseSubscriptions(file); + // Fix up files that contain the old default + // which was changed in 0.9.11 + if (result.remove(Daemon.OLD_DEFAULT_SUB)) { + for (String sub : list) { + if (!result.contains(sub)) + result.add(sub); + } + try { + writeSubscriptions(result, file); + // TODO log + } catch (IOException ioe) {} + } } catch (IOException exp) { result = list; try { - ConfigParser.writeSubscriptions(result, file); + writeSubscriptions(result, file); } catch (IOException exp2) { } } @@ -289,8 +301,7 @@ class ConfigParser { boolean success = false; if (!isWindows) { File tmp = SecureFile.createTempFile("temp-", ".tmp", file.getAbsoluteFile().getParentFile()); - ConfigParser - .write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(tmp), "UTF-8"))); + write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(tmp), "UTF-8"))); success = tmp.renameTo(file); if (!success) { tmp.delete(); @@ -299,8 +310,7 @@ class ConfigParser { } if (!success) { // hmm, that didn't work, try it the old way - ConfigParser - .write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8"))); + write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8"))); } } @@ -337,7 +347,7 @@ class ConfigParser { */ public static void writeSubscriptions(List list, File file) throws IOException { - ConfigParser.writeSubscriptions(list, new BufferedWriter( + writeSubscriptions(list, new BufferedWriter( new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8"))); } diff --git a/apps/addressbook/java/src/net/i2p/addressbook/Daemon.java b/apps/addressbook/java/src/net/i2p/addressbook/Daemon.java index d22ac7534..f0ed16569 100644 --- a/apps/addressbook/java/src/net/i2p/addressbook/Daemon.java +++ b/apps/addressbook/java/src/net/i2p/addressbook/Daemon.java @@ -50,6 +50,9 @@ public class Daemon { private static final Daemon _instance = new Daemon(); private volatile boolean _running; private static final boolean DEBUG = false; + private static final String DEFAULT_SUB = "http://i2p-projekt.i2p/hosts.txt"; + /** @since 0.9.12 */ + static final String OLD_DEFAULT_SUB = "http://www.i2p2.i2p/hosts.txt"; /** * Update the router and published address books using remote data from the @@ -253,7 +256,7 @@ public class Daemon { List defaultSubs = new LinkedList(); // defaultSubs.add("http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/hosts.txt"); - defaultSubs.add("http://www.i2p2.i2p/hosts.txt"); + defaultSubs.add(DEFAULT_SUB); SubscriptionList subscriptions = new SubscriptionList(subscriptionFile, etagsFile, lastModifiedFile, lastFetchedFile, delay, defaultSubs, settings diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerID.java b/apps/i2psnark/java/src/org/klomp/snark/PeerID.java index 16dc9224a..0a71450c7 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerID.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerID.java @@ -52,6 +52,7 @@ class PeerID implements Comparable private boolean triedDestLookup; private final int hash; private final I2PSnarkUtil util; + private String _toStringCache; public PeerID(byte[] id, Destination address) { @@ -216,13 +217,15 @@ class PeerID implements Comparable } /** - * Returns the String "id@address" where id is the base64 encoded id - * and address is the base64 dest (was the base64 hash of the dest) which + * Returns the String "id@address" where id is the first 4 chars of the base64 encoded id + * and address is the first 6 chars of the base64 dest (was the base64 hash of the dest) which * should match what the bytemonsoon tracker reports on its web pages. */ - @Override + @Override public String toString() { + if (_toStringCache != null) + return _toStringCache; if (id == null || address == null) return "unkn@" + Base64.encode(destHash).substring(0, 6); int nonZero = 0; @@ -232,7 +235,8 @@ class PeerID implements Comparable break; } } - return Base64.encode(id, nonZero, id.length-nonZero).substring(0,4) + "@" + address.toBase64().substring(0,6); + _toStringCache = Base64.encode(id, nonZero, id.length-nonZero).substring(0,4) + "@" + address.toBase64().substring(0,6); + return _toStringCache; } /** diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index 3fe2b2ade..21ffac758 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -24,6 +24,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.LinkedBlockingQueue; import net.i2p.I2PAppContext; +import net.i2p.app.ClientAppManager; import net.i2p.data.Base64; import net.i2p.data.DataHelper; import net.i2p.update.*; @@ -198,7 +199,9 @@ public class SnarkManager implements CompleteListener { public void timeReached() { if (!_running) return; - _umgr = _context.updateManager(); + ClientAppManager cmgr = _context.clientAppManager(); + if (cmgr != null) + _umgr = (UpdateManager) cmgr.getRegisteredApp(UpdateManager.APP_NAME); if (_umgr != null) { _uhandler = new UpdateHandler(_context, _umgr, SnarkManager.this); _umgr.register(_uhandler, UpdateType.ROUTER_SIGNED, UpdateMethod.TORRENT, 10); diff --git a/apps/i2psnark/locale/messages_fr.po b/apps/i2psnark/locale/messages_fr.po index 0fae67ab8..7de66f204 100644 --- a/apps/i2psnark/locale/messages_fr.po +++ b/apps/i2psnark/locale/messages_fr.po @@ -2,7 +2,7 @@ # Copyright (C) 2009 The I2P Project # This file is distributed under the same license as the i2psnark package. # To contribute translations, see http://www.i2p2.de/newdevelopers -# +# # Translators: # Boxoa590, 2012-2013 # ducki2p , 2011 @@ -11,20 +11,19 @@ # Boxoa590, 2013 # Boxoa590, 2012 # jackjack , 2011 -# Towatowa441, 2013 +# Towatowa441, 2013-2014 msgid "" msgstr "" "Project-Id-Version: I2P\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-01-09 19:14+0000\n" -"PO-Revision-Date: 2013-11-22 10:17+0000\n" +"POT-Creation-Date: 2014-01-09 19:27+0000\n" +"PO-Revision-Date: 2014-01-23 06:59+0000\n" "Last-Translator: Towatowa441\n" -"Language-Team: French (http://www.transifex.com/projects/p/I2P/language/" -"fr/)\n" -"Language: fr\n" +"Language-Team: French (http://www.transifex.com/projects/p/I2P/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: ../java/src/org/klomp/snark/IdleChecker.java:69 @@ -101,9 +100,7 @@ msgstr "Répertoire des données changé pour {0}" #: ../java/src/org/klomp/snark/SnarkManager.java:647 msgid "I2CP and tunnel changes will take effect after stopping all torrents" -msgstr "" -"Les modifications sur I2CP et les tunnels seront pris en compte après avoir " -"arrêté tous les torrents" +msgstr "Les modifications sur I2CP et les tunnels seront pris en compte après avoir arrêté tous les torrents" #: ../java/src/org/klomp/snark/SnarkManager.java:651 #, java-format @@ -122,9 +119,7 @@ msgstr "Les paramètres I2CP ont été changés à {0}" #: ../java/src/org/klomp/snark/SnarkManager.java:664 msgid "" "Unable to connect with the new settings, reverting to the old I2CP settings" -msgstr "" -"Impossible de se connecter avec les nouveaux paramètres, retour à l'ancienne " -"configuration I2CP" +msgstr "Impossible de se connecter avec les nouveaux paramètres, retour à l'ancienne configuration I2CP" #: ../java/src/org/klomp/snark/SnarkManager.java:668 msgid "Unable to reconnect with the old settings!" @@ -157,14 +152,11 @@ msgstr "Démarrage automatique désactivé" #: ../java/src/org/klomp/snark/SnarkManager.java:708 msgid "Enabled open trackers - torrent restart required to take effect." -msgstr "" -"Open trackers activés - redémarrage des torrents requis pour prise en compte." +msgstr "Open trackers activés - redémarrage des torrents requis pour prise en compte." #: ../java/src/org/klomp/snark/SnarkManager.java:710 msgid "Disabled open trackers - torrent restart required to take effect." -msgstr "" -"Open trackers désactivés - redémarrage des torrents requis pour prise en " -"compte." +msgstr "Open trackers désactivés - redémarrage des torrents requis pour prise en compte." #: ../java/src/org/klomp/snark/SnarkManager.java:717 msgid "Enabled DHT." @@ -181,9 +173,7 @@ msgstr "Le changement DHT nécessite la fermeture puis réouverture du tunnel" #: ../java/src/org/klomp/snark/SnarkManager.java:728 #, java-format msgid "{0} theme loaded, return to main i2psnark page to view." -msgstr "" -"Thème {0} chargé, revenez à la page d''accueil d''i2psnark pour voir comme " -"il est beau !" +msgstr "Thème {0} chargé, revenez à la page d''accueil d''i2psnark pour voir comme il est beau !" #: ../java/src/org/klomp/snark/SnarkManager.java:738 msgid "Configuration unchanged." @@ -191,15 +181,11 @@ msgstr "Aucun changement de configuration." #: ../java/src/org/klomp/snark/SnarkManager.java:770 msgid "Open Tracker list changed - torrent restart required to take effect." -msgstr "" -"Liste des Open trackers modifiée - redémarrage des torrents requis pour " -"prise en compte" +msgstr "Liste des Open trackers modifiée - redémarrage des torrents requis pour prise en compte" #: ../java/src/org/klomp/snark/SnarkManager.java:780 msgid "Private tracker list changed - affects newly created torrents only." -msgstr "" -"Liste tracker privé modifiée - affecte seulement les torrents nouvellement " -"créés." +msgstr "Liste tracker privé modifiée - affecte seulement les torrents nouvellement créés." #: ../java/src/org/klomp/snark/SnarkManager.java:826 #, java-format @@ -226,7 +212,8 @@ msgstr "Erreur : Impossible d’ajouter le torrent : {0}" msgid "Cannot open \"{0}\"" msgstr "Impossible d’ouvrir: \"{0}\"" -#. TODO - if the existing one is a magnet, delete it and add the metainfo instead? +#. TODO - if the existing one is a magnet, delete it and add the metainfo +#. instead? #: ../java/src/org/klomp/snark/SnarkManager.java:957 #: ../java/src/org/klomp/snark/SnarkManager.java:1058 #: ../java/src/org/klomp/snark/SnarkManager.java:1140 @@ -243,30 +230,24 @@ msgstr "ERREUR - Pas de trackers I2P dans le torrent privé \"{0}\"" #: ../java/src/org/klomp/snark/SnarkManager.java:965 #, java-format msgid "" -"Warning - No I2P trackers in \"{0}\", will announce to I2P open trackers and " -"DHT only." -msgstr "" -"Avertissement - Pas de trackers I2P dans \"{0}\", vais annoncer aux trackers " -"I2P ouverts et DHT seulement." +"Warning - No I2P trackers in \"{0}\", will announce to I2P open trackers and" +" DHT only." +msgstr "Avertissement - Pas de trackers I2P dans \"{0}\", vais annoncer aux trackers I2P ouverts et DHT seulement." #: ../java/src/org/klomp/snark/SnarkManager.java:968 #, java-format msgid "" "Warning - No I2P trackers in \"{0}\", and open trackers are disabled, will " "announce to DHT only." -msgstr "" -"Avertissement - Pas de trackers I2P dans \"{0}\", et les trackers ouverts " -"sont désactivés, vais annoncer à DHT seulement." +msgstr "Avertissement - Pas de trackers I2P dans \"{0}\", et les trackers ouverts sont désactivés, vais annoncer à DHT seulement." #: ../java/src/org/klomp/snark/SnarkManager.java:970 #, java-format msgid "" "Warning - No I2P trackers in \"{0}\", and DHT and open trackers are " -"disabled, you should enable open trackers or DHT before starting the torrent." -msgstr "" -"Avertissement - Pas de trackers I2P dans \"{0}\", et DHT et les trackers " -"ouverts sont désactivés, vous devriez activer les trackers ouverts ou DHT " -"avant de démarrer le torrent." +"disabled, you should enable open trackers or DHT before starting the " +"torrent." +msgstr "Avertissement - Pas de trackers I2P dans \"{0}\", et DHT et les trackers ouverts sont désactivés, vous devriez activer les trackers ouverts ou DHT avant de démarrer le torrent." #: ../java/src/org/klomp/snark/SnarkManager.java:992 #, java-format @@ -277,8 +258,7 @@ msgstr "Le torrent dans \"{0}\" est invalide" #: ../java/src/org/klomp/snark/web/FetchAndAdd.java:186 #, java-format msgid "ERROR - Out of memory, cannot create torrent from {0}" -msgstr "" -"ERREUR - Mémoire insuffisante, impossible de créer le torrent depuis {0}" +msgstr "ERREUR - Mémoire insuffisante, impossible de créer le torrent depuis {0}" #: ../java/src/org/klomp/snark/SnarkManager.java:1011 #, java-format @@ -300,11 +280,9 @@ msgstr "Envoi {0}" #, java-format msgid "" "Open trackers are disabled and we have no DHT peers. Fetch of {0} may not " -"succeed until you start another torrent, enable open trackers, or enable DHT." -msgstr "" -"Les trackers ouverts sont désactivés et nous n''avons pas de pairs DHT. La " -"recherche de {0} pourrait ne pas réussir jusqu''à ce que vous démarriez un " -"autre torrent, activiez trackers ouverts, ou activeiz DHT." +"succeed until you start another torrent, enable open trackers, or enable " +"DHT." +msgstr "Les trackers ouverts sont désactivés et nous n''avons pas de pairs DHT. La recherche de {0} pourrait ne pas réussir jusqu''à ce que vous démarriez un autre torrent, activiez trackers ouverts, ou activeiz DHT." #: ../java/src/org/klomp/snark/SnarkManager.java:1079 #, java-format @@ -331,9 +309,7 @@ msgstr "Trop de fichiers dans \"{0}\" ({1}), suppression! " #: ../java/src/org/klomp/snark/SnarkManager.java:1402 #, java-format msgid "Torrent file \"{0}\" cannot end in \".torrent\", deleting it!" -msgstr "" -"Le fichier torrent \"{0}\" ne peut pas se terminer par \".torrent\", " -"suppression!" +msgstr "Le fichier torrent \"{0}\" ne peut pas se terminer par \".torrent\", suppression!" #: ../java/src/org/klomp/snark/SnarkManager.java:1404 #, java-format @@ -363,9 +339,7 @@ msgstr "Le fichier torrent \"{0}\" n'a pas de données, suppression!" #: ../java/src/org/klomp/snark/SnarkManager.java:1419 #, java-format msgid "Torrents larger than {0}B are not supported yet, deleting \"{1}\"" -msgstr "" -"Les torrents dont la taille est supérieure à \"{0}\"octets ne sont pas " -"encore supportés, suppression \"{1}\"." +msgstr "Les torrents dont la taille est supérieure à \"{0}\"octets ne sont pas encore supportés, suppression \"{1}\"." #: ../java/src/org/klomp/snark/SnarkManager.java:1435 #, java-format @@ -670,8 +644,7 @@ msgstr "Dernière page" #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:744 #, java-format msgid "Invalid URL: Must start with \"http://\", \"{0}\", or \"{1}\"" -msgstr "" -"URL incorrecte - elle doit débuter par \"http://\", \"{0}\", ou \"{1}\"" +msgstr "URL incorrecte - elle doit débuter par \"http://\", \"{0}\", ou \"{1}\"" #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:785 #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:814 @@ -714,9 +687,7 @@ msgstr "Répertoire effacé: {0}" #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:933 msgid "Error - Cannot include alternate trackers without a primary tracker" -msgstr "" -"Erreur - Ne peut pas inclure de trackers trackers alternatifs sans un " -"tracker primaire" +msgstr "Erreur - Ne peut pas inclure de trackers trackers alternatifs sans un tracker primaire" #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:946 msgid "Error - Cannot mix private and public trackers in a torrent" @@ -732,9 +703,7 @@ msgstr "Torrent créé pour \"{0}\"" msgid "" "Many I2P trackers require you to register new torrents before seeding - " "please do so before starting \"{0}\"" -msgstr "" -"De nombreux trackers I2P nécessitent d’enregistrer les nouveaux torrents " -"avant de seeder - faites-le avant de démarrer \"{0}\"!" +msgstr "De nombreux trackers I2P nécessitent d’enregistrer les nouveaux torrents avant de seeder - faites-le avant de démarrer \"{0}\"!" #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:970 #, java-format @@ -748,8 +717,7 @@ msgstr "Impossible de créer un torrent pour des données inexistantes: {0}" #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:977 msgid "Error creating torrent - you must enter a file or directory" -msgstr "" -"Erreur de création du torrent - vous devez saisir un fichier ou un répertoire" +msgstr "Erreur de création du torrent - vous devez saisir un fichier ou un répertoire" #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1008 #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2018 @@ -776,7 +744,8 @@ msgstr "Ajout tracker" msgid "Enter valid tracker name and URLs" msgstr "Entrez nom de tracker valide et URLs" -#. "\n" + +#. "\n" + #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1082 #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2021 msgid "Restore defaults" @@ -897,9 +866,7 @@ msgstr "Enlever le torrent de la liste active, suprression du fichier .torrent" msgid "" "Are you sure you want to delete the file \\''{0}\\'' (downloaded data will " "not be deleted) ?" -msgstr "" -"Êtes-vous sûr que vous voulez supprimer le fichier \\''{0}\\'' (les données " -"téléchargées ne seront pas supprimées) ?" +msgstr "Êtes-vous sûr que vous voulez supprimer le fichier \\''{0}\\'' (les données téléchargées ne seront pas supprimées) ?" #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1438 msgid "Remove" @@ -907,8 +874,7 @@ msgstr "Enlever" #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1450 msgid "Delete the .torrent file and the associated data file(s)" -msgstr "" -"Supprimer le fichier .torrent et le(s) fichier(s) de données associé(s)" +msgstr "Supprimer le fichier .torrent et le(s) fichier(s) de données associé(s)" #. Can't figure out how to escape double quotes inside the onclick string. #. Single quotes in translate strings with parameters must be doubled. @@ -918,9 +884,7 @@ msgstr "" msgid "" "Are you sure you want to delete the torrent \\''{0}\\'' and all downloaded " "data?" -msgstr "" -"Êtes-vous certain de vouloir supprimer le torrent \\''{0}\\'' ainsi que " -"toutes les données téléchargées ?" +msgstr "Êtes-vous certain de vouloir supprimer le torrent \\''{0}\\'' ainsi que toutes les données téléchargées ?" #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1458 #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1988 @@ -970,11 +934,9 @@ msgstr "Depuis l'URL" #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1680 msgid "" -"Enter the torrent file download URL (I2P only), magnet link, maggot link, or " -"info hash" -msgstr "" -"Entrez l'URL de téléchargement du fichier torrent (I2P seulement), lien " -"magnet, lien maggot, or l'info hash" +"Enter the torrent file download URL (I2P only), magnet link, maggot link, or" +" info hash" +msgstr "Entrez l'URL de téléchargement du fichier torrent (I2P seulement), lien magnet, lien maggot, or l'info hash" #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1685 msgid "Add torrent" @@ -993,7 +955,8 @@ msgstr "La suppression d'un fichier .torrent entraîne l'arrêt du torrent." msgid "Create Torrent" msgstr "Créer torrent" -#. out.write("From file:
\n"); +#. out.write("From file:
\n"); #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1716 msgid "Data to seed" msgstr "Données à seeder" @@ -1038,8 +1001,7 @@ msgstr "Fichiers lisibles par tous" #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1792 msgid "If checked, other users may access the downloaded files" -msgstr "" -"SI coché, les autres utilisateurs pourront accéder aux fichiers téléchargés." +msgstr "Si coché, les autres utilisateurs pourront accéder aux fichiers téléchargés." #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1796 msgid "Auto start" @@ -1103,11 +1065,9 @@ msgstr "Utiliser les open trackers aussi" #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1888 msgid "" -"If checked, announce torrents to open trackers as well as the tracker listed " -"in the torrent file" -msgstr "" -"Si coché, les torrents seront annoncés vers les open trackers ainsi que vers " -"les trackers indiqués dans le fichier torrent" +"If checked, announce torrents to open trackers as well as the tracker listed" +" in the torrent file" +msgstr "Si coché, les torrents seront annoncés vers les open trackers ainsi que vers les trackers indiqués dans le fichier torrent" #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1892 msgid "Enable DHT" diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java index f522193f6..42bad53f0 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java @@ -53,6 +53,9 @@ import java.util.StringTokenizer; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.atomic.AtomicLong; +import gnu.getopt.Getopt; +import gnu.getopt.LongOpt; + import net.i2p.I2PAppContext; import net.i2p.I2PException; import net.i2p.client.I2PClient; @@ -107,18 +110,46 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { private final Set listeners = new CopyOnWriteArraySet(); - public static void main(String[] args) throws IOException { - new I2PTunnel(args); + private static final int NOGUI = 99999; + private static final LongOpt[] longopts = new LongOpt[] { + new LongOpt("cli", LongOpt.NO_ARGUMENT, null, 'c'), + new LongOpt("die", LongOpt.NO_ARGUMENT, null, 'd'), + new LongOpt("gui", LongOpt.NO_ARGUMENT, null, 'g'), + new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'), + new LongOpt("nocli", LongOpt.NO_ARGUMENT, null, 'w'), + new LongOpt("nogui", LongOpt.NO_ARGUMENT, null, NOGUI), + new LongOpt("wait", LongOpt.NO_ARGUMENT, null, 'w') + }; + + public static void main(String[] args) { + try { + new I2PTunnel(args); + } catch (IllegalArgumentException iae) { + System.err.println(iae.toString()); + System.exit(1); + } } + /** + * Standard constructor for embedded, uses args "-nocli -die" to return immediately + */ public I2PTunnel() { this(nocli_args); } + /** + * See usage() for options + * @throws IllegalArgumentException + */ public I2PTunnel(String[] args) { this(args, null); } + /** + * See usage() for options + * @param lsnr may be null + * @throws IllegalArgumentException + */ public I2PTunnel(String[] args, ConnectionEventListener lsnr) { super(); _context = I2PAppContext.getGlobalContext(); // new I2PAppContext(); @@ -134,37 +165,95 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { boolean checkRunByE = true; boolean cli = true; boolean dontDie = true; - for (int i = 0; i < args.length; i++) { - if (args[i].equals("-die")) { + boolean error = false; + List eargs = null; + Getopt g = new Getopt("i2ptunnel", args, "d::n:c::w::e:h::", longopts); + int c; + while ((c = g.getopt()) != -1) { + switch (c) { + case 'd': // -d, -die, --die dontDie = false; gui = false; cli = false; checkRunByE = false; - } else if (args[i].equals("-nogui")) { + break; + + case 'n': // -noc, -nog, -nocli, -nogui + String a = g.getOptarg(); + if (a.startsWith("oc")) { + gui = false; + cli = false; + checkRunByE = false; + break; + } else if (a.startsWith("og")) { + // fall thru + } else { + error = true; + break; + } + // fall thru for -nogui only + + case NOGUI: // --nogui gui = false; - _log.warn(getPrefix() + "The `-nogui' option of I2PTunnel is deprecated.\n" + if (_log.shouldLog(Log.WARN)) + _log.warn(getPrefix() + "The `-nogui' option of I2PTunnel is deprecated.\n" + "Use `-cli', `-nocli' (aka `-wait') or `-die' instead."); - } else if (args[i].equals("-cli")) { + + case 'c': // -c, -cli, --cli gui = false; cli = true; checkRunByE = false; - } else if (args[i].equals("-nocli") || args[i].equals("-wait")) { + break; + + case 'w': // -w, -wait, --nocli gui = false; cli = false; checkRunByE = false; - } else if (args[i].equals("-e")) { - runCommand(args[i + 1], this); - i++; + break; + + case 'e': + if (eargs == null) + eargs = new ArrayList(4); + eargs.add(g.getOptarg()); if (checkRunByE) { checkRunByE = false; cli = false; } - } else if (new File(args[i]).exists()) { - runCommand("run " + args[i], this); - } else { - System.out.println("Unknown parameter " + args[i]); + break; + + case 'h': + case '?': + case ':': + default: + error = true; + } + } + + int remaining = args.length - g.getOptind(); + + if (error || remaining > 1) { + System.err.println(usage()); + throw new IllegalArgumentException(); + } + + if (eargs != null) { + for (String arg : eargs) { + runCommand(arg, this); } } + + if (remaining == 1) { + String f = args[g.getOptind()]; + File file = new File(f); + // This is probably just a problem with the options, so + // throw from here + if (!file.exists()) { + System.err.println(usage()); + throw new IllegalArgumentException("Command file does not exist: " + f); + } + runCommand("run " + f, this); + } + if (gui) { new I2PTunnelGUI(this); } else if (cli) { @@ -185,6 +274,9 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { } catch (IOException ex) { ex.printStackTrace(); } + } else if (eargs == null && remaining == 0 && dontDie) { + System.err.println(usage()); + throw new IllegalArgumentException("Waiting for nothing! Specify gui, cli, command, command file, or die"); } while (dontDie) { @@ -197,6 +289,23 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { } } + /** with newlines except for last line */ + private static String usage() { + // not sure this all makes sense, just documenting what's above + return + "Usage: i2ptunnel [options] [commandFile]\n" + + " Default is to run the GUI.\n" + + " commandFile: run all commands in this file\n" + + " Options:\n" + + " -c, -cli, --cli : run the command line interface\n" + + " -d, -die, --die : exit immediately, do not wait for commands to finish\n" + + " -e 'command [args]' : run the command\n" + + " -h, --help : display this help\n" + + " -nocli, --nocli : do not run the command line interface or GUI\n" + + " -nogui, --nogui : do not run the GUI\n" + + " -w, -wait, --wait : do not run the command line interface or GUI"; + } + /** @return A copy, non-null */ List getSessions() { return new ArrayList(_sessions); @@ -312,30 +421,30 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { * @param l logger to receive events and output */ private static void runHelp(Logging l) { - l.log("Command list:"); + l.log("Command list:\n" + // alphabetical please... - l.log(" auth "); - l.log(" client [, []"); - l.log(" clientoptions [-acx] [key=value ]*"); - l.log(" close [forced] |all"); - l.log(" config [-s] "); - l.log(" connectclient [] []"); - l.log(" genkeys []"); - l.log(" gentextkeys"); - l.log(" httpbidirserver "); - l.log(" httpclient [] []"); - l.log(" httpserver "); - l.log(" ircclient [, []"); - l.log(" list"); - l.log(" listen_on "); - l.log(" lookup "); - l.log(" owndest yes|no"); - l.log(" ping "); - l.log(" quit"); - l.log(" read_timeout "); - l.log(" run "); - l.log(" server "); - l.log(" textserver "); + " auth \n" + + " client [, []\n" + + " clientoptions [-acx] [key=value ]*\n" + + " close [forced] |all\n" + + " config [-s] \n" + + " connectclient [] []\n" + + " genkeys []\n" + + " gentextkeys\n" + + " httpbidirserver \n" + + " httpclient [] []\n" + + " httpserver \n" + + " ircclient [, []\n" + + " list\n" + + " listen_on \n" + + " lookup \n" + + " owndest yes|no\n" + + " ping \n" + + " quit\n" + + " read_timeout \n" + + " run \n" + + " server \n" + + " textserver \n"); } /** @@ -378,12 +487,12 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { _clientOptions.setProperty(key, val); } } else { - l.log("Usage:"); - l.log(" clientoptions [key=value ]* // sets current options"); - l.log(" clientoptions -a [key=value ]* // adds to current options"); - l.log(" clientoptions -c // clears current options"); - l.log(" clientoptions -x [key ]* // removes listed options"); - l.log("Current options:"); + l.log("Usage:\n" + + " clientoptions [key=value ]* // sets current options\n" + + " clientoptions -a [key=value ]* // adds to current options\n" + + " clientoptions -c // clears current options\n" + + " clientoptions -x [key ]* // removes listed options\n" + + "Current options:\n"); Properties p = new OrderedProperties(); p.putAll(_clientOptions); for (Map.Entry e : p.entrySet()) { @@ -466,8 +575,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { notifyEvent("serverTaskId", Integer.valueOf(serv.getId())); return; } else { - l.log("server "); - l.log(" creates a server that sends all incoming data\n" + " of its destination to host:port."); + l.log("server \n" + + " creates a server that sends all incoming data\n" + " of its destination to host:port."); notifyEvent("serverTaskId", Integer.valueOf(-1)); } } @@ -517,8 +626,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { notifyEvent("serverTaskId", Integer.valueOf(serv.getId())); return; } else { - l.log("server "); - l.log(" creates a server that sends all incoming data\n" + " of its destination to host:port."); + l.log("server \n" + + " creates a server that sends all incoming data\n" + " of its destination to host:port."); notifyEvent("serverTaskId", Integer.valueOf(-1)); } } @@ -578,8 +687,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { notifyEvent("serverTaskId", Integer.valueOf(serv.getId())); return; } else { - l.log("httpserver "); - l.log(" creates an HTTP server that sends all incoming data\n" + l.log("httpserver \n" + + " creates an HTTP server that sends all incoming data\n" + " of its destination to host:port., filtering the HTTP\n" + " headers so it looks like the request is to the spoofed host."); notifyEvent("serverTaskId", Integer.valueOf(-1)); @@ -654,8 +763,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { notifyEvent("serverTaskId", Integer.valueOf(serv.getId())); return; } else { - l.log("httpserver "); - l.log(" creates a bidirectional HTTP server that sends all incoming data\n" + l.log("httpserver \n" + + " creates a bidirectional HTTP server that sends all incoming data\n" + " of its destination to host:port., filtering the HTTP\n" + " headers so it looks like the request is to the spoofed host," + " and listens to host:proxyport to proxy HTTP requests."); @@ -707,8 +816,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { addtask(serv); notifyEvent("serverTaskId", Integer.valueOf(serv.getId())); } else { - l.log("textserver "); - l.log(" creates a server that sends all incoming data\n" + " of its destination to host:port."); + l.log("textserver \n" + + " creates a server that sends all incoming data\n" + " of its destination to host:port."); notifyEvent("textserverTaskId", Integer.valueOf(-1)); } } @@ -765,8 +874,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { throw iae; } } else { - l.log("client [,]|file:[ ] []"); - l.log(" creates a client that forwards port to the pubkey.\n" + l.log("client [,]|file:[ ] []\n" + + " creates a client that forwards port to the pubkey.\n" + " use 0 as port to get a free port assigned. If you specify\n" + " a comma delimited list of pubkeys, it will rotate among them\n" + " randomlyl. sharedClient indicates if this client shares \n" @@ -841,11 +950,11 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { throw iae; } } else { - l.log("httpclient [] []"); - l.log(" creates a client that distributes HTTP requests."); - l.log(" (optional) indicates if this client shares tunnels with other clients (true of false)"); - l.log(" (optional) indicates a proxy server to be used"); - l.log(" when trying to access an address out of the .i2p domain"); + l.log("httpclient [] []\n" + + " creates a client that distributes HTTP requests.\n" + + " (optional) indicates if this client shares tunnels with other clients (true of false)\n" + + " (optional) indicates a proxy server to be used\n" + + " when trying to access an address out of the .i2p domain"); notifyEvent("httpclientTaskId", Integer.valueOf(-1)); } } @@ -908,11 +1017,11 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { throw iae; } } else { - l.log("connectclient [] []"); - l.log(" creates a client that for SSL/HTTPS requests."); - l.log(" (optional) indicates if this client shares tunnels with other clients (true of false)"); - l.log(" (optional) indicates a proxy server to be used"); - l.log(" when trying to access an address out of the .i2p domain"); + l.log("connectclient [] []\n" + + " creates a client that for SSL/HTTPS requests.\n" + + " (optional) indicates if this client shares tunnels with other clients (true of false)\n" + + " (optional) indicates a proxy server to be used\n" + + " when trying to access an address out of the .i2p domain\n"); } } @@ -975,9 +1084,9 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { throw iae; } } else { - l.log("ircclient [ []]"); - l.log(" creates a client that filter IRC protocol."); - l.log(" (optional) indicates if this client shares tunnels with other clients (true of false)"); + l.log("ircclient [ []]\n" + + " creates a client that filter IRC protocol.\n" + + " (optional) indicates if this client shares tunnels with other clients (true of false)\n"); notifyEvent("ircclientTaskId", Integer.valueOf(-1)); } } @@ -1028,8 +1137,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { throw iae; } } else { - l.log("sockstunnel "); - l.log(" creates a tunnel that distributes SOCKS requests."); + l.log("sockstunnel \n" + + " creates a tunnel that distributes SOCKS requests."); notifyEvent("sockstunnelTaskId", Integer.valueOf(-1)); } } @@ -1075,8 +1184,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { throw iae; } } else { - l.log("socksirctunnel [ []]"); - l.log(" creates a tunnel for SOCKS IRC."); + l.log("socksirctunnel [ []]\n" + + " creates a tunnel for SOCKS IRC."); notifyEvent("sockstunnelTaskId", Integer.valueOf(-1)); } } @@ -1125,8 +1234,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { throw iae; } } else { - l.log("streamrclient "); - l.log(" creates a tunnel that receives streaming data."); + l.log("streamrclient \n" + + " creates a tunnel that receives streaming data."); notifyEvent("streamrtunnelTaskId", Integer.valueOf(-1)); } } @@ -1166,8 +1275,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { addtask(task); notifyEvent("streamrtunnelTaskId", Integer.valueOf(task.getId())); } else { - l.log("streamrserver "); - l.log(" creates a tunnel that sends streaming data."); + l.log("streamrserver \n" + + " creates a tunnel that sends streaming data."); notifyEvent("streamrtunnelTaskId", Integer.valueOf(-1)); } } @@ -1195,12 +1304,12 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { port = args[i]; notifyEvent("configResult", "ok"); } else { - l.log("Usage:"); - l.log(" config [-s] "); - l.log(" sets the connection to the i2p router."); - l.log("Current setting:"); boolean ssl = Boolean.parseBoolean(_clientOptions.getProperty("i2cp.SSL")); - l.log(" " + host + ' ' + port + (ssl ? " SSL" : "")); + l.log("Usage:\n" + + " config [-s] \n" + + " sets the connection to the i2p router.\n" + + "Current setting:\n" + + " " + host + ' ' + port + (ssl ? " SSL" : "")); notifyEvent("configResult", "error"); } } @@ -1210,16 +1319,16 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { * * @param args {username, password} * @param l logger to receive events and output - * @since 0.9.10 + * @since 0.9.11 */ private void runAuth(String args[], Logging l) { if (args.length == 2) { _clientOptions.setProperty("i2cp.username", args[0]); _clientOptions.setProperty("i2cp.password", args[1]); } else { - l.log("Usage:"); - l.log(" auth "); - l.log(" Sets the i2cp credentials"); + l.log("Usage:\n" + + " auth \n" + + " Sets the i2cp credentials"); } } @@ -1237,8 +1346,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { ownDest = args[0].equalsIgnoreCase("yes"); notifyEvent("owndestResult", "ok"); } else { - l.log("owndest yes|no"); - l.log(" Specifies whether to use its own destination \n" + " for each outgoing tunnel"); + l.log("owndest yes|no\n" + + " Specifies whether to use its own destination \n" + " for each outgoing tunnel"); notifyEvent("owndestResult", "error"); } } @@ -1256,8 +1365,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { listenHost = args[0]; notifyEvent("listen_onResult", "ok"); } else { - l.log("listen_on "); - l.log(" sets the interface to listen for the I2PClient."); + l.log("listen_on \n" + + " sets the interface to listen for the I2PClient."); notifyEvent("listen_onResult", "error"); } } @@ -1279,15 +1388,16 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { } notifyEvent("read_timeoutResult", "ok"); } else { - l.log("read_timeout "); - l.log(" sets the read timeout (in milliseconds) for I2P connections\n" + l.log("read_timeout \n" + + " sets the read timeout (in milliseconds) for I2P connections\n" +" Negative values will make the connections wait forever"); notifyEvent("read_timeoutResult", "error"); } } /** - * Generate a new keypair + * Generate a new keypair. + * Does NOT support non-default sig types. * Deprecated - only used by CLI * * Sets the event "genkeysResult" = "ok" or "error" after the generation is complete @@ -1307,8 +1417,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { return; } } else if (args.length != 1) { - l.log("genkeys []"); - l.log(" creates a new keypair and prints the public key.\n" + l.log("genkeys []\n" + + " creates a new keypair and prints the public key.\n" + " if pubkeyfile is given, saves the public key there." + "\n" + " if the privkeyfile already exists, just print/save" + "the pubkey."); //notifyEvent("genkeysResult", "error"); @@ -1330,7 +1440,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { } /** - * Generate a new keypair + * Generate a new keypair. + * Does NOT support non-default sig types. * Deprecated - only used by CLI * * Sets the event "privateKey" = base64 of the privateKey stream and @@ -1339,7 +1450,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { * @param l logger to receive events and output */ private static void runGenTextKeys(Logging l) { - ByteArrayOutputStream privkey = new ByteArrayOutputStream(512); + ByteArrayOutputStream privkey = new ByteArrayOutputStream(1024); ByteArrayOutputStream pubkey = new ByteArrayOutputStream(512); makeKey(privkey, pubkey, l); l.log("Private key: " + Base64.encode(privkey.toByteArray())); @@ -1394,8 +1505,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { */ public void runClose(String args[], Logging l) { if (args.length == 0 || args.length > 2) { - l.log("close [forced] |all"); - l.log(" stop running tasks. either only one or all.\n" + l.log("close [forced] |all\n" + + " stop running tasks. either only one or all.\n" + " use 'forced' to also stop tasks with active connections.\n" + " use the 'list' command to show the job numbers"); notifyEvent("closeResult", "error"); @@ -1456,8 +1567,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { notifyEvent("runResult", "error"); } } else { - l.log("run "); - l.log(" loads commandfile and runs each line in it. \n" + l.log("run \n" + + " loads commandfile and runs each line in it. \n" + " You can also give the filename on the commandline."); notifyEvent("runResult", "error"); } @@ -1474,8 +1585,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { */ private void runLookup(String args[], Logging l) { if (args.length != 1) { - l.log("lookup "); - l.log(" try to resolve the name into a destination key"); + l.log("lookup \n" + + " try to resolve the name into a destination key"); notifyEvent("lookupResult", "invalidUsage"); } else { try { @@ -1513,15 +1624,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { addtask(task); notifyEvent("pingTaskId", Integer.valueOf(task.getId())); } else { - l.log("ping "); - l.log("ping -h (pings all hosts in hosts.txt)"); - l.log("ping -l (pings a list of hosts in a file)"); - l.log(" Options:\n" + - " -c (require 5 consecutive pings to report success)\n" + - " -m maxSimultaneousPings (default 10)\n" + - " -n numberOfPings (default 3)\n" + - " -t timeout (ms, default 30000)\n"); - l.log(" Tests communication with peers.\n"); + l.log(I2Ping.usage()); notifyEvent("pingTaskId", Integer.valueOf(-1)); } } @@ -1593,10 +1696,11 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { /** * Create a new destination, storing the destination and its private keys where - * instructed + * instructed. + * Does NOT support non-default sig types. * Deprecated - only used by CLI * - * @param writeTo location to store the private keys + * @param writeTo location to store the destination and private keys * @param pubDest location to store the destination * @param l logger to send messages to */ @@ -1605,8 +1709,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { l.log("Generating new keys..."); I2PClient client = I2PClientFactory.createClient(); Destination d = client.createDestination(writeTo); - l.log("Secret key saved."); - l.log("Public key: " + d.toBase64()); + l.log("Secret key saved.\n" + + "Public key: " + d.toBase64()); writeTo.flush(); writeTo.close(); writePubKey(d, pubDest, l); @@ -1673,7 +1777,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging { * @param i2cpPort may be null * @param user may be null * @param pw may be null - * @since 0.9.10 + * @since 0.9.11 */ private static Destination destFromName(String name, String i2cpHost, String i2cpPort, boolean isSSL, diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java index 17ea0019f..5b06e271b 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java @@ -55,7 +55,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna private int localPort; /** - * Protected for I2Ping since 0.9.10. Not for use outside package. + * Protected for I2Ping since 0.9.11. Not for use outside package. */ protected boolean listenerReady; @@ -586,7 +586,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna } /** - * Non-final since 0.9.10. + * Non-final since 0.9.11. * Any overrides must set listenerReady = true. */ public void run() { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java index 2ae58a398..9abcdd0fd 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java @@ -24,6 +24,7 @@ import net.i2p.I2PAppContext; import net.i2p.client.streaming.I2PSocketManager; import net.i2p.data.Base64; import net.i2p.data.DataHelper; +import net.i2p.util.EepGet; import net.i2p.util.EventDispatcher; import net.i2p.util.InternalSocket; import net.i2p.util.Log; @@ -409,60 +410,8 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem * @since 0.9.4 */ private static Map parseArgs(String args) { - Map rv = new HashMap(8); - char data[] = args.toCharArray(); - StringBuilder buf = new StringBuilder(32); - boolean isQuoted = false; - String key = null; - for (int i = 0; i < data.length; i++) { - switch (data[i]) { - case '\"': - if (isQuoted) { - // keys never quoted - if (key != null) { - rv.put(key, buf.toString().trim()); - key = null; - } - buf.setLength(0); - } - isQuoted = !isQuoted; - break; - - case ' ': - case '\r': - case '\n': - case '\t': - case ',': - // whitespace - if we're in a quoted section, keep this as part of the quote, - // otherwise use it as a delim - if (isQuoted) { - buf.append(data[i]); - } else { - if (key != null) { - rv.put(key, buf.toString().trim()); - key = null; - } - buf.setLength(0); - } - break; - - case '=': - if (isQuoted) { - buf.append(data[i]); - } else { - key = buf.toString().trim().toLowerCase(Locale.US); - buf.setLength(0); - } - break; - - default: - buf.append(data[i]); - break; - } - } - if (key != null) - rv.put(key, buf.toString().trim()); - return rv; + // moved to EepGet, since it needs this too + return EepGet.parseAuthArgs(args); } //////// Error page stuff diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java index e9a9a5b21..66351f749 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java @@ -18,6 +18,7 @@ import javax.net.ssl.SSLException; import net.i2p.I2PAppContext; import net.i2p.client.streaming.I2PSocket; import net.i2p.data.ByteArray; +import net.i2p.data.DataHelper; import net.i2p.util.ByteCache; import net.i2p.util.Clock; import net.i2p.util.I2PAppThread; @@ -137,6 +138,8 @@ public class I2PTunnelRunner extends I2PAppThread implements I2PSocket.SocketErr protected InputStream getSocketIn() throws IOException { return s.getInputStream(); } protected OutputStream getSocketOut() throws IOException { return s.getOutputStream(); } + private static final byte[] POST = { 'P', 'O', 'S', 'T', ' ' }; + @Override public void run() { try { @@ -159,8 +162,12 @@ public class I2PTunnelRunner extends I2PAppThread implements I2PSocket.SocketErr // So we now get a fast return from flush(), and can do it here to save 250 ms. // To make sure we are under the initial window size and don't hang waiting for accept, // only flush if it fits in one message. - if (initialI2PData.length <= 1730) // ConnectionOptions.DEFAULT_MAX_MESSAGE_SIZE - i2pout.flush(); + if (initialI2PData.length <= 1730) { // ConnectionOptions.DEFAULT_MAX_MESSAGE_SIZE + // Don't flush if POST, so we can get POST data into the initial packet + if (initialI2PData.length < 5 || + !DataHelper.eq(POST, 0, initialI2PData, 0, 5)) + i2pout.flush(); + } //} } if (initialSocketData != null) { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java index a41ae15ed..e8321e41a 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java @@ -11,6 +11,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +import gnu.getopt.Getopt; + import net.i2p.I2PAppContext; import net.i2p.I2PException; import net.i2p.client.I2PSession; @@ -86,48 +88,76 @@ public class I2Ping extends I2PTunnelClientBase { int count = PING_COUNT; boolean countPing = false; boolean reportTimes = true; - while (true) { - if (cmd.startsWith("-t ")) { // timeout - cmd = cmd.substring(3); - int pos = cmd.indexOf(" "); - if (pos == -1) { - l.log("Syntax error"); - return; - } else { - timeout = Long.parseLong(cmd.substring(0, pos)); + String hostListFile = null; + int localPort = 0; + int remotePort = 0; + boolean error = false; + String[] argv = cmd.split(" "); + Getopt g = new Getopt("ping", argv, "t:m:n:chl:f:p:"); + int c; + while ((c = g.getopt()) != -1) { + switch (c) { + case 't': // timeout + timeout = Long.parseLong(g.getOptarg()); // convenience, convert msec to sec if (timeout < 100) timeout *= 1000; - cmd = cmd.substring(pos + 1); - } - } else if (cmd.startsWith("-m ")) { // max simultaneous pings - cmd = cmd.substring(3); - int pos = cmd.indexOf(" "); - if (pos == -1) { - l.log("Syntax error"); - return; - } else { - MAX_SIMUL_PINGS = Integer.parseInt(cmd.substring(0, pos)); - cmd = cmd.substring(pos + 1); - } - } else if (cmd.startsWith("-n ")) { // number of pings - cmd = cmd.substring(3); - int pos = cmd.indexOf(" "); - if (pos == -1) { - l.log("Syntax error"); - return; - } else { - count = Integer.parseInt(cmd.substring(0, pos)); - cmd = cmd.substring(pos + 1); - } - } else if (cmd.startsWith("-c ")) { // "count" ping + break; + + case 'm': // max simultaneous pings + MAX_SIMUL_PINGS = Integer.parseInt(g.getOptarg()); + break; + + case 'n': // number of pings + count = Integer.parseInt(g.getOptarg()); + break; + + case 'c': // "count" ping countPing = true; count = CPING_COUNT; - cmd = cmd.substring(3); - } else if (cmd.equals("-h")) { // ping all hosts - cmd = "-l hosts.txt"; - } else if (cmd.startsWith("-l ")) { // ping a list of hosts - BufferedReader br = new BufferedReader(new FileReader(cmd.substring(3))); + break; + + case 'h': // ping all hosts + if (hostListFile != null) + error = true; + else + hostListFile = "hosts.txt"; + break; + + case 'l': // ping a list of hosts + if (hostListFile != null) + error = true; + else + hostListFile = g.getOptarg(); + break; + + case 'f': // local port + localPort = Integer.parseInt(g.getOptarg()); + break; + + case 'p': // remote port + remotePort = Integer.parseInt(g.getOptarg()); + break; + + case '?': + case ':': + default: + error = true; + } + } + + int remaining = argv.length - g.getOptind(); + + if (error || + remaining > 1 || + (remaining <= 0 && hostListFile == null) || + (remaining > 0 && hostListFile != null)) { + System.out.println(usage()); + return; + } + + if (hostListFile != null) { + BufferedReader br = new BufferedReader(new FileReader(hostListFile)); String line; List pingHandlers = new ArrayList(); int i = 0; @@ -138,7 +168,8 @@ public class I2Ping extends I2PTunnelClientBase { if (line.indexOf("=") != -1) { // maybe file is hosts.txt? line = line.substring(0, line.indexOf("=")); } - PingHandler ph = new PingHandler(line, count, timeout, countPing, reportTimes); + PingHandler ph = new PingHandler(line, count, localPort, remotePort, + timeout, countPing, reportTimes); ph.start(); pingHandlers.add(ph); if (++i > 1) @@ -148,13 +179,31 @@ public class I2Ping extends I2PTunnelClientBase { for (Thread t : pingHandlers) t.join(); return; - } else { - Thread t = new PingHandler(cmd, count, timeout, countPing, reportTimes); - t.start(); - t.join(); - return; - } } + + String host = argv[g.getOptind()]; + Thread t = new PingHandler(host, count, localPort, remotePort, + timeout, countPing, reportTimes); + t.start(); + t.join(); + } + + /** + * With newlines except for last line + * @since 0.9.12 + */ + public static String usage() { + return + "ping \n" + + "ping -h (pings all hosts in hosts.txt)\n" + + "ping -l (pings a list of hosts in a file)\n" + + "Options:\n" + + " -c (require 5 consecutive pings to report success)\n" + + " -m maxSimultaneousPings (default 10)\n" + + " -n numberOfPings (default 3)\n" + + " -t timeout (ms, default 30000)\n" + + " -f fromPort\n" + + " -p toPort"; } @Override @@ -170,7 +219,7 @@ public class I2Ping extends I2PTunnelClientBase { return true; } - private boolean ping(Destination dest, long timeout) throws I2PException { + private boolean ping(Destination dest, int fromPort, int toPort, long timeout) throws I2PException { try { synchronized (simulLock) { while (simulPings >= MAX_SIMUL_PINGS) { @@ -183,7 +232,7 @@ public class I2Ping extends I2PTunnelClientBase { } lastPingTime = System.currentTimeMillis(); } - boolean sent = sockMgr.ping(dest, timeout); + boolean sent = sockMgr.ping(dest, fromPort, toPort, timeout); synchronized (simulLock) { simulPings--; simulLock.notifyAll(); @@ -197,7 +246,7 @@ public class I2Ping extends I2PTunnelClientBase { /** * Does nothing. - * @since 0.9.10 + * @since 0.9.11 */ protected void clientConnectionRun(Socket s) {} @@ -207,15 +256,20 @@ public class I2Ping extends I2PTunnelClientBase { private final long timeout; private final boolean countPing; private final boolean reportTimes; + private final int localPort; + private final int remotePort; /** - * As of 0.9.10, does NOT start itself. + * As of 0.9.11, does NOT start itself. * Caller must call start() * @param dest b64 or b32 or host name */ - public PingHandler(String dest, int count, long timeout, boolean countPings, boolean report) { + public PingHandler(String dest, int count, int fromPort, int toPort, + long timeout, boolean countPings, boolean report) { this.destination = dest; cnt = count; + localPort = fromPort; + remotePort = toPort; this.timeout = timeout; countPing = countPings; reportTimes = report; @@ -235,8 +289,7 @@ public class I2Ping extends I2PTunnelClientBase { long totalTime = 0; StringBuilder pingResults = new StringBuilder(2 * cnt + destination.length() + 3); for (int i = 0; i < cnt; i++) { - boolean sent; - sent = ping(dest, timeout); + boolean sent = ping(dest, localPort, remotePort, timeout); if (countPing) { if (!sent) { pingResults.append(i).append(" "); @@ -276,7 +329,7 @@ public class I2Ping extends I2PTunnelClientBase { /** * @param name b64 or b32 or host name - * @since 0.9.10 + * @since 0.9.11 */ private Destination lookup(String name) { I2PAppContext ctx = I2PAppContext.getGlobalContext(); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java index 1b1fdefcf..5936b6936 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java @@ -7,11 +7,13 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Properties; + import net.i2p.I2PAppContext; import net.i2p.I2PException; import net.i2p.client.I2PClient; import net.i2p.client.I2PClientFactory; import net.i2p.client.I2PSession; +import net.i2p.crypto.SigType; import net.i2p.data.Base32; import net.i2p.data.Destination; import net.i2p.i2ptunnel.socks.I2PSOCKSTunnel; @@ -49,8 +51,8 @@ public class TunnelController implements Logging { * the prefix should be used (and, in turn, that prefix should be stripped off * before being interpreted by this controller) * - * @param config original key=value mapping - * @param prefix beginning of key values that are relevent to this tunnel + * @param config original key=value mapping non-null + * @param prefix beginning of key values that are relevant to this tunnel */ public TunnelController(Properties config, String prefix) { this(config, prefix, true); @@ -58,6 +60,8 @@ public class TunnelController implements Logging { /** * + * @param config original key=value mapping non-null + * @param prefix beginning of key values that are relevant to this tunnel * @param createKey for servers, whether we want to create a brand new destination * with private keys at the location specified or not (does not * overwrite existing ones) @@ -99,7 +103,16 @@ public class TunnelController implements Logging { FileOutputStream fos = null; try { fos = new SecureFileOutputStream(keyFile); - Destination dest = client.createDestination(fos); + SigType stype = I2PClient.DEFAULT_SIGTYPE; + String st = _config.getProperty("option." + I2PClient.PROP_SIGTYPE); + if (st != null) { + SigType type = SigType.parseSigType(st); + if (type != null) + stype = type; + else + log("Unsupported sig type " + st); + } + Destination dest = client.createDestination(fos, stype); String destStr = dest.toBase64(); log("Private key created and saved in " + keyFile.getAbsolutePath()); log("You should backup this file in a secure place."); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udpTunnel/I2PTunnelUDPClientBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udpTunnel/I2PTunnelUDPClientBase.java index 425cfb9ca..f1e8abaab 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udpTunnel/I2PTunnelUDPClientBase.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/udpTunnel/I2PTunnelUDPClientBase.java @@ -12,6 +12,7 @@ import net.i2p.client.I2PClient; import net.i2p.client.I2PClientFactory; import net.i2p.client.I2PSession; import net.i2p.client.I2PSessionException; +import net.i2p.crypto.SigType; import net.i2p.data.Destination; import net.i2p.i2ptunnel.I2PTunnel; import net.i2p.i2ptunnel.I2PTunnelTask; @@ -78,8 +79,17 @@ import net.i2p.util.EventDispatcher; I2PClient client = I2PClientFactory.createClient(); byte[] key; try { - ByteArrayOutputStream out = new ByteArrayOutputStream(512); - client.createDestination(out); + ByteArrayOutputStream out = new ByteArrayOutputStream(1024); + SigType stype = I2PClient.DEFAULT_SIGTYPE; + String st = tunnel.getClientOptions().getProperty(I2PClient.PROP_SIGTYPE); + if (st != null) { + SigType type = SigType.parseSigType(st); + if (type != null) + stype = type; + else + l.log("Unsupported sig type " + st); + } + client.createDestination(out, stype); key = out.toByteArray(); } catch(Exception exc) { throw new RuntimeException("failed to create i2p-destination", exc); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java index 990d2d1f1..77c89319b 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java @@ -14,6 +14,7 @@ import java.util.Properties; import java.util.Set; import java.util.TreeMap; +import net.i2p.client.I2PClient; import net.i2p.data.Base64; import net.i2p.data.Destination; import net.i2p.data.PrivateKeyFile; @@ -177,6 +178,11 @@ public class EditBean extends IndexBean { return getBooleanProperty(tunnel, "i2cp.encryptLeaseSet"); } + /** @since 0.9.12 */ + public int getSigType(int tunnel) { + return getProperty(tunnel, I2PClient.PROP_SIGTYPE, 0); + } + /** @since 0.8.9 */ public boolean getDCC(int tunnel) { return getBooleanProperty(tunnel, I2PTunnelIRCClient.PROP_DCC); @@ -358,6 +364,11 @@ public class EditBean extends IndexBean { return Addresses.getAllAddresses(); } + /** @since 0.9.12 */ + public boolean isAdvanced() { + return _context.getBooleanProperty("routerconsole.advanced"); + } + public String getI2CPHost(int tunnel) { if (_context.isRouterContext()) return _("internal"); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java index f674f490c..9b9ad31ad 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java @@ -24,6 +24,7 @@ import java.util.concurrent.ConcurrentHashMap; import net.i2p.I2PAppContext; import net.i2p.app.ClientAppManager; import net.i2p.app.Outproxy; +import net.i2p.client.I2PClient; import net.i2p.data.Base32; import net.i2p.data.Certificate; import net.i2p.data.Destination; @@ -983,6 +984,7 @@ public class IndexBean { } catch (NumberFormatException nfe) {} } } + public void setCert(String val) { if (val != null) { try { @@ -990,10 +992,24 @@ public class IndexBean { } catch (NumberFormatException nfe) {} } } + public void setSigner(String val) { _certSigner = val; } + /** @since 0.9.12 */ + public void setSigType(String val) { + if (val != null) { + _otherOptions.put(I2PClient.PROP_SIGTYPE, val); + if (val.equals("0")) + _certType = 0; + else + _certType = 5; + } + // TODO: Call modifyDestination?? + // Otherwise this only works on a new tunnel... + } + /** Modify or create a destination */ private String modifyDestination() { if (_privKeyFile == null || _privKeyFile.trim().length() <= 0) @@ -1234,13 +1250,14 @@ public class IndexBean { "outproxyUsername", "outproxyPassword", I2PTunnelHTTPClient.PROP_JUMP_SERVERS, I2PTunnelHTTPClientBase.PROP_AUTH, + I2PClient.PROP_SIGTYPE, I2PTunnelHTTPClient.PROP_SSL_OUTPROXIES }; private static final String _otherServerOpts[] = { "i2cp.reduceIdleTime", "i2cp.reduceQuantity", "i2cp.leaseSetKey", "i2cp.accessList", PROP_MAX_CONNS_MIN, PROP_MAX_CONNS_HOUR, PROP_MAX_CONNS_DAY, PROP_MAX_TOTAL_CONNS_MIN, PROP_MAX_TOTAL_CONNS_HOUR, PROP_MAX_TOTAL_CONNS_DAY, - PROP_MAX_STREAMS + PROP_MAX_STREAMS, I2PClient.PROP_SIGTYPE }; private static final String _httpServerOpts[] = { I2PTunnelHTTPServer.OPT_POST_WINDOW, diff --git a/apps/i2ptunnel/jsp/editClient.jsp b/apps/i2ptunnel/jsp/editClient.jsp index ff397556c..2b560173c 100644 --- a/apps/i2ptunnel/jsp/editClient.jsp +++ b/apps/i2ptunnel/jsp/editClient.jsp @@ -449,6 +449,37 @@ input.default { width: 1px; height: 1px; visibility: hidden; } <% } %> + <% if (editBean.isAdvanced()) { %> +
+ +
+
+
+ + class="tickbox" /> +
+
+ + class="tickbox" /> +
+
+ + class="tickbox" /> +
+
+ + class="tickbox" /> +
+
+ +
+
+
+ <% } // isAdvanced %>> + <% if ("httpclient".equals(tunnelType) || "connectclient".equals(tunnelType) || "sockstunnel".equals(tunnelType) || "socksirctunnel".equals(tunnelType)) { %>
diff --git a/apps/i2ptunnel/jsp/editServer.jsp b/apps/i2ptunnel/jsp/editServer.jsp index a6c8e7413..978afd63a 100644 --- a/apps/i2ptunnel/jsp/editServer.jsp +++ b/apps/i2ptunnel/jsp/editServer.jsp @@ -491,6 +491,7 @@ input.default { width: 1px; height: 1px; visibility: hidden; }
+<% /***************** %>
+<% **********************/ %> + + <% if (editBean.isAdvanced()) { %> +
+ +
+
+
+ + class="tickbox" /> +
+
+ + class="tickbox" /> +
+
+ + class="tickbox" /> +
+
+ + class="tickbox" /> +
+

+ <% } // isAdvanced %>>