/*
* free (adj.): unencumbered; not under the control of others
* Written by mihi in 2004 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*/
package net.i2p.client.naming;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import net.i2p.I2PAppContext;
import net.i2p.data.Destination;
/**
* A naming service based on multiple "hosts.txt" files.
* Supports .b32.i2p and {b64} lookups.
* Supports caching.
* All host names are converted to lower case.
*/
public class HostsTxtNamingService extends MetaNamingService {
/**
* The naming service should only be constructed and accessed through the
* application context. This constructor should only be used by the
* appropriate application context itself.
*
*/
public HostsTxtNamingService(I2PAppContext context) {
super(context, null);
for (String name : getFilenames()) {
addNamingService(new SingleFileNamingService(context, name), false);
}
}
/**
* If this system property is specified, the tunnel will read the
* given file for hostname=destKey values when resolving names
*/
public final static String PROP_HOSTS_FILE = "i2p.hostsfilelist";
/** default hosts.txt filenames */
public final static String DEFAULT_HOSTS_FILE =
"privatehosts.txt,userhosts.txt,hosts.txt";
private List<String> getFilenames() {
String list = _context.getProperty(PROP_HOSTS_FILE, DEFAULT_HOSTS_FILE);
StringTokenizer tok = new StringTokenizer(list, ",");
List<String> rv = new ArrayList<String>(tok.countTokens());
while (tok.hasMoreTokens())
rv.add(tok.nextToken());
return rv;
}
@Override
public Destination lookup(String hostname, Properties lookupOptions, Properties storedOptions) {
// If it's long, assume it's a key.
if (hostname.length() >= DEST_SIZE)
return lookupBase64(hostname);
return super.lookup(hostname.toLowerCase(Locale.US), lookupOptions, storedOptions);
}
@Override
public boolean put(String hostname, Destination d, Properties options) {
return super.put(hostname.toLowerCase(Locale.US), d, options);
}
@Override
public boolean putIfAbsent(String hostname, Destination d, Properties options) {
return super.putIfAbsent(hostname.toLowerCase(Locale.US), d, options);
}
@Override
public boolean remove(String hostname, Properties options) {
return super.remove(hostname.toLowerCase(Locale.US), options);
}
/**
* All services aggregated, unless options contains
* the property "file", in which case only for that file
*/
@Override
public Set<String> getNames(Properties options) {
String file = null;
if (options != null)
file = options.getProperty("file");
if (file == null)
return super.getNames(options);
for (NamingService ns : _services) {
String name = ns.getName();
if (name.equals(file) || name.endsWith('/' + file) || name.endsWith('\\' + file))
return ns.getNames(options);
}
return new HashSet<String>(0);
}
}