Changes in / [090a790:855cae0]


Ignore:
Files:
17 added
32 edited

Legend:

Unmodified
Added
Removed
  • .tx/config

    r090a790 r855cae0  
    243243trans.zh_CN = installer/resources/locale/po/messages_zh.po
    244244
     245[I2P.getopt]
     246source_file = core/java/src/gnu/getopt/MessagesBundle.properties
     247source_lang = en
     248type = PROPERTIES
     249trans.cs = core/java/src/gnu/getopt/MessagesBundle_cs.properties
     250trans.de = core/java/src/gnu/getopt/MessagesBundle_de.properties
     251trans.es = core/java/src/gnu/getopt/MessagesBundle_es.properties
     252trans.fr = core/java/src/gnu/getopt/MessagesBundle_fr.properties
     253trans.hu = core/java/src/gnu/getopt/MessagesBundle_hu.properties
     254trans.it = core/java/src/gnu/getopt/MessagesBundle_it.properties
     255trans.ja = core/java/src/gnu/getopt/MessagesBundle_ha.properties
     256trans.nl = core/java/src/gnu/getopt/MessagesBundle_nl.properties
     257trans.nb = core/java/src/gnu/getopt/MessagesBundle_nb.properties
     258trans.pl = core/java/src/gnu/getopt/MessagesBundle_pl.properties
     259trans.ro = core/java/src/gnu/getopt/MessagesBundle_ro.properties
     260trans.zh_CN = core/java/src/gnu/getopt/MessagesBundle_zh.properties
     261
    245262[main]
    246263host = https://www.transifex.com
  • LICENSE.txt

    r090a790 r855cae0  
    7777   See licenses/LICENSE-Apache2.0.txt
    7878
     79   Getopt:
     80   Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
     81   See licenses/LICENSE-LGPLv2.1.txt
     82
     83
    7984Router (router.jar):
    8085Public domain except as listed below:
  • apps/i2psnark/java/src/org/klomp/snark/PeerID.java

    r090a790 r855cae0  
    5353  private final int hash;
    5454  private final I2PSnarkUtil util;
     55  private String _toStringCache;
    5556
    5657  public PeerID(byte[] id, Destination address)
     
    217218
    218219  /**
    219    * Returns the String "id@address" where id is the base64 encoded id
    220    * and address is the base64 dest (was the base64 hash of the dest) which
     220   * Returns the String "id@address" where id is the first 4 chars of the base64 encoded id
     221   * and address is the first 6 chars of the base64 dest (was the base64 hash of the dest) which
    221222   * should match what the bytemonsoon tracker reports on its web pages.
    222223   */
    223     @Override
     224  @Override
    224225  public String toString()
    225226  {
     227    if (_toStringCache != null)
     228        return _toStringCache;
    226229    if (id == null || address == null)
    227230        return "unkn@" + Base64.encode(destHash).substring(0, 6);
     
    233236        }
    234237    }
    235     return Base64.encode(id, nonZero, id.length-nonZero).substring(0,4) + "@" + address.toBase64().substring(0,6);
     238    _toStringCache = Base64.encode(id, nonZero, id.length-nonZero).substring(0,4) + "@" + address.toBase64().substring(0,6);
     239    return _toStringCache;
    236240  }
    237241
  • apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java

    r090a790 r855cae0  
    2525
    2626import net.i2p.I2PAppContext;
     27import net.i2p.app.ClientAppManager;
    2728import net.i2p.data.Base64;
    2829import net.i2p.data.DataHelper;
     
    199200            if (!_running)
    200201                return;
    201             _umgr = _context.updateManager();
     202            ClientAppManager cmgr = _context.clientAppManager();
     203            if (cmgr != null)
     204                _umgr = (UpdateManager) cmgr.getRegisteredApp(UpdateManager.APP_NAME);
    202205            if (_umgr != null) {
    203206                _uhandler = new UpdateHandler(_context, _umgr, SnarkManager.this);
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java

    r090a790 r855cae0  
    5454import java.util.concurrent.atomic.AtomicLong;
    5555
     56import gnu.getopt.Getopt;
     57import gnu.getopt.LongOpt;
     58
    5659import net.i2p.I2PAppContext;
    5760import net.i2p.I2PException;
     
    108111    private final Set<ConnectionEventListener> listeners = new CopyOnWriteArraySet<ConnectionEventListener>();
    109112
    110     public static void main(String[] args) throws IOException {
    111         new I2PTunnel(args);
    112     }
    113 
     113    private static final int NOGUI = 99999;
     114    private static final LongOpt[] longopts = new LongOpt[] {
     115        new LongOpt("cli", LongOpt.NO_ARGUMENT, null, 'c'),
     116        new LongOpt("die", LongOpt.NO_ARGUMENT, null, 'd'),
     117        new LongOpt("gui", LongOpt.NO_ARGUMENT, null, 'g'),
     118        new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'),
     119        new LongOpt("nocli", LongOpt.NO_ARGUMENT, null, 'w'),
     120        new LongOpt("nogui", LongOpt.NO_ARGUMENT, null, NOGUI),
     121        new LongOpt("wait", LongOpt.NO_ARGUMENT, null, 'w')
     122    };
     123
     124    public static void main(String[] args) {
     125        try {
     126            new I2PTunnel(args);
     127        } catch (IllegalArgumentException iae) {
     128            System.err.println(iae.toString());
     129            System.exit(1);
     130        }
     131    }
     132
     133    /**
     134     *  Standard constructor for embedded, uses args "-nocli -die" to return immediately
     135     */
    114136    public I2PTunnel() {
    115137        this(nocli_args);
    116138    }
    117139
     140    /**
     141     *  See usage() for options
     142     *  @throws IllegalArgumentException
     143     */
    118144    public I2PTunnel(String[] args) {
    119145        this(args, null);
    120146    }
    121147
     148    /**
     149     *  See usage() for options
     150     *  @param lsnr may be null
     151     *  @throws IllegalArgumentException
     152     */
    122153    public I2PTunnel(String[] args, ConnectionEventListener lsnr) {
    123154        super();
     
    135166        boolean cli = true;
    136167        boolean dontDie = true;
    137         for (int i = 0; i < args.length; i++) {
    138             if (args[i].equals("-die")) {
     168        boolean error = false;
     169        List<String> eargs = null;
     170        Getopt g = new Getopt("i2ptunnel", args, "d::n:c::w::e:h::", longopts);
     171        int c;
     172        while ((c = g.getopt()) != -1) {
     173          switch (c) {
     174            case 'd':  // -d, -die, --die
    139175                dontDie = false;
    140176                gui = false;
    141177                cli = false;
    142178                checkRunByE = false;
    143             } else if (args[i].equals("-nogui")) {
     179                break;
     180
     181            case 'n':  // -noc, -nog, -nocli, -nogui
     182                String a = g.getOptarg();
     183                if (a.startsWith("oc")) {
     184                    gui = false;
     185                    cli = false;
     186                    checkRunByE = false;
     187                    break;
     188                } else if (a.startsWith("og")) {
     189                    // fall thru
     190                } else {
     191                    error = true;
     192                    break;
     193                }
     194                // fall thru for -nogui only
     195
     196            case NOGUI:  // --nogui
    144197                gui = false;
    145                 _log.warn(getPrefix() + "The `-nogui' option of I2PTunnel is deprecated.\n"
     198                if (_log.shouldLog(Log.WARN))
     199                    _log.warn(getPrefix() + "The `-nogui' option of I2PTunnel is deprecated.\n"
    146200                          + "Use `-cli', `-nocli' (aka `-wait') or `-die' instead.");
    147             } else if (args[i].equals("-cli")) {
     201
     202            case 'c':  // -c, -cli, --cli
    148203                gui = false;
    149204                cli = true;
    150205                checkRunByE = false;
    151             } else if (args[i].equals("-nocli") || args[i].equals("-wait")) {
     206                break;
     207
     208            case 'w':  // -w, -wait, --nocli
    152209                gui = false;
    153210                cli = false;
    154211                checkRunByE = false;
    155             } else if (args[i].equals("-e")) {
    156                 runCommand(args[i + 1], this);
    157                 i++;
     212                break;
     213
     214            case 'e':
     215                if (eargs == null)
     216                    eargs = new ArrayList<String>(4);
     217                eargs.add(g.getOptarg());
    158218                if (checkRunByE) {
    159219                    checkRunByE = false;
    160220                    cli = false;
    161221                }
    162             } else if (new File(args[i]).exists()) {
    163                 runCommand("run " + args[i], this);
    164             } else {
    165                 System.out.println("Unknown parameter " + args[i]);
    166             }
    167         }
     222                break;
     223
     224            case 'h':
     225            case '?':
     226            case ':':
     227            default:
     228              error = true;
     229          }
     230        }
     231
     232        int remaining = args.length - g.getOptind();
     233
     234        if (error || remaining > 1) {
     235            System.err.println(usage());
     236            throw new IllegalArgumentException();
     237        }
     238
     239        if (eargs != null) {
     240            for (String arg : eargs) {
     241                runCommand(arg, this);
     242            }
     243        }
     244
     245        if (remaining == 1) {
     246            String f = args[g.getOptind()];
     247            File file = new File(f);
     248            // This is probably just a problem with the options, so
     249            // throw from here
     250            if (!file.exists()) {
     251                System.err.println(usage());
     252                throw new IllegalArgumentException("Command file does not exist: " + f);
     253            }
     254            runCommand("run " + f, this);
     255        }
     256
    168257        if (gui) {
    169258            new I2PTunnelGUI(this);
     
    186275                ex.printStackTrace();
    187276            }
     277        } else if (eargs == null && remaining == 0 && dontDie) {
     278            System.err.println(usage());
     279            throw new IllegalArgumentException("Waiting for nothing! Specify gui, cli, command, command file, or die");
    188280        }
    189281
     
    196288            }
    197289        }
     290    }
     291
     292    /** with newlines except for last line */
     293    private static String usage() {
     294        // not sure this all makes sense, just documenting what's above
     295        return
     296            "Usage: i2ptunnel [options] [commandFile]\n" +
     297            "  Default is to run the GUI.\n" +
     298            "  commandFile: run all commands in this file\n" +
     299            "  Options:\n" +
     300            "    -c, -cli, --cli     :  run the command line interface\n" +
     301            "    -d, -die, --die     :  exit immediately, do not wait for commands to finish\n" +
     302            "    -e 'command [args]' :  run the command\n" +
     303            "    -h, --help          :  display this help\n" +
     304            "    -nocli, --nocli     :  do not run the command line interface or GUI\n" +
     305            "    -nogui, --nogui     :  do not run the GUI\n" +
     306            "    -w, -wait, --wait   :  do not run the command line interface or GUI";
    198307    }
    199308
     
    313422     */
    314423    private static void runHelp(Logging l) {
    315         l.log("Command list:");
     424        l.log("Command list:\n" +
    316425        // alphabetical please...
    317         l.log("  auth <username> <password>");
    318         l.log("  client <port> <pubkey>[,<pubkey,...]|file:<pubkeyfile> [<sharedClient>]");
    319         l.log("  clientoptions [-acx] [key=value ]*");
    320         l.log("  close [forced] <jobnumber>|all");
    321         l.log("  config [-s] <i2phost> <i2pport>");
    322         l.log("  connectclient <port> [<sharedClient>] [<proxy>]");
    323         l.log("  genkeys <privkeyfile> [<pubkeyfile>]");
    324         l.log("  gentextkeys");
    325         l.log("  httpbidirserver <host> <port> <proxyport> <spoofedhost> <privkeyfile>");
    326         l.log("  httpclient <port> [<sharedClient>] [<proxy>]");
    327         l.log("  httpserver <host> <port> <spoofedhost> <privkeyfile>");
    328         l.log("  ircclient <port> <pubkey>[,<pubkey,...]|file:<pubkeyfile> [<sharedClient>]");
    329         l.log("  list");
    330         l.log("  listen_on <ip>");
    331         l.log("  lookup <name>");
    332         l.log("  owndest yes|no");
    333         l.log("  ping <args>");
    334         l.log("  quit");
    335         l.log("  read_timeout <msecs>");
    336         l.log("  run <commandfile>");
    337         l.log("  server <host> <port> <privkeyfile>");
    338         l.log("  textserver <host> <port> <privkey>");
     426              "  auth <username> <password>\n" +
     427              "  client <port> <pubkey>[,<pubkey,...]|file:<pubkeyfile> [<sharedClient>]\n" +
     428              "  clientoptions [-acx] [key=value ]*\n" +
     429              "  close [forced] <jobnumber>|all\n" +
     430              "  config [-s] <i2phost> <i2pport>\n" +
     431              "  connectclient <port> [<sharedClient>] [<proxy>]\n" +
     432              "  genkeys <privkeyfile> [<pubkeyfile>]\n" +
     433              "  gentextkeys\n" +
     434              "  httpbidirserver <host> <port> <proxyport> <spoofedhost> <privkeyfile>\n" +
     435              "  httpclient <port> [<sharedClient>] [<proxy>]\n" +
     436              "  httpserver <host> <port> <spoofedhost> <privkeyfile>\n" +
     437              "  ircclient <port> <pubkey>[,<pubkey,...]|file:<pubkeyfile> [<sharedClient>]\n" +
     438              "  list\n" +
     439              "  listen_on <ip>\n" +
     440              "  lookup <name>\n" +
     441              "  owndest yes|no\n" +
     442              "  ping <args>\n" +
     443              "  quit\n" +
     444              "  read_timeout <msecs>\n" +
     445              "  run <commandfile>\n" +
     446              "  server <host> <port> <privkeyfile>\n" +
     447              "  textserver <host> <port> <privkey>\n");
    339448    }
    340449   
     
    379488            }
    380489        } else {
    381             l.log("Usage:");
    382             l.log("  clientoptions [key=value ]*     // sets current options");
    383             l.log("  clientoptions -a [key=value ]*  // adds to current options");
    384             l.log("  clientoptions -c                // clears current options");
    385             l.log("  clientoptions -x [key ]*        // removes listed options");
    386             l.log("Current options:");
     490            l.log("Usage:\n" +
     491                  "  clientoptions [key=value ]*     // sets current options\n" +
     492                  "  clientoptions -a [key=value ]*  // adds to current options\n" +
     493                  "  clientoptions -c                // clears current options\n" +
     494                  "  clientoptions -x [key ]*        // removes listed options\n" +
     495                  "Current options:\n");
    387496            Properties p = new OrderedProperties();
    388497            p.putAll(_clientOptions);
     
    467576            return;
    468577        } else {
    469             l.log("server <host> <port> <privkeyfile>");
    470             l.log("  creates a server that sends all incoming data\n" + "  of its destination to host:port.");
     578            l.log("server <host> <port> <privkeyfile>\n" +
     579                  "  creates a server that sends all incoming data\n" + "  of its destination to host:port.");
    471580            notifyEvent("serverTaskId", Integer.valueOf(-1));
    472581        }
     
    518627            return;
    519628        } else {
    520             l.log("server <host> <port> <privkeyfile>");
    521             l.log("  creates a server that sends all incoming data\n" + "  of its destination to host:port.");
     629            l.log("server <host> <port> <privkeyfile>\n" +
     630                  "  creates a server that sends all incoming data\n" + "  of its destination to host:port.");
    522631            notifyEvent("serverTaskId", Integer.valueOf(-1));
    523632        }
     
    579688            return;
    580689        } else {
    581             l.log("httpserver <host> <port> <spoofedhost> <privkeyfile>");
    582             l.log("  creates an HTTP server that sends all incoming data\n"
     690            l.log("httpserver <host> <port> <spoofedhost> <privkeyfile>\n" +
     691                  "  creates an HTTP server that sends all incoming data\n"
    583692                  + "  of its destination to host:port., filtering the HTTP\n"
    584693                  + "  headers so it looks like the request is to the spoofed host.");
     
    655764            return;
    656765        } else {
    657             l.log("httpserver <host> <port> <proxyport> <spoofedhost> <privkeyfile>");
    658             l.log("  creates a bidirectional HTTP server that sends all incoming data\n"
     766            l.log("httpserver <host> <port> <proxyport> <spoofedhost> <privkeyfile>\n" +
     767                  "  creates a bidirectional HTTP server that sends all incoming data\n"
    659768                  + "  of its destination to host:port., filtering the HTTP\n"
    660769                  + "  headers so it looks like the request is to the spoofed host,"
     
    708817            notifyEvent("serverTaskId", Integer.valueOf(serv.getId()));
    709818        } else {
    710             l.log("textserver <host> <port> <privkey>");
    711             l.log("  creates a server that sends all incoming data\n" + "  of its destination to host:port.");
     819            l.log("textserver <host> <port> <privkey>\n" +
     820                  "  creates a server that sends all incoming data\n" + "  of its destination to host:port.");
    712821            notifyEvent("textserverTaskId", Integer.valueOf(-1));
    713822        }
     
    766875            }
    767876        } else {
    768             l.log("client <port> <pubkey>[,<pubkey>]|file:<pubkeyfile>[ <sharedClient>] [<privKeyFile>]");
    769             l.log("  creates a client that forwards port to the pubkey.\n"
     877            l.log("client <port> <pubkey>[,<pubkey>]|file:<pubkeyfile>[ <sharedClient>] [<privKeyFile>]\n" +
     878                  "  creates a client that forwards port to the pubkey.\n"
    770879                  + "  use 0 as port to get a free port assigned.  If you specify\n"
    771880                  + "  a comma delimited list of pubkeys, it will rotate among them\n"
     
    842951            }
    843952        } else {
    844             l.log("httpclient <port> [<sharedClient>] [<proxy>]");
    845             l.log("  creates a client that distributes HTTP requests.");
    846             l.log("  <sharedClient> (optional) indicates if this client shares tunnels with other clients (true of false)");
    847             l.log("  <proxy> (optional) indicates a proxy server to be used");
    848             l.log("  when trying to access an address out of the .i2p domain");
     953            l.log("httpclient <port> [<sharedClient>] [<proxy>]\n" +
     954                  "  creates a client that distributes HTTP requests.\n" +
     955                  "  <sharedClient> (optional) indicates if this client shares tunnels with other clients (true of false)\n" +
     956                  "  <proxy> (optional) indicates a proxy server to be used\n" +
     957                  "  when trying to access an address out of the .i2p domain");
    849958            notifyEvent("httpclientTaskId", Integer.valueOf(-1));
    850959        }
     
    9091018            }
    9101019        } else {
    911             l.log("connectclient <port> [<sharedClient>] [<proxy>]");
    912             l.log("  creates a client that for SSL/HTTPS requests.");
    913             l.log("  <sharedClient> (optional) indicates if this client shares tunnels with other clients (true of false)");
    914             l.log("  <proxy> (optional) indicates a proxy server to be used");
    915             l.log("  when trying to access an address out of the .i2p domain");
     1020            l.log("connectclient <port> [<sharedClient>] [<proxy>]\n" +
     1021                  "  creates a client that for SSL/HTTPS requests.\n" +
     1022                  "  <sharedClient> (optional) indicates if this client shares tunnels with other clients (true of false)\n" +
     1023                  "  <proxy> (optional) indicates a proxy server to be used\n" +
     1024                  "  when trying to access an address out of the .i2p domain\n");
    9161025        }
    9171026    }
     
    9761085            }
    9771086        } else {
    978             l.log("ircclient <port> [<sharedClient> [<privKeyFile>]]");
    979             l.log("  creates a client that filter IRC protocol.");
    980             l.log("  <sharedClient> (optional) indicates if this client shares tunnels with other clients (true of false)");
     1087            l.log("ircclient <port> [<sharedClient> [<privKeyFile>]]\n" +
     1088                  "  creates a client that filter IRC protocol.\n" +
     1089                  "  <sharedClient> (optional) indicates if this client shares tunnels with other clients (true of false)\n");
    9811090            notifyEvent("ircclientTaskId", Integer.valueOf(-1));
    9821091        }
     
    10291138            }
    10301139        } else {
    1031             l.log("sockstunnel <port>");
    1032             l.log("  creates a tunnel that distributes SOCKS requests.");
     1140            l.log("sockstunnel <port>\n" +
     1141                  "  creates a tunnel that distributes SOCKS requests.");
    10331142            notifyEvent("sockstunnelTaskId", Integer.valueOf(-1));
    10341143        }
     
    10761185            }
    10771186        } else {
    1078             l.log("socksirctunnel <port> [<sharedClient> [<privKeyFile>]]");
    1079             l.log("  creates a tunnel for SOCKS IRC.");
     1187            l.log("socksirctunnel <port> [<sharedClient> [<privKeyFile>]]\n" +
     1188                  "  creates a tunnel for SOCKS IRC.");
    10801189            notifyEvent("sockstunnelTaskId", Integer.valueOf(-1));
    10811190        }
     
    11261235            }
    11271236        } else {
    1128             l.log("streamrclient <host> <port> <destination>");
    1129             l.log("  creates a tunnel that receives streaming data.");
     1237            l.log("streamrclient <host> <port> <destination>\n" +
     1238                  "  creates a tunnel that receives streaming data.");
    11301239            notifyEvent("streamrtunnelTaskId", Integer.valueOf(-1));
    11311240        }
     
    11671276            notifyEvent("streamrtunnelTaskId", Integer.valueOf(task.getId()));
    11681277        } else {
    1169             l.log("streamrserver <port> <privkeyfile>");
    1170             l.log("  creates a tunnel that sends streaming data.");
     1278            l.log("streamrserver <port> <privkeyfile>\n" +
     1279                  "  creates a tunnel that sends streaming data.");
    11711280            notifyEvent("streamrtunnelTaskId", Integer.valueOf(-1));
    11721281        }
     
    11961305            notifyEvent("configResult", "ok");
    11971306        } else {
    1198             l.log("Usage:");
    1199             l.log("  config [-s] <i2phost> <i2pport>");
    1200             l.log("  sets the connection to the i2p router.");
    1201             l.log("Current setting:");
    12021307            boolean ssl = Boolean.parseBoolean(_clientOptions.getProperty("i2cp.SSL"));
    1203             l.log("  " + host + ' ' + port + (ssl ? " SSL" : ""));
     1308            l.log("Usage:\n" +
     1309                  "  config [-s] <i2phost> <i2pport>\n" +
     1310                  "  sets the connection to the i2p router.\n" +
     1311                  "Current setting:\n" +
     1312                  "  " + host + ' ' + port + (ssl ? " SSL" : ""));
    12041313            notifyEvent("configResult", "error");
    12051314        }
     
    12181327            _clientOptions.setProperty("i2cp.password", args[1]);
    12191328        } else {
    1220             l.log("Usage:");
    1221             l.log("  auth <username> <password>");
    1222             l.log("  Sets the i2cp credentials");
     1329            l.log("Usage:\n" +
     1330                  "  auth <username> <password>\n" +
     1331                  "  Sets the i2cp credentials");
    12231332        }
    12241333    }
     
    12381347            notifyEvent("owndestResult", "ok");
    12391348        } else {
    1240             l.log("owndest yes|no");
    1241             l.log("  Specifies whether to use its own destination \n" + "  for each outgoing tunnel");
     1349            l.log("owndest yes|no\n" +
     1350                  "  Specifies whether to use its own destination \n" + "  for each outgoing tunnel");
    12421351            notifyEvent("owndestResult", "error");
    12431352        }
     
    12571366            notifyEvent("listen_onResult", "ok");
    12581367        } else {
    1259             l.log("listen_on <ip>");
    1260             l.log("  sets the interface to listen for the I2PClient.");
     1368            l.log("listen_on <ip>\n" +
     1369                  "  sets the interface to listen for the I2PClient.");
    12611370            notifyEvent("listen_onResult", "error");
    12621371        }
     
    12801389            notifyEvent("read_timeoutResult", "ok");
    12811390        } else {
    1282             l.log("read_timeout <msecs>");
    1283             l.log("  sets the read timeout (in milliseconds) for I2P connections\n"
     1391            l.log("read_timeout <msecs>\n" +
     1392                  "  sets the read timeout (in milliseconds) for I2P connections\n"
    12841393                  +"  Negative values will make the connections wait forever");
    12851394            notifyEvent("read_timeoutResult", "error");
     
    13081417            }
    13091418        } else if (args.length != 1) {
    1310             l.log("genkeys <privkeyfile> [<pubkeyfile>]");
    1311             l.log("   creates a new keypair and prints the public key.\n"
     1419            l.log("genkeys <privkeyfile> [<pubkeyfile>]\n" +
     1420                  "   creates a new keypair and prints the public key.\n"
    13121421                  + "   if pubkeyfile is given, saves the public key there." + "\n"
    13131422                  + "   if the privkeyfile already exists, just print/save" + "the pubkey.");
     
    13951504    public void runClose(String args[], Logging l) {
    13961505        if (args.length == 0 || args.length > 2) {
    1397             l.log("close [forced] <jobnumber>|all");
    1398             l.log("   stop running tasks. either only one or all.\n"
     1506            l.log("close [forced] <jobnumber>|all\n" +
     1507                  "   stop running tasks. either only one or all.\n"
    13991508                  + "   use 'forced' to also stop tasks with active connections.\n"
    14001509                  + "   use the 'list' command to show the job numbers");
     
    14571566            }
    14581567        } else {
    1459             l.log("run <commandfile>");
    1460             l.log("   loads commandfile and runs each line in it. \n"
     1568            l.log("run <commandfile>\n" +
     1569                  "   loads commandfile and runs each line in it. \n"
    14611570                  + "   You can also give the filename on the commandline.");
    14621571            notifyEvent("runResult", "error");
     
    14751584    private void runLookup(String args[], Logging l) {
    14761585        if (args.length != 1) {
    1477             l.log("lookup <name>");
    1478             l.log("   try to resolve the name into a destination key");
     1586            l.log("lookup <name>\n" +
     1587                  "   try to resolve the name into a destination key");
    14791588            notifyEvent("lookupResult", "invalidUsage");
    14801589        } else {
     
    15141623            notifyEvent("pingTaskId", Integer.valueOf(task.getId()));
    15151624        } else {
    1516             l.log("ping <opts> <b64dest|host>");
    1517             l.log("ping <opts> -h (pings all hosts in hosts.txt)");
    1518             l.log("ping <opts> -l <destlistfile> (pings a list of hosts in a file)");
    1519             l.log("   Options:\n" +
    1520                   "     -c (require 5 consecutive pings to report success)\n" +
    1521                   "     -m maxSimultaneousPings (default 10)\n" +
    1522                   "     -n numberOfPings (default 3)\n" +
    1523                   "     -t timeout (ms, default 30000)\n");
    1524             l.log("   Tests communication with peers.\n");
     1625            l.log(I2Ping.usage());
    15251626            notifyEvent("pingTaskId", Integer.valueOf(-1));
    15261627        }
     
    16061707            I2PClient client = I2PClientFactory.createClient();
    16071708            Destination d = client.createDestination(writeTo);
    1608             l.log("Secret key saved.");
    1609             l.log("Public key: " + d.toBase64());
     1709            l.log("Secret key saved.\n" +
     1710                  "Public key: " + d.toBase64());
    16101711            writeTo.flush();
    16111712            writeTo.close();
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java

    r090a790 r855cae0  
    2525import net.i2p.data.Base64;
    2626import net.i2p.data.DataHelper;
     27import net.i2p.util.EepGet;
    2728import net.i2p.util.EventDispatcher;
    2829import net.i2p.util.InternalSocket;
     
    410411     */
    411412    private static Map<String, String> parseArgs(String args) {
    412         Map<String, String> rv = new HashMap<String, String>(8);
    413         char data[] = args.toCharArray();
    414         StringBuilder buf = new StringBuilder(32);
    415         boolean isQuoted = false;
    416         String key = null;
    417         for (int i = 0; i < data.length; i++) {
    418             switch (data[i]) {
    419                 case '\"':
    420                     if (isQuoted) {
    421                         // keys never quoted
    422                         if (key != null) {
    423                             rv.put(key, buf.toString().trim());
    424                             key = null;
    425                         }
    426                         buf.setLength(0);
    427                     }
    428                     isQuoted = !isQuoted;
    429                     break;
    430 
    431                 case ' ':
    432                 case '\r':
    433                 case '\n':
    434                 case '\t':
    435                 case ',':
    436                     // whitespace - if we're in a quoted section, keep this as part of the quote,
    437                     // otherwise use it as a delim
    438                     if (isQuoted) {
    439                         buf.append(data[i]);
    440                     } else {
    441                         if (key != null) {
    442                             rv.put(key, buf.toString().trim());
    443                             key = null;
    444                         }
    445                         buf.setLength(0);
    446                     }
    447                     break;
    448 
    449                 case '=':
    450                     if (isQuoted) {
    451                         buf.append(data[i]);
    452                     } else {
    453                         key = buf.toString().trim().toLowerCase(Locale.US);
    454                         buf.setLength(0);
    455                     }
    456                     break;
    457 
    458                 default:
    459                     buf.append(data[i]);
    460                     break;
    461             }
    462         }
    463         if (key != null)
    464             rv.put(key, buf.toString().trim());
    465         return rv;
     413        // moved to EepGet, since it needs this too
     414        return EepGet.parseAuthArgs(args);
    466415    }
    467416
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2Ping.java

    r090a790 r855cae0  
    1111import java.util.List;
    1212import java.util.Locale;
     13
     14import gnu.getopt.Getopt;
    1315
    1416import net.i2p.I2PAppContext;
     
    8789      boolean countPing = false;
    8890      boolean reportTimes = true;
    89       while (true) {
    90         if (cmd.startsWith("-t ")) { // timeout
    91             cmd = cmd.substring(3);
    92             int pos = cmd.indexOf(" ");
    93             if (pos == -1) {
    94                 l.log("Syntax error");
    95                 return;
    96             } else {
    97                 timeout = Long.parseLong(cmd.substring(0, pos));
     91      String hostListFile = null;
     92      int localPort = 0;
     93      int remotePort = 0;
     94      boolean error = false;
     95      String[] argv = cmd.split(" ");
     96      Getopt g = new Getopt("ping", argv, "t:m:n:chl:f:p:");
     97      int c;
     98      while ((c = g.getopt()) != -1) {
     99        switch (c) {
     100          case 't':  // timeout
     101            timeout = Long.parseLong(g.getOptarg());
    98102                // convenience, convert msec to sec
    99103                if (timeout < 100)
    100104                    timeout *= 1000;
    101                 cmd = cmd.substring(pos + 1);
    102             }
    103         } else if (cmd.startsWith("-m ")) { // max simultaneous pings
    104             cmd = cmd.substring(3);
    105             int pos = cmd.indexOf(" ");
    106             if (pos == -1) {
    107                 l.log("Syntax error");
    108                 return;
    109             } else {
    110                 MAX_SIMUL_PINGS = Integer.parseInt(cmd.substring(0, pos));
    111                 cmd = cmd.substring(pos + 1);
    112             }
    113         } else if (cmd.startsWith("-n ")) { // number of pings
    114             cmd = cmd.substring(3);
    115             int pos = cmd.indexOf(" ");
    116             if (pos == -1) {
    117                 l.log("Syntax error");
    118                 return;
    119             } else {
    120                 count = Integer.parseInt(cmd.substring(0, pos));
    121                 cmd = cmd.substring(pos + 1);
    122             }
    123         } else if (cmd.startsWith("-c ")) { // "count" ping
     105            break;
     106
     107          case 'm': // max simultaneous pings
     108            MAX_SIMUL_PINGS = Integer.parseInt(g.getOptarg());
     109            break;
     110
     111          case 'n': // number of pings
     112            count = Integer.parseInt(g.getOptarg());
     113            break;
     114
     115          case 'c': // "count" ping
    124116            countPing = true;
    125117            count = CPING_COUNT;
    126             cmd = cmd.substring(3);
    127         } else if (cmd.equals("-h")) { // ping all hosts
    128             cmd = "-l hosts.txt";
    129         } else if (cmd.startsWith("-l ")) { // ping a list of hosts
    130             BufferedReader br = new BufferedReader(new FileReader(cmd.substring(3)));
     118            break;
     119
     120          case 'h': // ping all hosts
     121            if (hostListFile != null)
     122                error = true;
     123            else
     124                hostListFile = "hosts.txt";
     125            break;
     126
     127          case 'l':  // ping a list of hosts
     128            if (hostListFile != null)
     129                error = true;
     130            else
     131                hostListFile = g.getOptarg();
     132            break;
     133
     134          case 'f': // local port
     135            localPort = Integer.parseInt(g.getOptarg());
     136            break;
     137
     138          case 'p': // remote port
     139            remotePort = Integer.parseInt(g.getOptarg());
     140            break;
     141
     142          case '?':
     143          case ':':
     144          default:
     145            error = true;
     146        }
     147      }
     148
     149      int remaining = argv.length - g.getOptind();
     150
     151      if (error ||
     152          remaining > 1 ||
     153          (remaining <= 0 && hostListFile == null) ||
     154          (remaining > 0 && hostListFile != null)) {
     155          System.out.println(usage());
     156          return;
     157      }
     158
     159      if (hostListFile != null) {
     160            BufferedReader br = new BufferedReader(new FileReader(hostListFile));
    131161            String line;
    132162            List<PingHandler> pingHandlers = new ArrayList<PingHandler>();
     
    139169                    line = line.substring(0, line.indexOf("="));
    140170                }
    141                 PingHandler ph = new PingHandler(line, count, timeout, countPing, reportTimes);
     171                PingHandler ph = new PingHandler(line, count, localPort, remotePort,
     172                                                 timeout, countPing, reportTimes);
    142173                ph.start();
    143174                pingHandlers.add(ph);
     
    149180                t.join();
    150181            return;
    151         } else {
    152             Thread t = new PingHandler(cmd, count, timeout, countPing, reportTimes);
    153             t.start();
    154             t.join();
    155             return;
    156         }
    157182      }
     183
     184      String host = argv[g.getOptind()];
     185      Thread t = new PingHandler(host, count, localPort, remotePort,
     186                                 timeout, countPing, reportTimes);
     187      t.start();
     188      t.join();
     189    }
     190
     191    /**
     192     *  With newlines except for last line
     193     *  @since 0.9.12
     194     */
     195    public static String usage() {
     196        return
     197            "ping <opts> <b64dest|host>\n" +
     198            "ping <opts> -h (pings all hosts in hosts.txt)\n" +
     199            "ping <opts> -l <destlistfile> (pings a list of hosts in a file)\n" +
     200            "Options:\n" +
     201            "     -c (require 5 consecutive pings to report success)\n" +
     202            "     -m maxSimultaneousPings (default 10)\n" +
     203            "     -n numberOfPings (default 3)\n" +
     204            "     -t timeout (ms, default 30000)\n" +
     205            "     -f fromPort\n" +
     206            "     -p toPort";
    158207    }
    159208
     
    171220    }
    172221
    173     private boolean ping(Destination dest, long timeout) throws I2PException {
     222    private boolean ping(Destination dest, int fromPort, int toPort, long timeout) throws I2PException {
    174223        try {
    175224            synchronized (simulLock) {
     
    184233                lastPingTime = System.currentTimeMillis();
    185234            }
    186             boolean sent = sockMgr.ping(dest, timeout);
     235            boolean sent = sockMgr.ping(dest, fromPort, toPort, timeout);
    187236            synchronized (simulLock) {
    188237                simulPings--;
     
    208257        private final boolean countPing;
    209258        private final boolean reportTimes;
     259        private final int localPort;
     260        private final int remotePort;
    210261
    211262        /**
     
    214265         *  @param dest b64 or b32 or host name
    215266         */
    216         public PingHandler(String dest, int count, long timeout, boolean countPings, boolean report) {
     267        public PingHandler(String dest, int count, int fromPort, int toPort,
     268                           long timeout, boolean countPings, boolean report) {
    217269            this.destination = dest;
    218270            cnt = count;
     271            localPort = fromPort;
     272            remotePort = toPort;
    219273            this.timeout = timeout;
    220274            countPing = countPings;
     
    236290                StringBuilder pingResults = new StringBuilder(2 * cnt + destination.length() + 3);
    237291                for (int i = 0; i < cnt; i++) {
    238                     boolean sent;
    239                     sent = ping(dest, timeout);
     292                    boolean sent = ping(dest, localPort, remotePort, timeout);
    240293                    if (countPing) {
    241294                        if (!sent) {
  • apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketManager.java

    r090a790 r855cae0  
    127127     * the timeout specified, false otherwise.  This call blocks.
    128128     *
     129     * Uses the ports from the default options.
     130     *
    129131     * @param peer Destination to ping
    130      * @param timeoutMs timeout in ms
     132     * @param timeoutMs timeout in ms, greater than zero
     133     * @throws IllegalArgumentException
    131134     * @return success or failure
    132135     */
    133136    public boolean ping(Destination peer, long timeoutMs);
     137
     138    /**
     139     * Ping the specified peer, returning true if they replied to the ping within
     140     * the timeout specified, false otherwise.  This call blocks.
     141     *
     142     * Uses the ports specified.
     143     *
     144     * @param peer Destination to ping
     145     * @param localPort 0 - 65535
     146     * @param remotePort 0 - 65535
     147     * @param timeoutMs timeout in ms, greater than zero
     148     * @return success or failure
     149     * @throws IllegalArgumentException
     150     * @since 0.9.12
     151     */
     152    public boolean ping(Destination peer, int localPort, int remotePort, long timeoutMs);
    134153
    135154    public String getName();
  • apps/routerconsole/java/src/net/i2p/router/update/ConsoleUpdateManager.java

    r090a790 r855cae0  
    1818
    1919import net.i2p.I2PAppContext;
     20import net.i2p.app.ClientAppManager;
     21import net.i2p.app.ClientAppState;
     22import static net.i2p.app.ClientAppState.*;
    2023import net.i2p.crypto.SU3File;
    2124import net.i2p.crypto.TrustedUpdate;
     
    2427import net.i2p.router.RouterContext;
    2528import net.i2p.router.RouterVersion;
     29import net.i2p.router.app.RouterApp;
    2630import net.i2p.router.web.ConfigServiceHandler;
    2731import net.i2p.router.web.ConfigUpdateHandler;
     
    5155 *  @since 0.9.4
    5256 */
    53 public class ConsoleUpdateManager implements UpdateManager {
     57public class ConsoleUpdateManager implements UpdateManager, RouterApp {
    5458   
    5559    private final RouterContext _context;
     
    6973    private final boolean _allowTorrent;
    7074    private static final DecimalFormat _pct = new DecimalFormat("0.0%");
     75    private final ClientAppManager _cmgr;
     76    private volatile ClientAppState _state = UNINITIALIZED;
    7177
    7278    private volatile String _status;
     
    7884    private static final String PROP_UNSIGNED_AVAILABLE = "router.updateUnsignedAvailable";
    7985
    80     public ConsoleUpdateManager(RouterContext ctx) {
     86    /**
     87     *  @param args ignored
     88     */
     89    public ConsoleUpdateManager(RouterContext ctx, ClientAppManager listener, String[] args) {
    8190        _context = ctx;
     91        _cmgr = listener;
    8292        _log = ctx.logManager().getLog(ConsoleUpdateManager.class);
    8393        _registeredUpdaters = new ConcurrentHashSet<RegisteredUpdater>();
     
    99109        // Finally, for 0.9.12, 18 months later...
    100110        _allowTorrent = true;
    101     }
    102 
     111        _state = INITIALIZED;
     112    }
     113
     114    /**
     115     *  @return null if not found
     116     */
    103117    public static ConsoleUpdateManager getInstance() {
    104         return (ConsoleUpdateManager) I2PAppContext.getGlobalContext().updateManager();
    105     }
    106 
     118        ClientAppManager cmgr = I2PAppContext.getGlobalContext().clientAppManager();
     119        if (cmgr == null)
     120            return null;
     121        return (ConsoleUpdateManager) cmgr.getRegisteredApp(APP_NAME);
     122    }
     123
     124    /////// ClientApp methods
     125
     126    /**
     127     *  UpdateManager interface
     128     */
    107129    public void start() {
     130        startup();
     131    }
     132
     133    /**
     134     *  ClientApp interface
     135     *  @since 0.9.12
     136     */
     137    public synchronized void startup() {
     138        changeState(STARTING);
    108139        notifyInstalled(NEWS, "", Long.toString(NewsHelper.lastUpdated(_context)));
    109140        notifyInstalled(ROUTER_SIGNED, "", RouterVersion.VERSION);
     
    119150        }
    120151
    121         _context.registerUpdateManager(this);
    122152        DummyHandler dh = new DummyHandler(_context, this);
    123153        register((Checker)dh, TYPE_DUMMY, METHOD_DUMMY, 0);
     
    163193        new NewsTimerTask(_context, this);
    164194        _context.simpleScheduler().addPeriodicEvent(new TaskCleaner(), TASK_CLEANER_TIME);
    165     }
    166 
     195        changeState(RUNNING);
     196        if (_cmgr != null)
     197            _cmgr.register(this);
     198    }
     199
     200    /**
     201     *  UpdateManager interface
     202     */
    167203    public void shutdown() {
    168         _context.unregisterUpdateManager(this);
     204        shutdown(null);
     205    }
     206
     207    /**
     208     *  ClientApp interface
     209     *  @param args ignored
     210     *  @since 0.9.12
     211     */
     212    public synchronized void shutdown(String[] args) {
     213        if (_state == STOPPED)
     214            return;
     215        changeState(STOPPING);
    169216        stopChecks();
    170217        stopUpdates();
     
    174221        _downloaded.clear();
    175222        _installed.clear();
     223        changeState(STOPPED);
     224    }
     225
     226    /** @since 0.9.12 */
     227    public ClientAppState getState() {
     228        return _state;
     229    }
     230
     231    /** @since 0.9.12 */
     232    public String getName() {
     233        return APP_NAME;
     234    }
     235
     236    /** @since 0.9.12 */
     237    public String getDisplayName() {
     238        return "Console Update Manager";
     239    }
     240
     241    /////// end ClientApp methods
     242
     243    private synchronized void changeState(ClientAppState state) {
     244        _state = state;
     245        if (_cmgr != null)
     246            _cmgr.notify(this, state, null, null);
    176247    }
    177248
  • apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java

    r090a790 r855cae0  
    371371     */
    372372    private void installPlugin(String app, String url) {
    373         ConsoleUpdateManager mgr = (ConsoleUpdateManager) _context.updateManager();
     373        ConsoleUpdateManager mgr = UpdateHandler.updateManager(_context);
    374374        if (mgr == null) {
    375375            addFormError("Update manager not registered, cannot install");
     
    398398
    399399    private void checkPlugin(String app) {
    400         ConsoleUpdateManager mgr = (ConsoleUpdateManager) _context.updateManager();
     400        ConsoleUpdateManager mgr = UpdateHandler.updateManager(_context);
    401401        if (mgr == null) {
    402402            addFormError("Update manager not registered, cannot check");
  • apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java

    r090a790 r855cae0  
    140140            return;
    141141        if (_action.equals(_("Check for updates"))) {
    142             ConsoleUpdateManager mgr = (ConsoleUpdateManager) _context.updateManager();
     142            ConsoleUpdateManager mgr = UpdateHandler.updateManager(_context);
    143143            if (mgr == null) {
    144144                addFormError("Update manager not registered, cannot check");
  • apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java

    r090a790 r855cae0  
    122122            return;
    123123
    124         ConsoleUpdateManager mgr = (ConsoleUpdateManager) ctx.updateManager();
     124        ConsoleUpdateManager mgr = UpdateHandler.updateManager(ctx);
    125125        if (mgr == null)
    126126            return;
  • apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java

    r090a790 r855cae0  
    646646        t.start();
    647647       
    648             ConsoleUpdateManager um = new ConsoleUpdateManager(_context);
     648            ConsoleUpdateManager um = new ConsoleUpdateManager(_context, _mgr, null);
    649649            um.start();
    650650       
  • apps/routerconsole/java/src/net/i2p/router/web/UpdateHandler.java

    r090a790 r855cae0  
    11package net.i2p.router.web;
    22
     3import net.i2p.app.ClientAppManager;
    34import net.i2p.router.RouterContext;
    45import net.i2p.router.update.ConsoleUpdateManager;
     6import net.i2p.update.UpdateManager;
    57import net.i2p.update.UpdateType;
    68import static net.i2p.update.UpdateType.*;
     
    3335        _context = ctx;
    3436        _log = ctx.logManager().getLog(UpdateHandler.class);
     37    }
     38
     39    /**
     40     *  @return null if not found
     41     *  @since 0.9.12
     42     */
     43    public static ConsoleUpdateManager updateManager(RouterContext ctx) {
     44        ClientAppManager cmgr = ctx.clientAppManager();
     45        if (cmgr == null)
     46            return null;
     47        return (ConsoleUpdateManager) cmgr.getRegisteredApp(UpdateManager.APP_NAME);
    3548    }
    3649   
     
    7689
    7790    private void update(UpdateType type) {
    78         ConsoleUpdateManager mgr = (ConsoleUpdateManager) _context.updateManager();
     91        ConsoleUpdateManager mgr = updateManager(_context);
    7992        if (mgr == null)
    8093            return;
  • apps/routerconsole/jsp/debug.jsp

    r090a790 r855cae0  
    3131     *  Print out the status for the UpdateManager
    3232     */
    33     ctx.updateManager().renderStatusHTML(out);
     33    net.i2p.app.ClientAppManager cmgr = ctx.clientAppManager();
     34    if (cmgr != null) {
     35        net.i2p.router.update.ConsoleUpdateManager umgr =
     36            (net.i2p.router.update.ConsoleUpdateManager) cmgr.getRegisteredApp(net.i2p.update.UpdateManager.APP_NAME);
     37        if (umgr != null) {
     38            umgr.renderStatusHTML(out);
     39        }
     40    }
    3441
    3542    /*
  • apps/streaming/java/src/net/i2p/client/streaming/impl/Connection.java

    r090a790 r855cae0  
    308308        reply.setReceiveStreamId(_receiveStreamId);
    309309        reply.setOptionalFrom(_connectionManager.getSession().getMyDestination());
     310        reply.setLocalPort(_localPort);
     311        reply.setRemotePort(_remotePort);
    310312        // this just sends the packet - no retries or whatnot
    311313        if (_outboundQueue.enqueue(reply)) {
  • apps/streaming/java/src/net/i2p/client/streaming/impl/ConnectionDataReceiver.java

    r090a790 r855cae0  
    207207            packet.setOptionalFrom(con.getSession().getMyDestination());
    208208            packet.setOptionalMaxSize(con.getOptions().getMaxMessageSize());
    209             packet.setLocalPort(con.getLocalPort());
    210             packet.setRemotePort(con.getPort());
    211         }
     209        }
     210        packet.setLocalPort(con.getLocalPort());
     211        packet.setRemotePort(con.getPort());
    212212        if (con.getSendStreamId() == Packet.STREAM_ID_UNKNOWN) {
    213213            packet.setFlag(Packet.FLAG_NO_ACK);
  • apps/streaming/java/src/net/i2p/client/streaming/impl/ConnectionManager.java

    r090a790 r855cae0  
    263263            reply.setReceiveStreamId(0);
    264264            reply.setOptionalFrom(_session.getMyDestination());
     265            reply.setLocalPort(synPacket.getLocalPort());
     266            reply.setRemotePort(synPacket.getRemotePort());
    265267            // this just sends the packet - no retries or whatnot
    266268            _outboundQueue.enqueue(reply);
     
    283285        _context.statManager().addRateData("stream.connectionReceived", 1, 0);
    284286        return con;
     287    }
     288   
     289    /**
     290     *  Process a ping by checking for throttling, etc., then sending a pong.
     291     *
     292     *  @param con null if unknown
     293     *  @param ping Ping packet to process, must have From and Sig fields,
     294     *              with signature already verified, only if answerPings() returned true
     295     *  @return true if we sent a pong
     296     *  @since 0.9.12 from PacketHandler.receivePing()
     297     */
     298    public boolean receivePing(Connection con, Packet ping) {
     299        Destination dest = ping.getOptionalFrom();
     300        if (dest == null)
     301            return false;
     302        if (con == null) {
     303            // Use the same throttling as for connections
     304            String why = shouldRejectConnection(ping);
     305            if (why != null) {
     306                if ((!_defaultOptions.getDisableRejectLogging()) || _log.shouldLog(Log.WARN))
     307                    _log.logAlways(Log.WARN, "Dropping ping since peer is " + why + ": " + dest.calculateHash());
     308                return false;
     309            }
     310        } else {
     311            // in-connection ping to a 3rd party ???
     312            if (!dest.equals(con.getRemotePeer())) {
     313                _log.logAlways(Log.WARN, "Dropping ping from " + con.getRemotePeer().calculateHash() +
     314                                         " to " + dest.calculateHash());
     315                return false;
     316            }
     317        }
     318        PacketLocal pong = new PacketLocal(_context, dest);
     319        pong.setFlag(Packet.FLAG_ECHO | Packet.FLAG_NO_ACK);
     320        pong.setReceiveStreamId(ping.getSendStreamId());
     321        pong.setLocalPort(ping.getLocalPort());
     322        pong.setRemotePort(ping.getRemotePort());
     323        _outboundQueue.enqueue(pong);
     324        return true;
    285325    }
    286326   
     
    573613    }
    574614
    575     /** blocking */
    576     public boolean ping(Destination peer, long timeoutMs) {
    577         return ping(peer, timeoutMs, true, null);
    578     }
    579     public boolean ping(Destination peer, long timeoutMs, boolean blocking) {
    580         return ping(peer, timeoutMs, blocking, null);
    581     }
    582 
    583     /**
    584      * @deprecated I2PSession ignores tags, use non-tag variant
    585      * @param keyToUse ignored
    586      * @param tagsToSend ignored
    587      */
    588     public boolean ping(Destination peer, long timeoutMs, boolean blocking, SessionKey keyToUse, Set<?> tagsToSend, PingNotifier notifier) {
    589         return ping(peer, timeoutMs, blocking, notifier);
    590     }
    591 
    592     public boolean ping(Destination peer, long timeoutMs, boolean blocking, PingNotifier notifier) {
     615    /**
     616     *  blocking
     617     *
     618     *  @param timeoutMs greater than zero
     619     *  @return true if pong received
     620     *  @since 0.9.12 added port args
     621     */
     622    public boolean ping(Destination peer, int fromPort, int toPort, long timeoutMs) {
     623        return ping(peer, fromPort, toPort, timeoutMs, true, null);
     624    }
     625
     626    /**
     627     *  @param timeoutMs greater than zero
     628     *  @return true if blocking and pong received
     629     *  @since 0.9.12 added port args
     630     */
     631    public boolean ping(Destination peer, int fromPort, int toPort, long timeoutMs, boolean blocking) {
     632        return ping(peer, fromPort, toPort, timeoutMs, blocking, null);
     633    }
     634
     635    /**
     636     *  @param timeoutMs greater than zero
     637     *  @param notifier may be null
     638     *  @return true if blocking and pong received
     639     *  @since 0.9.12 added port args
     640     */
     641    public boolean ping(Destination peer, int fromPort, int toPort, long timeoutMs,
     642                        boolean blocking, PingNotifier notifier) {
    593643        Long id = Long.valueOf(_context.random().nextLong(Packet.MAX_STREAM_ID-1)+1);
    594644        PacketLocal packet = new PacketLocal(_context, peer);
     
    598648                       Packet.FLAG_SIGNATURE_INCLUDED);
    599649        packet.setOptionalFrom(_session.getMyDestination());
     650        packet.setLocalPort(fromPort);
     651        packet.setRemotePort(toPort);
    600652        //if ( (keyToUse != null) && (tagsToSend != null) ) {
    601653        //    packet.setKeyUsed(keyToUse);
     
    603655        //}
    604656        if (_log.shouldLog(Log.INFO)) {
    605             _log.info(String.format("about to ping %s timeout=%d blocking=%b",
    606                     peer,timeoutMs,blocking));
     657            _log.info(String.format("about to ping %s port %d from port %d timeout=%d blocking=%b",
     658                      peer.calculateHash().toString(), toPort, fromPort, timeoutMs, blocking));
    607659        }
    608660           
     
    659711        private final PingNotifier _notifier;
    660712
     713        /** @param notifier may be null */
    661714        public PingRequest(PingNotifier notifier) {
    662715            _notifier = notifier;
  • apps/streaming/java/src/net/i2p/client/streaming/impl/I2PSocketManagerFull.java

    r090a790 r855cae0  
    149149     * the timeout specified, false otherwise.  This call blocks.
    150150     *
     151     * Uses the ports from the default options.
    151152     *
    152153     * @param peer
    153      * @param timeoutMs
     154     * @param timeoutMs timeout in ms, greater than zero
    154155     * @return true on success, false on failure
     156     * @throws IllegalArgumentException
    155157     */
    156158    public boolean ping(Destination peer, long timeoutMs) {
    157         return _connectionManager.ping(peer, timeoutMs);
     159        if (timeoutMs <= 0)
     160            throw new IllegalArgumentException("bad timeout");
     161        return _connectionManager.ping(peer, _defaultOptions.getLocalPort(),
     162                                       _defaultOptions.getPort(), timeoutMs);
     163    }
     164
     165    /**
     166     * Ping the specified peer, returning true if they replied to the ping within
     167     * the timeout specified, false otherwise.  This call blocks.
     168     *
     169     * Uses the ports specified.
     170     *
     171     * @param peer Destination to ping
     172     * @param localPort 0 - 65535
     173     * @param remotePort 0 - 65535
     174     * @param timeoutMs timeout in ms, greater than zero
     175     * @return success or failure
     176     * @throws IllegalArgumentException
     177     * @since 0.9.12
     178     */
     179    public boolean ping(Destination peer, int localPort, int remotePort, long timeoutMs) {
     180        if (localPort < 0 || localPort > 65535 ||
     181            remotePort < 0 || remotePort > 65535)
     182            throw new IllegalArgumentException("bad port");
     183        if (timeoutMs <= 0)
     184            throw new IllegalArgumentException("bad timeout");
     185        return _connectionManager.ping(peer, localPort, remotePort, timeoutMs);
    158186    }
    159187
  • apps/streaming/java/src/net/i2p/client/streaming/impl/PacketHandler.java

    r090a790 r855cae0  
    137137            if (packet.getSendStreamId() > 0) {
    138138                if (con.getOptions().getAnswerPings())
    139                     receivePing(packet);
     139                    receivePing(con, packet);
    140140                else if (_log.shouldLog(Log.WARN))
    141141                    _log.warn("Dropping Echo packet on existing con: " + packet);
     
    248248        reply.setReceiveStreamId(packet.getSendStreamId());
    249249        reply.setOptionalFrom(_manager.getSession().getMyDestination());
     250        reply.setLocalPort(packet.getLocalPort());
     251        reply.setRemotePort(packet.getRemotePort());
    250252        // this just sends the packet - no retries or whatnot
    251253        _manager.getPacketQueue().enqueue(reply);
     
    256258            if (packet.getSendStreamId() > 0) {
    257259                if (_manager.answerPings())
    258                     receivePing(packet);
     260                    receivePing(null, packet);
    259261                else if (_log.shouldLog(Log.WARN))
    260262                    _log.warn("Dropping Echo packet on unknown con: " + packet);
     
    336338    }
    337339   
    338     private void receivePing(Packet packet) {
     340    /**
     341     *  @param con null if unknown
     342     */
     343    private void receivePing(Connection con, Packet packet) {
    339344        boolean ok = packet.verifySignature(_context, packet.getOptionalFrom(), null);
    340345        if (!ok) {
     
    349354            }
    350355        } else {
    351             PacketLocal pong = new PacketLocal(_context, packet.getOptionalFrom());
    352             pong.setFlag(Packet.FLAG_ECHO | Packet.FLAG_NO_ACK);
    353             pong.setReceiveStreamId(packet.getSendStreamId());
    354             _manager.getPacketQueue().enqueue(pong);
     356            _manager.receivePing(con, packet);
    355357        }
    356358    }
  • build.xml

    r090a790 r855cae0  
    449449    </target>
    450450
    451     <target name="prep-script-translation" >
     451    <condition property="no.bundle">
     452        <isfalse value="${require.gettext}" />
     453    </condition>
     454
     455    <target name="prep-script-translation" unless="no.bundle" >
    452456        <!-- script translation added in 0.8.13, enabled in 0.9.5. -->
    453457        <ant dir="installer/resources/locale" target="bundle" />
     
    468472            doctitle="I2P Javadocs for Release ${release.number} Build ${i2p.build.number}${build.extra}"
    469473            windowtitle="I2P Anonymous Network - Java Documentation - Version ${release.number}">
    470             <group title="Core SDK (i2p.jar)" packages="net.i2p:net.i2p.*:net.i2p.client:net.i2p.client.*:net.i2p.internal:net.i2p.internal.*:freenet.support.CPUInformation:org.bouncycastle.oldcrypto:org.bouncycastle.oldcrypto.*:gnu.crypto.*:gnu.gettext:com.nettgryppa.security:net.metanotion:net.metanotion.*" />
     474            <group title="Core SDK (i2p.jar)" packages="net.i2p:net.i2p.*:net.i2p.client:net.i2p.client.*:net.i2p.internal:net.i2p.internal.*:freenet.support.CPUInformation:org.bouncycastle.oldcrypto:org.bouncycastle.oldcrypto.*:gnu.crypto.*:gnu.getopt:gnu.gettext:com.nettgryppa.security:net.metanotion:net.metanotion.*" />
    471475            <group title="Streaming Library" packages="net.i2p.client.streaming:net.i2p.client.streaming.impl" />
    472476            <group title="Router" packages="net.i2p.router:net.i2p.router.*:net.i2p.data.i2np:org.cybergarage.*:org.freenetproject:org.xlattice.crypto.filters" />
  • core/java/build.xml

    r090a790 r855cae0  
    4747        <!-- set if unset -->
    4848        <property name="workspace.changes.tr" value="" />
    49         <jar destfile="./build/i2p.jar" basedir="./build/obj" includes="**/*.class" >
     49        <jar destfile="./build/i2p.jar" >
     50            <fileset dir="./build/obj" includes="**/*.class" />
     51            <!-- the getopt translation files -->
     52            <fileset dir="src" includes="gnu/getopt/*.properties" />
    5053            <manifest>
    5154                <attribute name="Implementation-Version" value="${full.version}" />
  • core/java/src/net/i2p/I2PAppContext.java

    r090a790 r855cae0  
    10191019
    10201020    /**
    1021      *  The controller of router, plugin, and other updates.
    1022      *  @return always null in I2PAppContext, the update manager if in RouterContext and it is registered
    1023      *  @since 0.9.4
    1024      */
    1025     public UpdateManager updateManager() {
    1026         return null;
    1027     }
    1028 
    1029     /**
    10301021     *  The RouterAppManager in RouterContext, null always in I2PAppContext
    10311022     *  @return null always
  • core/java/src/net/i2p/crypto/SU3File.java

    r090a790 r855cae0  
    2626import java.util.NoSuchElementException;
    2727import java.util.Properties;
     28
     29import gnu.getopt.Getopt;
    2830
    2931import net.i2p.I2PAppContext;
     
    438440    public static void main(String[] args) {
    439441        boolean ok = false;
    440         List<String> a = new ArrayList<String>(Arrays.asList(args));
    441442        try {
    442443            // defaults
    443444            String stype = null;
    444445            String ctype = null;
    445             Iterator<String> iter = a.iterator();
    446             String cmd = iter.next();
    447             iter.remove();
    448             for ( ; iter.hasNext(); ) {
    449                 String arg = iter.next();
    450                 if (arg.equals("-t")) {
    451                     iter.remove();
    452                     stype = iter.next();
    453                     iter.remove();
    454                 } else if (arg.equals("-c")) {
    455                     iter.remove();
    456                     ctype = iter.next();
    457                     iter.remove();
    458                 }
    459             }
    460             if ("showversion".equals(cmd)) {
     446            boolean error = false;
     447            Getopt g = new Getopt("SU3File", args, "t:c:");
     448            int c;
     449            while ((c = g.getopt()) != -1) {
     450              switch (c) {
     451                case 't':
     452                    stype = g.getOptarg();
     453                    break;
     454
     455                case 'c':
     456                    ctype = g.getOptarg();
     457                    break;
     458
     459                case '?':
     460                case ':':
     461                default:
     462                  error = true;
     463              }
     464            }
     465
     466            int idx = g.getOptind();
     467            String cmd = args[idx];
     468            List<String> a = new ArrayList<String>(Arrays.asList(args).subList(idx + 1, args.length));
     469
     470            if (error) {
     471                showUsageCLI();
     472            } else if ("showversion".equals(cmd)) {
    461473                ok = showVersionCLI(a.get(0));
    462474            } else if ("sign".equals(cmd)) {
  • core/java/src/net/i2p/data/PrivateKeyFile.java

    r090a790 r855cae0  
    1212import com.nettgryppa.security.HashCash;
    1313
     14import gnu.getopt.Getopt;
     15
    1416import net.i2p.I2PException;
    1517import net.i2p.client.I2PClient;
     
    1820import net.i2p.client.I2PSessionException;
    1921import net.i2p.crypto.DSAEngine;
     22import net.i2p.crypto.SigType;
    2023
    2124/**
     
    5154     */
    5255    public static void main(String args[]) {
    53         if (args.length == 0) {
    54             System.err.println("Usage: PrivateKeyFile filename (generates if nonexistent, then prints)");
    55             System.err.println("       PrivateKeyFile -h filename (generates if nonexistent, adds hashcash cert)");
    56             System.err.println("       PrivateKeyFile -h effort filename (specify HashCash effort instead of default " + HASH_EFFORT + ")");
    57             System.err.println("       PrivateKeyFile -n filename (changes to null cert)");
    58             System.err.println("       PrivateKeyFile -s filename signwithdestfile (generates if nonexistent, adds cert signed by 2nd dest)");
    59             System.err.println("       PrivateKeyFile -u filename (changes to unknown cert)");
    60             System.err.println("       PrivateKeyFile -x filename (changes to hidden cert)");
    61             return;
    62         }
     56        int hashEffort = HASH_EFFORT;
     57        String stype = null;
     58        int mode = 0;
     59        boolean error = false;
     60        Getopt g = new Getopt("pkf", args, "t:nuxhse:");
     61        int c;
     62        while ((c = g.getopt()) != -1) {
     63          switch (c) {
     64            case 't':
     65                stype = g.getOptarg();
     66                // fall thru...
     67
     68            case 'n':
     69            case 'u':
     70            case 'x':
     71            case 'h':
     72            case 's':
     73                if (mode == 0)
     74                    mode = c;
     75                else
     76                    error = true;
     77                break;
     78
     79            case 'e':
     80                hashEffort = Integer.parseInt(g.getOptarg());
     81                break;
     82
     83            case '?':
     84            case ':':
     85            default:
     86                error = true;
     87                break;
     88          }  // switch
     89        } // while
     90
     91        int remaining = args.length - g.getOptind();
     92        int reqd = mode == 's' ? 2 : 1;
     93        if (error || remaining != reqd) {
     94            usage();
     95            System.exit(1);
     96        }
     97        String filearg = args[g.getOptind()];
     98
    6399        I2PClient client = I2PClientFactory.createClient();
    64100
    65         int filearg = 0;
    66         if (args.length > 1) {
    67             if (args.length >= 2 && args[0].equals("-h"))
    68                 filearg = args.length - 1;
    69             else
    70                 filearg = 1;
    71         }
    72101        try {
    73             File f = new File(args[filearg]);
     102            File f = new File(filearg);
    74103            PrivateKeyFile pkf = new PrivateKeyFile(f, client);
    75104            Destination d = pkf.createIfAbsent();
     
    77106            System.out.println(pkf);
    78107            verifySignature(d);
    79             if (args.length == 1)
    80                 return;
    81             if (args[0].equals("-n")) {
     108            switch (mode) {
     109              case 0:
     110                // we are done
     111                break;
     112
     113              case 'n':
    82114                // Cert constructor generates a null cert
    83115                pkf.setCertType(Certificate.CERTIFICATE_TYPE_NULL);
    84116                System.out.println("New destination with null cert is:");
    85             } else if (args[0].equals("-u")) {
     117                break;
     118
     119              case 'u':
    86120                pkf.setCertType(99);
    87121                System.out.println("New destination with unknown cert is:");
    88             } else if (args[0].equals("-x")) {
     122                break;
     123
     124              case 'x':
    89125                pkf.setCertType(Certificate.CERTIFICATE_TYPE_HIDDEN);
    90126                System.out.println("New destination with hidden cert is:");
    91             } else if (args[0].equals("-h")) {
    92                 int hashEffort = HASH_EFFORT;
    93                 if (args.length == 3)
    94                     hashEffort = Integer.parseInt(args[1]);
     127                break;
     128
     129              case 'h':
    95130                System.out.println("Estimating hashcash generation time, stand by...");
    96131                System.out.println(estimateHashCashTime(hashEffort));
    97132                pkf.setHashCashCert(hashEffort);
    98133                System.out.println("New destination with hashcash cert is:");
    99             } else if (args.length == 3 && args[0].equals("-s")) {
     134                break;
     135
     136              case 's':
    100137                // Sign dest1 with dest2's Signing Private Key
    101                 PrivateKeyFile pkf2 = new PrivateKeyFile(args[2]);
     138                PrivateKeyFile pkf2 = new PrivateKeyFile(args[g.getOptind() + 1]);
    102139                pkf.setSignedCert(pkf2);
    103140                System.out.println("New destination with signed cert is:");
     141                break;
     142
     143              case 't':
     144                // TODO merge with ecdsa branch
     145                throw new UnsupportedOperationException();
     146
     147              default:
     148                // shouldn't happen
     149                usage();
     150                return;
    104151            }
    105152            System.out.println(pkf);
     
    108155        } catch (Exception e) {
    109156            e.printStackTrace();
    110         }
     157            System.exit(1);
     158        }
     159    }
     160
     161    private static void usage() {
     162        System.err.println("Usage: PrivateKeyFile filename (generates if nonexistent, then prints)\n" +
     163                           "       PrivateKeyFile -h filename (generates if nonexistent, adds hashcash cert)\n" +
     164                           "       PrivateKeyFile -h -e effort filename (specify HashCash effort instead of default " + HASH_EFFORT + ")\n" +
     165                           "       PrivateKeyFile -n filename (changes to null cert)\n" +
     166                           "       PrivateKeyFile -s filename signwithdestfile (generates if nonexistent, adds cert signed by 2nd dest)\n" +
     167                           "       PrivateKeyFile -t sigtype filename (changes to KeyCertificate of the given sig type\n" +
     168                           "       PrivateKeyFile -u filename (changes to unknown cert)\n" +
     169                           "       PrivateKeyFile -x filename (changes to hidden cert)\n");
    111170    }
    112171   
  • core/java/src/net/i2p/update/UpdateManager.java

    r090a790 r855cae0  
    1919public interface UpdateManager {
    2020   
     21    /**
     22     *  The name we register with the ClientAppManager
     23     *  @since 0.9.12
     24     */
     25    public static final String APP_NAME = "update";
     26
    2127    /**
    2228     *  Call once for each type/method pair.
  • core/java/src/net/i2p/util/EepGet.java

    r090a790 r855cae0  
    22
    33import java.io.BufferedInputStream;
     4import java.io.BufferedReader;
    45import java.io.File;
    56import java.io.FileOutputStream;
    67import java.io.IOException;
    78import java.io.InputStream;
     9import java.io.InputStreamReader;
    810import java.io.PipedInputStream;
    911import java.io.PipedOutputStream;
     
    1214import java.net.MalformedURLException;
    1315import java.net.Socket;
     16import java.net.UnknownHostException;
    1417import java.net.URL;
    1518import java.text.DecimalFormat;
     
    1720import java.util.Date;
    1821import java.util.Formatter;
     22import java.util.HashMap;
    1923import java.util.List;
    2024import java.util.Locale;
     25import java.util.Map;
     26
     27import gnu.getopt.Getopt;
    2128
    2229import net.i2p.I2PAppContext;
     30import net.i2p.data.Base32;
    2331import net.i2p.data.Base64;
    2432import net.i2p.data.ByteArray;
     
    8391    protected IOException _decompressException;
    8492
     93    // following for proxy digest auth
     94    // only created via addAuthorization()
     95    protected AuthState _authState;
     96
    8597    /** this will be replaced by the HTTP Proxy if we are using it */
    8698    protected static final String USER_AGENT = "Wget/1.11.4";
     
    164176        String etag = null;
    165177        String saveAs = null;
    166         String url = null;
    167178        List<String> extra = null;
    168179        String username = null;
    169180        String password = null;
     181        boolean error = false;
     182        //
     183        // note: if you add options, please update installer/resources/man/eepget.1
     184        //
     185        Getopt g = new Getopt("eepget", args, "p:cn:t:e:o:m:l:h:u:x:");
    170186        try {
    171             for (int i = 0; i < args.length; i++) {
    172                 if (args[i].equals("-p")) {
    173                     proxyHost = args[++i].substring(0, args[i].indexOf(':'));
    174                     String port = args[i].substring(args[i].indexOf(':')+1);
    175                     proxyPort = Integer.parseInt(port);
    176                 } else if (args[i].equals("-n")) {
    177                     numRetries = Integer.parseInt(args[i+1]);
    178                     i++;
    179                 } else if (args[i].equals("-t")) {
    180                     inactivityTimeout = 1000 * Integer.parseInt(args[i+1]);
    181                     i++;
    182                 } else if (args[i].equals("-e")) {
    183                     etag = "\"" + args[i+1] + "\"";
    184                     i++;
    185                 } else if (args[i].equals("-o")) {
    186                     saveAs = args[i+1];
    187                     i++;
    188                 } else if (args[i].equals("-m")) {
    189                     markSize = Integer.parseInt(args[++i]);
    190                     lineLen = Integer.parseInt(args[++i]);
    191                 } else if (args[i].equals("-h")) {
    192                     if (extra == null)
    193                         extra = new ArrayList<String>(2);
    194                     extra.add(args[++i]);
    195                     extra.add(args[++i]);
    196                 } else if (args[i].equals("-u")) {
    197                     username = args[++i];
    198                     password = args[++i];
    199                 } else if (args[i].startsWith("-")) {
    200                     usage();
    201                     return;
    202                 } else {
    203                     url = args[i];
    204                 }
    205             }
     187            int c;
     188            while ((c = g.getopt()) != -1) {
     189              switch (c) {
     190                case 'p':
     191                    String s = g.getOptarg();
     192                    int colon = s.indexOf(':');
     193                    if (colon >= 0) {
     194                        // Todo IPv6 [a:b:c]:4444
     195                        proxyHost = s.substring(0, colon);
     196                        String port = s.substring(colon + 1);
     197                        proxyPort = Integer.parseInt(port);
     198                    } else {
     199                        proxyHost = s;
     200                        // proxyPort remains default
     201                    }
     202                    break;
     203
     204                case 'c':
     205                    // no proxy, same as -p :0
     206                    proxyHost = "";
     207                    proxyPort = 0;
     208                    break;
     209
     210                case 'n':
     211                    numRetries = Integer.parseInt(g.getOptarg());
     212                    break;
     213
     214                case 't':
     215                    inactivityTimeout = 1000 * Integer.parseInt(g.getOptarg());
     216                    break;
     217
     218                case 'e':
     219                    etag = "\"" + g.getOptarg() + "\"";
     220                    break;
     221
     222                case 'o':
     223                    saveAs = g.getOptarg();
     224                    break;
     225
     226                case 'm':
     227                    markSize = Integer.parseInt(g.getOptarg());
     228                    break;
     229
     230                case 'l':
     231                    lineLen = Integer.parseInt(g.getOptarg());
     232                    break;
     233
     234                case 'h':
     235                    String a = g.getOptarg();
     236                    int eq = a.indexOf('=');
     237                    if (eq > 0) {
     238                        if (extra == null)
     239                            extra = new ArrayList<String>(2);
     240                        String key = a.substring(0, eq);
     241                        String val = a.substring(eq + 1);
     242                        extra.add(key);
     243                        extra.add(val);
     244                    } else {
     245                        error = true;
     246                    }
     247                    break;
     248
     249                case 'u':
     250                    username = g.getOptarg();
     251                    break;
     252
     253                case 'x':
     254                    password = g.getOptarg();
     255                    break;
     256
     257                case '?':
     258                case ':':
     259                default:
     260                    error = true;
     261                    break;
     262              }  // switch
     263            } // while
    206264        } catch (Exception e) {
    207265            e.printStackTrace();
     266            error = true;
     267        }
     268
     269        if (error || args.length - g.getOptind() != 1) {
    208270            usage();
    209             return;
    210         }
    211 
    212         if (url == null) {
    213             usage();
    214             return;
    215         }
     271            System.exit(1);
     272        }
     273        String url = args[g.getOptind()];
     274
    216275        if (saveAs == null)
    217276            saveAs = suggestName(url);
     
    223282            }
    224283        }
    225         if (username != null && password != null)
     284        if (username != null) {
     285            if (password == null) {
     286                try {
     287                    BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
     288                    do {
     289                        System.err.print("Proxy password: ");
     290                        password = r.readLine();
     291                        if (password == null)
     292                            throw new IOException();
     293                        password = password.trim();
     294                    } while (password.length() <= 0);
     295                } catch (IOException ioe) {
     296                    System.exit(1);
     297                }
     298            }
    226299            get.addAuthorization(username, password);
     300        }
    227301        get.addStatusListener(get.new CLIStatusListener(markSize, lineLen));
    228302        if (!get.fetch(CONNECT_TIMEOUT, -1, inactivityTimeout))
     
    279353
    280354    private static void usage() {
    281         System.err.println("EepGet [-p 127.0.0.1:4444] [-n #retries] [-o outputFile]\n" +
    282                            "       [-m markSize lineLen] [-t timeout] [-h headerKey headerValue]\n" +
    283                            "       [-u username password] url]\n" +
    284                            "       (use -p :0 for no proxy)");
     355        System.err.println("eepget [-p 127.0.0.1[:4444]] [-c] [-o outputFile]\n" +
     356                           "       [-n #retries] (default 5)\n" +
     357                           "       [-m markSize] (default 1024)\n" +
     358                           "       [-l lineLen]  (default 40)\n" +
     359                           "       [-t timeout]  (default 60 sec)\n" +
     360                           "       [-e etag]\n" +
     361                           "       [-h headerName=headerValue]\n" +
     362                           "       [-u username] [-x password] url\n" +
     363                           "       (use -c or -p :0 for no proxy)");
    285364    }
    286365   
     
    533612                    _log.warn("ERR: doFetch failed ", ioe);
    534613                if (ioe instanceof MalformedURLException ||
     614                    ioe instanceof UnknownHostException ||
    535615                    ioe instanceof ConnectException) // proxy or nonproxied host Connection Refused
    536616                    _keepFetching = false;
     
    593673       
    594674        if (_redirectLocation != null) {
     675            // we also are here after a 407
    595676            //try {
    596677                if (_redirectLocation.startsWith("http://")) {
     
    611692            //    throw new IOException("Redirected from an invalid URL");
    612693            //}
    613             _redirects++;
    614             if (_redirects > 5)
    615                 throw new IOException("Too many redirects: to " + _redirectLocation);
    616             if (_log.shouldLog(Log.INFO)) _log.info("Redirecting to " + _redirectLocation);
     694
     695            AuthState as = _authState;
     696            if (_responseCode == 407) {
     697                if (!_shouldProxy)
     698                    throw new IOException("Proxy auth response from non-proxy");
     699                if (as == null)
     700                    throw new IOException("Proxy requires authentication");
     701                if (as.authSent)
     702                    throw new IOException("Proxy authentication failed");  // ignore stale
     703                if (_log.shouldLog(Log.INFO)) _log.info("Adding auth");
     704                // actually happens in getRequest()
     705            } else {
     706                _redirects++;
     707                if (_redirects > 5)
     708                    throw new IOException("Too many redirects: to " + _redirectLocation);
     709                if (_log.shouldLog(Log.INFO)) _log.info("Redirecting to " + _redirectLocation);
     710                if (as != null)
     711                    as.authSent = false;
     712            }
    617713
    618714            // reset some important variables, we don't want to save the values from the redirect
     
    802898                _notModified = true;
    803899                return;
     900            case 401: // server auth
    804901            case 403: // bad req
    805902            case 404: // not found
     
    819916                        _out = new FileOutputStream(_outputFile, true);
    820917                }
     918                break;
     919            case 407: // proxy auth
     920                // we will treat this is a redirect if we haven't sent auth yet
     921                //_redirectLocation will be set to _actualURL below
     922                _alreadyTransferred = 0;
     923                if (_authState != null)
     924                    rcOk = !_authState.authSent;
     925                else
     926                    rcOk = false;
     927                redirect = rcOk;
     928                _keepFetching = rcOk;
    821929                break;
    822930            case 416: // completed (or range out of reach)
     
    9011009                    if (isEndOfHeaders(lookahead)) {
    9021010                        if (!rcOk)
    903                             throw new IOException("Invalid HTTP response code: " + _responseCode);
     1011                            throw new IOException("Invalid HTTP response code: " + _responseCode + ' ' + _responseText);
    9041012                        if (_encodingChunked) {
    9051013                            _bytesRemaining = readChunkLength();
    9061014                        }
    907                         if (!redirect) _redirectLocation = null;
     1015                        if (!redirect)
     1016                            _redirectLocation = null;
     1017                        else if (_responseCode == 407)
     1018                            _redirectLocation = _actualURL;
    9081019                        return;
    9091020                    }
     
    10121123        } else if (key.equals("location")) {
    10131124            _redirectLocation=val;
     1125        } else if (key.equals("proxy-authenticate") && _responseCode == 407 && _authState != null && _shouldProxy) {
     1126            _authState.setAuthChallenge(val);
    10141127        } else {
    10151128            // ignore the rest
     
    10621175                if ("http".equals(url.getProtocol())) {
    10631176                    String host = url.getHost();
    1064                     if (host.toLowerCase(Locale.US).endsWith(".i2p"))
    1065                         throw new MalformedURLException("I2P addresses must be proxied");
     1177                    String hostlc = host.toLowerCase(Locale.US);
     1178                    if (hostlc.endsWith(".i2p"))
     1179                        throw new UnknownHostException("I2P addresses must be proxied");
     1180                    if (hostlc.endsWith(".onion"))
     1181                        throw new UnknownHostException("Tor addresses must be proxied");
    10661182                    int port = url.getPort();
    10671183                    if (port == -1)
     
    11201236        }
    11211237        if (post) {
    1122             buf.append("POST ").append(urlToSend).append(" HTTP/1.1\r\n");
     1238            buf.append("POST ");
    11231239        } else {
    1124             buf.append("GET ").append(urlToSend).append(" HTTP/1.1\r\n");
    1125         }
     1240            buf.append("GET ");
     1241        }
     1242        buf.append(urlToSend).append(" HTTP/1.1\r\n");
    11261243        // RFC 2616 sec 5.1.2 - host + port (NOT authority, which includes userinfo)
    11271244        buf.append("Host: ").append(host);
     
    11681285        if(!uaOverridden)
    11691286            buf.append("User-Agent: " + USER_AGENT + "\r\n");
     1287        if (_authState != null && _shouldProxy && _authState.authMode != AUTH_MODE.NONE) {
     1288            buf.append("Proxy-Authorization: ");
     1289            String method = post ? "POST" : "GET";
     1290            buf.append(_authState.getAuthHeader(method, urlToSend));
     1291            buf.append("\r\n");
     1292        }
    11701293        buf.append("Connection: close\r\n\r\n");
    11711294        if (post)
     
    12581381     *  Only added if the request is going through a proxy.
    12591382     *  Must be called before fetch().
    1260      *  Not supported by EepHead.
    12611383     *
    12621384     *  @since 0.8.9
    12631385     */
    12641386    public void addAuthorization(String userName, String password) {
    1265         if (_shouldProxy)
    1266             addHeader("Proxy-Authorization",
    1267                       "Basic " + Base64.encode(DataHelper.getUTF8(userName + ':' + password), true));  // true = use standard alphabet
     1387        if (_shouldProxy) {
     1388            // Could only do this for Basic
     1389            // Now we always wait for the 407, in the hope we can use Digest
     1390            //addHeader("Proxy-Authorization",
     1391            //          "Basic " + Base64.encode(DataHelper.getUTF8(userName + ':' + password), true));  // true = use standard alphabet
     1392            if (_authState != null)
     1393                throw new IllegalStateException();
     1394            _authState = new AuthState(userName, password);
     1395        }
     1396    }
     1397
     1398    /**
     1399     *  Parse the args in an authentication header.
     1400     *
     1401     *  Modified from LoadClientAppsJob.
     1402     *  All keys are mapped to lower case.
     1403     *  Double quotes around values are stripped.
     1404     *  Ref: RFC 2617
     1405     *
     1406     *  Public for I2PTunnelHTTPClientBase; use outside of tree at own risk, subject to change or removal
     1407     *
     1408     *  @param args non-null, starting after "Digest " or "Basic "
     1409     *  @since 0.9.4, moved from I2PTunnelHTTPClientBase in 0.9.12
     1410     */
     1411    public static Map<String, String> parseAuthArgs(String args) {
     1412        Map<String, String> rv = new HashMap<String, String>(8);
     1413        char data[] = args.toCharArray();
     1414        StringBuilder buf = new StringBuilder(32);
     1415        boolean isQuoted = false;
     1416        String key = null;
     1417        for (int i = 0; i < data.length; i++) {
     1418            switch (data[i]) {
     1419                case '\"':
     1420                    if (isQuoted) {
     1421                        // keys never quoted
     1422                        if (key != null) {
     1423                            rv.put(key, buf.toString().trim());
     1424                            key = null;
     1425                        }
     1426                        buf.setLength(0);
     1427                    }
     1428                    isQuoted = !isQuoted;
     1429                    break;
     1430
     1431                case ' ':
     1432                case '\r':
     1433                case '\n':
     1434                case '\t':
     1435                case ',':
     1436                    // whitespace - if we're in a quoted section, keep this as part of the quote,
     1437                    // otherwise use it as a delim
     1438                    if (isQuoted) {
     1439                        buf.append(data[i]);
     1440                    } else {
     1441                        if (key != null) {
     1442                            rv.put(key, buf.toString().trim());
     1443                            key = null;
     1444                        }
     1445                        buf.setLength(0);
     1446                    }
     1447                    break;
     1448
     1449                case '=':
     1450                    if (isQuoted) {
     1451                        buf.append(data[i]);
     1452                    } else {
     1453                        key = buf.toString().trim().toLowerCase(Locale.US);
     1454                        buf.setLength(0);
     1455                    }
     1456                    break;
     1457
     1458                default:
     1459                    buf.append(data[i]);
     1460                    break;
     1461            }
     1462        }
     1463        if (key != null)
     1464            rv.put(key, buf.toString().trim());
     1465        return rv;
     1466    }
     1467
     1468
     1469    /**
     1470     *  @since 0.9.12
     1471     */
     1472    protected enum AUTH_MODE {NONE, BASIC, DIGEST, UNKNOWN}
     1473
     1474    /**
     1475     *  Manage the authentication parameters
     1476     *  Ref: RFC 2617
     1477     *  Supports both Basic and Digest, however i2ptunnel HTTP proxy
     1478     *  has migrated all previous Basic support to Digest.
     1479     *
     1480     *  @since 0.9.12
     1481     */
     1482    protected class AuthState {
     1483        private final String username;
     1484        private final String password;
     1485        // as recvd in 407
     1486        public AUTH_MODE authMode = AUTH_MODE.NONE;
     1487        // as recvd in 407, after the mode string
     1488        private String authChallenge;
     1489        public boolean authSent;
     1490        private int nonceCount;
     1491        private String cnonce;
     1492        // as parsed from authChallenge
     1493        private Map<String, String> args;
     1494
     1495        public AuthState(String user, String pw) {
     1496            username = user;
     1497            password = pw;
     1498        }
     1499
     1500        /**
     1501         *  May be called multiple times, save the best one
     1502         */
     1503        public void setAuthChallenge(String auth) {
     1504            String authLC = auth.toLowerCase(Locale.US);
     1505            if (authLC.startsWith("basic ")) {
     1506                // better than anything but DIGEST
     1507                if (authMode != AUTH_MODE.DIGEST) {
     1508                    // use standard alphabet
     1509                    authMode = AUTH_MODE.BASIC;
     1510                    authChallenge = auth.substring(6);
     1511                }
     1512            } else if (authLC.startsWith("digest ")) {
     1513                // better than anything
     1514                authMode = AUTH_MODE.DIGEST;
     1515                authChallenge = auth.substring(7);
     1516            } else {
     1517                // better than NONE only
     1518                if (authMode == AUTH_MODE.NONE) {
     1519                    authMode = AUTH_MODE.UNKNOWN;
     1520                    authChallenge = null;
     1521                }
     1522            }
     1523            nonceCount = 0;
     1524            args = null;
     1525        }
     1526
     1527        public String getAuthHeader(String method, String uri) throws IOException {
     1528            switch (authMode) {
     1529                case BASIC:
     1530                    authSent = true;
     1531                    // use standard alphabet
     1532                    return "Basic " +
     1533                           Base64.encode(DataHelper.getUTF8(username + ':' + password), true);
     1534
     1535                case DIGEST:
     1536                    if (authChallenge == null)
     1537                        throw new IOException("Bad proxy auth response");
     1538                    if (args == null)
     1539                        args = parseAuthArgs(authChallenge);
     1540                    Map<String, String> outArgs = generateAuthArgs(method, uri);
     1541                    if (outArgs == null)
     1542                        throw new IOException("Bad proxy auth response");
     1543                    StringBuilder buf = new StringBuilder(256);
     1544                    buf.append("Digest");
     1545                    for (Map.Entry<String, String> e : outArgs.entrySet()) {
     1546                        buf.append(' ').append(e.getKey()).append('=').append(e.getValue());
     1547                    }
     1548                    authSent = true;
     1549                    return buf.toString();
     1550
     1551                default:
     1552                    throw new IOException("Unknown proxy auth type " + authChallenge);
     1553            }
     1554        }
     1555
     1556        /**
     1557         *  Generate the digest authentication parameters
     1558         *  Ref: RFC 2617
     1559         *
     1560         *  @since 0.9.12 modified from I2PTunnelHTTPClientBase.validateDigest()
     1561         */
     1562        public Map<String, String> generateAuthArgs(String method, String uri) throws IOException {
     1563            Map<String, String> rv = new HashMap<String, String>(12);
     1564            String realm = args.get("realm");
     1565            String nonce = args.get("nonce");
     1566            String qop = args.get("qop");
     1567            String opaque = args.get("opaque");
     1568            //String algorithm = args.get("algorithm");
     1569            //String stale = args.get("stale");
     1570            if (realm == null || nonce == null) {
     1571                if (_log.shouldLog(Log.INFO))
     1572                    _log.info("Bad digest request: " + DataHelper.toString(args));
     1573                throw new IOException("Bad auth response");
     1574            }
     1575            rv.put("username", '"' + username + '"');
     1576            rv.put("realm", '"' + realm + '"');
     1577            rv.put("nonce", '"' + nonce + '"');
     1578            rv.put("uri", '"' + uri + '"');
     1579            if (opaque != null)
     1580                rv.put("opaque", '"' + opaque + '"');
     1581            String kdMiddle;
     1582            if ("auth".equals(qop)) {
     1583                rv.put("qop", "\"auth\"");
     1584                if (cnonce == null) {
     1585                    byte[] rand = new byte[5];
     1586                    _context.random().nextBytes(rand);
     1587                    cnonce = Base32.encode(rand);
     1588                }  // else reuse on redirect
     1589                rv.put("cnonce", '"' + cnonce + '"');
     1590                String nc = lc8hex(++nonceCount);
     1591                rv.put("nc", nc);
     1592                kdMiddle = ':' + nc + ':' + cnonce + ':' + qop;
     1593            } else {
     1594                kdMiddle = "";
     1595            }
     1596
     1597            // get H(A1)
     1598            String ha1 = PasswordManager.md5Hex(username + ':' + realm + ':' + password);
     1599            // get H(A2)
     1600            String a2 = method + ':' + uri;
     1601            String ha2 = PasswordManager.md5Hex(a2);
     1602            // response
     1603            String kd = ha1 + ':' + nonce + kdMiddle + ':' + ha2;
     1604            rv.put("response", '"' + PasswordManager.md5Hex(kd) + '"');
     1605            return rv;
     1606        }
     1607    }
     1608
     1609    /**
     1610     *  @return 8 hex chars, lower case, e.g. 00000001
     1611     *  @since 0.8.10
     1612     */
     1613    private static String lc8hex(int nc) {
     1614        StringBuilder buf = new StringBuilder(8);
     1615        for (int i = 28; i >= 0; i -= 4) {
     1616            int v = (nc >> i) & 0xf;
     1617            if (v < 10)
     1618                buf.append((char) (v + '0'));
     1619            else
     1620                buf.append((char) (v + 'a' - 10));
     1621        }
     1622        return buf.toString();
    12681623    }
    12691624
  • core/java/src/net/i2p/util/EepHead.java

    r090a790 r855cae0  
    11package net.i2p.util;
    22
     3import java.io.BufferedInputStream;
     4import java.io.BufferedReader;
    35import java.io.ByteArrayOutputStream;
    46import java.io.IOException;
     7import java.io.InputStreamReader;
    58import java.io.OutputStream;
    69import java.net.URL;
     10
     11import gnu.getopt.Getopt;
    712
    813import net.i2p.I2PAppContext;
     
    5257        int numRetries = 0;
    5358        int inactivityTimeout = 60*1000;
    54         String url = null;
     59        String username = null;
     60        String password = null;
     61        boolean error = false;
     62        Getopt g = new Getopt("eephead", args, "p:cn:t:u:x:");
    5563        try {
    56             for (int i = 0; i < args.length; i++) {
    57                 if (args[i].equals("-p")) {
    58                     proxyHost = args[i+1].substring(0, args[i+1].indexOf(':'));
    59                     String port = args[i+1].substring(args[i+1].indexOf(':')+1);
    60                     proxyPort = Integer.parseInt(port);
    61                     i++;
    62                 } else if (args[i].equals("-n")) {
    63                     numRetries = Integer.parseInt(args[i+1]);
    64                     i++;
    65                 } else if (args[i].equals("-t")) {
    66                     inactivityTimeout = 1000 * Integer.parseInt(args[i+1]);
    67                     i++;
    68                 } else if (args[i].startsWith("-")) {
    69                     usage();
    70                     return;
    71                 } else {
    72                     url = args[i];
     64            int c;
     65            while ((c = g.getopt()) != -1) {
     66              switch (c) {
     67                case 'p':
     68                    String s = g.getOptarg();
     69                    int colon = s.indexOf(':');
     70                    if (colon >= 0) {
     71                        // Todo IPv6 [a:b:c]:4444
     72                        proxyHost = s.substring(0, colon);
     73                        String port = s.substring(colon + 1);
     74                        proxyPort = Integer.parseInt(port);
     75                    } else {
     76                        proxyHost = s;
     77                        // proxyPort remains default
     78                    }
     79                    break;
     80
     81                case 'c':
     82                    // no proxy, same as -p :0
     83                    proxyHost = "";
     84                    proxyPort = 0;
     85                    break;
     86
     87                case 'n':
     88                    numRetries = Integer.parseInt(g.getOptarg());
     89                    break;
     90
     91                case 't':
     92                    inactivityTimeout = 1000 * Integer.parseInt(g.getOptarg());
     93                    break;
     94
     95                case 'u':
     96                    username = g.getOptarg();
     97                    break;
     98
     99                case 'x':
     100                    password = g.getOptarg();
     101                    break;
     102
     103                case '?':
     104                case ':':
     105                default:
     106                    error = true;
     107                    break;
     108              }  // switch
     109            } // while
     110        } catch (Exception e) {
     111            e.printStackTrace();
     112            error = true;
     113        }
     114
     115        if (error || args.length - g.getOptind() != 1) {
     116            usage();
     117            System.exit(1);
     118        }
     119        String url = args[g.getOptind()];
     120       
     121        EepHead get = new EepHead(I2PAppContext.getGlobalContext(), proxyHost, proxyPort, numRetries, url);
     122        if (username != null) {
     123            if (password == null) {
     124                try {
     125                    BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
     126                    do {
     127                        System.err.print("Proxy password: ");
     128                        password = r.readLine();
     129                        if (password == null)
     130                            throw new IOException();
     131                        password = password.trim();
     132                    } while (password.length() <= 0);
     133                } catch (IOException ioe) {
     134                    System.exit(1);
    73135                }
    74136            }
    75         } catch (Exception e) {
    76             e.printStackTrace();
    77             usage();
    78             return;
    79         }
    80        
    81         if (url == null) {
    82             usage();
    83             return;
    84         }
    85 
    86         EepHead get = new EepHead(I2PAppContext.getGlobalContext(), proxyHost, proxyPort, numRetries, url);
     137            get.addAuthorization(username, password);
     138        }
    87139        if (get.fetch(45*1000, -1, inactivityTimeout)) {
    88140            System.err.println("Content-Type: " + get.getContentType());
     
    97149   
    98150    private static void usage() {
    99         System.err.println("EepHead [-p 127.0.0.1:4444] [-n #retries] [-t timeout] url");
     151        System.err.println("EepHead [-p 127.0.0.1[:4444]] [-c]\n" +
     152                           "        [-n #retries] (default 0)\n" +
     153                           "        [-t timeout]  (default 60 sec)\n" +
     154                           "        [-u username] [-x password] url\n" +
     155                           "        (use -c or -p :0 for no proxy)");
    100156    }
    101157   
     
    139195            //    throw new IOException("Redirected from an invalid URL");
    140196            //}
    141             _redirects++;
    142             if (_redirects > 5)
    143                 throw new IOException("Too many redirects: to " + _redirectLocation);
    144             if (_log.shouldLog(Log.INFO)) _log.info("Redirecting to " + _redirectLocation);
     197            AuthState as = _authState;
     198            if (_responseCode == 407) {
     199                if (!_shouldProxy)
     200                    throw new IOException("Proxy auth response from non-proxy");
     201                if (as == null)
     202                    throw new IOException("Proxy requires authentication");
     203                if (as.authSent)
     204                    throw new IOException("Proxy authentication failed");  // ignore stale
     205                if (_log.shouldLog(Log.INFO)) _log.info("Adding auth");
     206                // actually happens in getRequest()
     207            } else {
     208                _redirects++;
     209                if (_redirects > 5)
     210                    throw new IOException("Too many redirects: to " + _redirectLocation);
     211                if (_log.shouldLog(Log.INFO)) _log.info("Redirecting to " + _redirectLocation);
     212                if (as != null)
     213                    as.authSent = false;
     214            }
    145215
    146216            // reset some important variables, we don't want to save the values from the redirect
     
    213283        // This will be replaced if we are going through I2PTunnelHTTPClient
    214284        buf.append("User-Agent: " + USER_AGENT + "\r\n");
     285        if (_authState != null && _shouldProxy && _authState.authMode != AUTH_MODE.NONE) {
     286            buf.append("Proxy-Authorization: ");
     287            buf.append(_authState.getAuthHeader("HEAD", urlToSend));
     288            buf.append("\r\n");
     289        }
    215290        buf.append("Connection: close\r\n\r\n");
    216291        if (_log.shouldLog(Log.DEBUG))
  • core/java/src/net/i2p/util/PartialEepGet.java

    r090a790 r855cae0  
    11package net.i2p.util;
    22
     3import java.io.BufferedReader;
    34import java.io.FileOutputStream;
    45import java.io.IOException;
     6import java.io.InputStreamReader;
    57import java.io.OutputStream;
    68import java.net.MalformedURLException;
    79import java.net.URL;
    810import java.util.Locale;
     11
     12import gnu.getopt.Getopt;
    913
    1014import net.i2p.I2PAppContext;
     
    5155        // 40 sig + 16 version for .suds
    5256        long size = 56;
    53         String url = null;
     57        String saveAs = null;
     58        String username = null;
     59        String password = null;
     60        boolean error = false;
     61        Getopt g = new Getopt("partialeepget", args, "p:cl:o:u:x:");
    5462        try {
    55             for (int i = 0; i < args.length; i++) {
    56                 if (args[i].equals("-p")) {
    57                     proxyHost = args[i+1].substring(0, args[i+1].indexOf(':'));
    58                     String port = args[i+1].substring(args[i+1].indexOf(':')+1);
    59                     proxyPort = Integer.parseInt(port);
    60                     i++;
    61                 } else if (args[i].equals("-l")) {
    62                     size = Long.parseLong(args[i+1]);
    63                     i++;
    64                 } else if (args[i].startsWith("-")) {
    65                     usage();
    66                     return;
    67                 } else {
    68                     url = args[i];
    69                 }
    70             }
     63            int c;
     64            while ((c = g.getopt()) != -1) {
     65              switch (c) {
     66                case 'p':
     67                    String s = g.getOptarg();
     68                    int colon = s.indexOf(':');
     69                    if (colon >= 0) {
     70                        // Todo IPv6 [a:b:c]:4444
     71                        proxyHost = s.substring(0, colon);
     72                        String port = s.substring(colon + 1);
     73                        proxyPort = Integer.parseInt(port);
     74                    } else {
     75                        proxyHost = s;
     76                        // proxyPort remains default
     77                    }
     78                    break;
     79
     80                case 'c':
     81                    // no proxy, same as -p :0
     82                    proxyHost = "";
     83                    proxyPort = 0;
     84                    break;
     85
     86                case 'l':
     87                    size = Long.parseLong(g.getOptarg());
     88                    break;
     89
     90                case 'o':
     91                    saveAs = g.getOptarg();
     92                    break;
     93
     94                case 'u':
     95                    username = g.getOptarg();
     96                    break;
     97
     98                case 'x':
     99                    password = g.getOptarg();
     100                    break;
     101
     102                case '?':
     103                case ':':
     104                default:
     105                    error = true;
     106                    break;
     107              }  // switch
     108            } // while
    71109        } catch (Exception e) {
    72110            e.printStackTrace();
     111            error = true;
     112        }
     113
     114        if (error || args.length - g.getOptind() != 1) {
    73115            usage();
    74             return;
    75         }
    76        
    77         if (url == null) {
    78             usage();
    79             return;
    80         }
    81 
    82         String saveAs = suggestName(url);
     116            System.exit(1);
     117        }
     118        String url = args[g.getOptind()];
     119
     120        if (saveAs == null)
     121            saveAs = suggestName(url);
    83122        OutputStream out;
    84123        try {
     
    87126        } catch (IOException ioe) {
    88127            System.err.println("Failed to create output file " + saveAs);
    89             return;
     128            out = null; // dummy for compiler
     129            System.exit(1);
    90130        }
    91131
    92132        EepGet get = new PartialEepGet(I2PAppContext.getGlobalContext(), proxyHost, proxyPort, out, url, size);
     133        if (username != null) {
     134            if (password == null) {
     135                try {
     136                    BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
     137                    do {
     138                        System.err.print("Proxy password: ");
     139                        password = r.readLine();
     140                        if (password == null)
     141                            throw new IOException();
     142                        password = password.trim();
     143                    } while (password.length() <= 0);
     144                } catch (IOException ioe) {
     145                    System.exit(1);
     146                }
     147            }
     148            get.addAuthorization(username, password);
     149        }
    93150        get.addStatusListener(get.new CLIStatusListener(1024, 40));
    94151        if (get.fetch(45*1000, -1, 60*1000)) {
     
    102159   
    103160    private static void usage() {
    104         System.err.println("PartialEepGet [-p 127.0.0.1:4444] [-l #bytes] url\n" +
    105                            "              (use -p :0 for no proxy)");
     161        System.err.println("PartialEepGet [-p 127.0.0.1[:4444]] [-c] [-o outputFile]\n" +
     162                           "              [-l #bytes] (default 56)\n" +
     163                           "              [-u username] [-x password] url\n" +
     164                           "              (use -c or -p :0 for no proxy)");
    106165    }
    107166   
     
    159218        if(!uaOverridden)
    160219            buf.append("User-Agent: " + USER_AGENT + "\r\n");
     220        if (_authState != null && _shouldProxy && _authState.authMode != AUTH_MODE.NONE) {
     221            buf.append("Proxy-Authorization: ");
     222            buf.append(_authState.getAuthHeader("GET", urlToSend));
     223            buf.append("\r\n");
     224        }
    161225        buf.append("\r\n");
    162226
  • core/java/src/net/i2p/util/SSLEepGet.java

    r090a790 r855cae0  
    5959import javax.net.ssl.X509TrustManager;
    6060
     61import gnu.getopt.Getopt;
     62
    6163import net.i2p.I2PAppContext;
    6264import net.i2p.crypto.CertUtil;
     
    148150     */
    149151    public static void main(String args[]) {
    150         String url = null;
    151152        boolean saveCerts = false;
     153        boolean error = false;
     154        Getopt g = new Getopt("ssleepget", args, "s");
    152155        try {
    153             for (int i = 0; i < args.length; i++) {
    154                 if (args[i].equals("-s")) {
     156            int c;
     157            while ((c = g.getopt()) != -1) {
     158              switch (c) {
     159                case 's':
    155160                    saveCerts = true;
    156                 } else if (args[i].startsWith("-")) {
    157                     usage();
    158                     return;
    159                 } else {
    160                     url = args[i];
    161                 }
    162             }
     161                    break;
     162
     163                case '?':
     164                case ':':
     165                default:
     166                    error = true;
     167                    break;
     168              }  // switch
     169            } // while
    163170        } catch (Exception e) {
    164171            e.printStackTrace();
     172            error = true;
     173        }
     174
     175        if (error || args.length - g.getOptind() != 1) {
    165176            usage();
    166             return;
    167         }
    168        
    169         if (url == null) {
    170             usage();
    171             return;
    172         }
     177            System.exit(1);
     178        }
     179        String url = args[g.getOptind()];
    173180
    174181        String saveAs = suggestName(url);
     
    192199   
    193200    private static void usage() {
    194         System.err.println("Usage: SSLEepGet https://url");
    195         System.err.println("To save unknown certs, use: SSLEepGet -s https://url");
     201        System.err.println("Usage: SSLEepGet https://url\n" +
     202                           "To save unknown certs, use: SSLEepGet -s https://url");
    196203    }
    197204
  • installer/resources/man/eepget.1

    r090a790 r855cae0  
    1 .TH EEEPGET 1 "April 19, 2012" "" "Eepget - I2P Downloader"
     1.TH EEEPGET 1 "February 5, 2014" "" "Eepget - I2P Downloader"
    22
    33.SH NAME
     
    2222.SH OPTIONS
    2323.B
    24 \fB\-p\fR proxy_host:port
     24\fB\-c\fR
    2525.TP
    26 Specify an I2P proxy server (eeproxy) to use. If this option is not specified, eepget will use 127.0.0.1:4444. Specify \fB\-p\fR :0 to disable the eeproxy.
     26Clearnet. Do not use a proxy. Same as \fB\-p\fR :0 .
     27.TP
     28
     29.B
     30\fB\-e\fR etag
     31.TP
     32Sets the etag value in the request headers.
     33.TP
     34
     35.B
     36\fB\-h\fR name=value
     37.TP
     38Adds an arbitrary request header with the given name and value.
     39.TP
     40
     41.B
     42\fB\-l\fR lineLen
     43.TP
     44Controls the progress display. \fB\ lineLen \fP is the length of one progress line in characters. The default is 40.
     45.TP
     46
     47.B
     48\fB\-m\fR markSize
     49.TP
     50Controls the progress display. \fB\ markSize \fP is the number of bytes one '#' character represents. The default is 1024.
    2751.TP
    2852
     
    3054\fB\-n\fR retries
    3155.TP
    32 Specify the number of times to retry downloading if the download isn't successful. If this option is not specified, eepget will retry downloading the file 3 times.
     56Specify the number of times to retry downloading if the download isn't successful. If this option is not specified, eepget will retry downloading the file 5 times.
    3357.TP
    3458
     
    4064
    4165.B
    42 \fB\-m\fR markSize lineLen
     66\fB\-p\fR proxy_host[:port]
    4367.TP
    44 Controls the progress display. \fB\ markSize \fP is the number of bytes one '#' character represents. \fB\ lineLen \fP is the length of one progress line in characters. The defaults are 1024 and 40.
     68Specify an I2P proxy server (eeproxy) to use. If the port is not specified, eepget will use 4444. If this option is not specified, eepget will use 127.0.0.1:4444. Specify \fB\-c\fR or \fB\-p\fR :0 to disable the eeproxy.
    4569.TP
    4670
     
    4973.TP
    5074Sets the inactivity timeout. The default is 60 seconds.
     75.TP
     76
     77.B
     78\fB\-u\fR username
     79.TP
     80Sets the username for proxy authorization, if required.
     81.TP
     82
     83.B
     84\fB\-x\fR password
     85.TP
     86Sets the password for proxy authorization, if required. If a username is specified but not a password, EepGet will prompt for the password.
     87.TP
    5188
    5289.SH EXIT STATUS
     
    5794.SH "SEE ALSO"
    5895
    59 wget(1)
     96curl(1) wget(1)
    6097
  • router/java/src/net/i2p/router/RouterContext.java

    r090a790 r855cae0  
    6868    // split up big lock on this to avoid deadlocks
    6969    private volatile boolean _initialized;
    70     private final Object _lock1 = new Object(), _lock2 = new Object(), _lock3 = new Object();
     70    private final Object _lock1 = new Object(), _lock2 = new Object();
    7171
    7272    private static final List<RouterContext> _contexts = new CopyOnWriteArrayList<RouterContext>();
     
    548548
    549549    /**
    550      *  The controller of router, plugin, and other updates.
    551      *  @return The manager if it is registered, else null
    552      *  @since 0.9.4
    553      */
    554     @Override
    555     public UpdateManager updateManager() {
    556         return _updateManager;
    557     }
    558 
    559     /**
    560      *  Register as the update manager.
    561      *  @throws IllegalStateException if one was already registered
    562      *  @since 0.9.4
    563      */
    564     public void registerUpdateManager(UpdateManager mgr) {
    565         synchronized(_lock3) {
    566             if (_updateManager != null)
    567                 throw new IllegalStateException();
    568             _updateManager = mgr;
    569         }
    570     }
    571 
    572     /**
    573      *  Unregister the update manager.
    574      *  @throws IllegalStateException if it was not registered
    575      *  @since 0.9.4
    576      */
    577     public void unregisterUpdateManager(UpdateManager mgr) {
    578         synchronized(_lock3) {
    579             if (_updateManager != mgr)
    580                 throw new IllegalStateException();
    581             _updateManager = null;
    582         }
    583     }
    584 
    585     /**
    586550     *  The RouterAppManager.
    587551     *  @return the manager
Note: See TracChangeset for help on using the changeset viewer.