use of net.i2p.util.SecureFile in project i2p.i2p by i2p.
the class I2PSnarkServlet method processRequest.
/**
* Do what they ask, adding messages to _manager.addMessage as necessary
*/
private void processRequest(HttpServletRequest req) {
String action = req.getParameter("action");
if (action == null) {
// http://www.onenaught.com/posts/382/firefox-4-change-input-type-image-only-submits-x-and-y-not-name
// TODO-Java6: Remove cast, return type is correct
@SuppressWarnings("unchecked") Map<String, String[]> params = req.getParameterMap();
for (Object o : params.keySet()) {
String key = (String) o;
if (key.startsWith("action_") && key.endsWith(".x")) {
action = key.substring(0, key.length() - 2).substring(7);
break;
}
}
if (action == null) {
_manager.addMessage("No action specified");
return;
}
}
// }
if ("Add".equals(action)) {
String newURL = req.getParameter("nofilter_newURL");
/**
****
* // NOTE - newFile currently disabled in HTML form - see below
* File f = null;
* if ( (newFile != null) && (newFile.trim().length() > 0) )
* f = new File(newFile.trim());
* if ( (f != null) && (!f.exists()) ) {
* _manager.addMessage(_t("Torrent file {0} does not exist", newFile));
* }
* if ( (f != null) && (f.exists()) ) {
* // NOTE - All this is disabled - load from local file disabled
* File local = new File(_manager.getDataDir(), f.getName());
* String canonical = null;
* try {
* canonical = local.getCanonicalPath();
*
* if (local.exists()) {
* if (_manager.getTorrent(canonical) != null)
* _manager.addMessage(_t("Torrent already running: {0}", newFile));
* else
* _manager.addMessage(_t("Torrent already in the queue: {0}", newFile));
* } else {
* boolean ok = FileUtil.copy(f.getAbsolutePath(), local.getAbsolutePath(), true);
* if (ok) {
* _manager.addMessage(_t("Copying torrent to {0}", local.getAbsolutePath()));
* _manager.addTorrent(canonical);
* } else {
* _manager.addMessage(_t("Unable to copy the torrent to {0}", local.getAbsolutePath()) + ' ' + _t("from {0}", f.getAbsolutePath()));
* }
* }
* } catch (IOException ioe) {
* _log.warn("hrm: " + local, ioe);
* }
* } else
****
*/
if (newURL != null) {
newURL = newURL.trim();
String newDir = req.getParameter("nofilter_newDir");
File dir = null;
if (newDir != null) {
newDir = newDir.trim();
if (newDir.length() > 0) {
dir = new SecureFile(newDir);
if (!dir.isAbsolute()) {
_manager.addMessage(_t("Data directory must be an absolute path") + ": " + dir);
return;
}
if (!dir.isDirectory() && !dir.mkdirs()) {
_manager.addMessage(_t("Data directory cannot be created") + ": " + dir);
return;
}
Collection<Snark> snarks = _manager.getTorrents();
for (Snark s : snarks) {
Storage storage = s.getStorage();
if (storage == null)
continue;
File sbase = storage.getBase();
if (isParentOf(sbase, dir)) {
_manager.addMessage(_t("Cannot add torrent {0} inside another torrent: {1}", dir.getAbsolutePath(), sbase));
return;
}
}
}
}
File dd = _manager.getDataDir();
if (!dd.canWrite()) {
_manager.addMessage(_t("No write permissions for data directory") + ": " + dd);
return;
}
if (newURL.startsWith("http://")) {
FetchAndAdd fetch = new FetchAndAdd(_context, _manager, newURL, dir);
_manager.addDownloader(fetch);
} else if (newURL.startsWith(MagnetURI.MAGNET) || newURL.startsWith(MagnetURI.MAGGOT)) {
addMagnet(newURL, dir);
} else if (newURL.length() == 40 && newURL.replaceAll("[a-fA-F0-9]", "").length() == 0) {
// hex
newURL = newURL.toUpperCase(Locale.US);
addMagnet(MagnetURI.MAGNET_FULL + newURL, dir);
} else if (newURL.length() == 32 && newURL.replaceAll("[a-zA-Z2-7]", "").length() == 0) {
// b32
newURL = newURL.toUpperCase(Locale.US);
addMagnet(MagnetURI.MAGNET_FULL + newURL, dir);
} else {
_manager.addMessage(_t("Invalid URL: Must start with \"http://\", \"{0}\", or \"{1}\"", MagnetURI.MAGNET, MagnetURI.MAGGOT));
}
} else {
// no file or URL specified
}
} else if (action.startsWith("Stop_")) {
String torrent = action.substring(5);
if (torrent != null) {
byte[] infoHash = Base64.decode(torrent);
if ((infoHash != null) && (infoHash.length == 20)) {
// valid sha1
for (String name : _manager.listTorrentFiles()) {
Snark snark = _manager.getTorrent(name);
if ((snark != null) && (DataHelper.eq(infoHash, snark.getInfoHash()))) {
_manager.stopTorrent(snark, false);
break;
}
}
}
}
} else if (action.startsWith("Start_")) {
String torrent = action.substring(6);
if (torrent != null) {
byte[] infoHash = Base64.decode(torrent);
if ((infoHash != null) && (infoHash.length == 20)) {
// valid sha1
_manager.startTorrent(infoHash);
}
}
} else if (action.startsWith("Remove_")) {
String torrent = action.substring(7);
if (torrent != null) {
byte[] infoHash = Base64.decode(torrent);
if ((infoHash != null) && (infoHash.length == 20)) {
// valid sha1
for (String name : _manager.listTorrentFiles()) {
Snark snark = _manager.getTorrent(name);
if ((snark != null) && (DataHelper.eq(infoHash, snark.getInfoHash()))) {
MetaInfo meta = snark.getMetaInfo();
if (meta == null) {
// magnet - remove and delete are the same thing
// Remove not shown on UI so we shouldn't get here
_manager.deleteMagnet(snark);
_manager.addMessage(_t("Magnet deleted: {0}", name));
return;
}
File f = new File(name);
File dd = _manager.getDataDir();
boolean canDelete = dd.canWrite() || !f.exists();
_manager.stopTorrent(snark, canDelete);
// TODO race here with the DirMonitor, could get re-added
if (f.delete()) {
_manager.addMessage(_t("Torrent file deleted: {0}", f.getAbsolutePath()));
} else if (f.exists()) {
if (!canDelete)
_manager.addMessage(_t("No write permissions for data directory") + ": " + dd);
_manager.addMessage(_t("Torrent file could not be deleted: {0}", f.getAbsolutePath()));
}
break;
}
}
}
}
} else if (action.startsWith("Delete_")) {
String torrent = action.substring(7);
if (torrent != null) {
byte[] infoHash = Base64.decode(torrent);
if ((infoHash != null) && (infoHash.length == 20)) {
// valid sha1
for (String name : _manager.listTorrentFiles()) {
Snark snark = _manager.getTorrent(name);
if ((snark != null) && (DataHelper.eq(infoHash, snark.getInfoHash()))) {
MetaInfo meta = snark.getMetaInfo();
if (meta == null) {
// magnet - remove and delete are the same thing
_manager.deleteMagnet(snark);
if (snark instanceof FetchAndAdd)
_manager.addMessage(_t("Download deleted: {0}", name));
else
_manager.addMessage(_t("Magnet deleted: {0}", name));
return;
}
File f = new File(name);
File dd = _manager.getDataDir();
boolean canDelete = dd.canWrite() || !f.exists();
_manager.stopTorrent(snark, canDelete);
// TODO race here with the DirMonitor, could get re-added
if (f.delete()) {
_manager.addMessage(_t("Torrent file deleted: {0}", f.getAbsolutePath()));
} else if (f.exists()) {
if (!canDelete)
_manager.addMessage(_t("No write permissions for data directory") + ": " + dd);
_manager.addMessage(_t("Torrent file could not be deleted: {0}", f.getAbsolutePath()));
return;
}
Storage storage = snark.getStorage();
if (storage == null)
break;
List<List<String>> files = meta.getFiles();
if (files == null) {
// single file torrent
for (File df : storage.getFiles()) {
// should be only one
if (df.delete())
_manager.addMessage(_t("Data file deleted: {0}", df.getAbsolutePath()));
else if (df.exists())
_manager.addMessage(_t("Data file could not be deleted: {0}", df.getAbsolutePath()));
// else already gone
}
break;
}
// step 1 delete files
for (File df : storage.getFiles()) {
if (df.delete()) {
// _manager.addMessage(_t("Data file deleted: {0}", df.getAbsolutePath()));
} else if (df.exists()) {
_manager.addMessage(_t("Data file could not be deleted: {0}", df.getAbsolutePath()));
// else already gone
}
}
// step 2 delete dirs bottom-up
Set<File> dirs = storage.getDirectories();
if (dirs == null)
// directory deleted out from under us
break;
if (_log.shouldLog(Log.INFO))
_log.info("Dirs to delete: " + DataHelper.toString(dirs));
boolean ok = false;
for (File df : dirs) {
if (df.delete()) {
ok = true;
// _manager.addMessage(_t("Data dir deleted: {0}", df.getAbsolutePath()));
} else if (df.exists()) {
ok = false;
_manager.addMessage(_t("Directory could not be deleted: {0}", df.getAbsolutePath()));
if (_log.shouldLog(Log.WARN))
_log.warn("Could not delete dir " + df);
// else already gone
}
}
// step 3 message for base (last one)
if (ok)
_manager.addMessage(_t("Directory deleted: {0}", storage.getBase()));
break;
}
}
}
}
} else if ("Save".equals(action)) {
String dataDir = req.getParameter("nofilter_dataDir");
boolean filesPublic = req.getParameter("filesPublic") != null;
boolean autoStart = req.getParameter("autoStart") != null;
boolean smartSort = req.getParameter("smartSort") != null;
String seedPct = req.getParameter("seedPct");
String eepHost = req.getParameter("eepHost");
String eepPort = req.getParameter("eepPort");
String i2cpHost = req.getParameter("i2cpHost");
String i2cpPort = req.getParameter("i2cpPort");
String i2cpOpts = buildI2CPOpts(req);
String upLimit = req.getParameter("upLimit");
String upBW = req.getParameter("upBW");
String refreshDel = req.getParameter("refreshDelay");
String startupDel = req.getParameter("startupDelay");
String pageSize = req.getParameter("pageSize");
boolean useOpenTrackers = req.getParameter("useOpenTrackers") != null;
boolean useDHT = req.getParameter("useDHT") != null;
// String openTrackers = req.getParameter("openTrackers");
String theme = req.getParameter("theme");
String lang = req.getParameter("lang");
boolean ratings = req.getParameter("ratings") != null;
boolean comments = req.getParameter("comments") != null;
// commentsName is filtered in SnarkManager.updateConfig()
String commentsName = req.getParameter("nofilter_commentsName");
boolean collapsePanels = req.getParameter("collapsePanels") != null;
_manager.updateConfig(dataDir, filesPublic, autoStart, smartSort, refreshDel, startupDel, pageSize, seedPct, eepHost, eepPort, i2cpHost, i2cpPort, i2cpOpts, upLimit, upBW, useOpenTrackers, useDHT, theme, lang, ratings, comments, commentsName, collapsePanels);
// update servlet
try {
setResourceBase(_manager.getDataDir());
} catch (ServletException se) {
}
} else if ("Save2".equals(action)) {
String taction = req.getParameter("taction");
if (taction != null)
processTrackerForm(taction, req);
} else if ("Create".equals(action)) {
String baseData = req.getParameter("nofilter_baseFile");
if (baseData != null && baseData.trim().length() > 0) {
File baseFile = new File(baseData.trim());
if (!baseFile.isAbsolute())
baseFile = new File(_manager.getDataDir(), baseData);
String announceURL = req.getParameter("announceURL");
if (baseFile.exists()) {
File dd = _manager.getDataDir();
if (!dd.canWrite()) {
_manager.addMessage(_t("No write permissions for data directory") + ": " + dd);
return;
}
String torrentName = baseFile.getName();
if (torrentName.toLowerCase(Locale.US).endsWith(".torrent")) {
_manager.addMessage(_t("Cannot add a torrent ending in \".torrent\": {0}", baseFile.getAbsolutePath()));
return;
}
Snark snark = _manager.getTorrentByBaseName(torrentName);
if (snark != null) {
_manager.addMessage(_t("Torrent with this name is already running: {0}", torrentName));
return;
}
if (isParentOf(baseFile, _manager.getDataDir()) || isParentOf(baseFile, _manager.util().getContext().getBaseDir()) || isParentOf(baseFile, _manager.util().getContext().getConfigDir())) {
_manager.addMessage(_t("Cannot add a torrent including an I2P directory: {0}", baseFile.getAbsolutePath()));
return;
}
Collection<Snark> snarks = _manager.getTorrents();
for (Snark s : snarks) {
Storage storage = s.getStorage();
if (storage == null)
continue;
File sbase = storage.getBase();
if (isParentOf(sbase, baseFile)) {
_manager.addMessage(_t("Cannot add torrent {0} inside another torrent: {1}", baseFile.getAbsolutePath(), sbase));
return;
}
if (isParentOf(baseFile, sbase)) {
_manager.addMessage(_t("Cannot add torrent {0} including another torrent: {1}", baseFile.getAbsolutePath(), sbase));
return;
}
}
if (announceURL.equals("none"))
announceURL = null;
_lastAnnounceURL = announceURL;
List<String> backupURLs = new ArrayList<String>();
Enumeration<?> e = req.getParameterNames();
while (e.hasMoreElements()) {
Object o = e.nextElement();
if (!(o instanceof String))
continue;
String k = (String) o;
if (k.startsWith("backup_")) {
String url = k.substring(7);
if (!url.equals(announceURL))
backupURLs.add(DataHelper.stripHTML(url));
}
}
List<List<String>> announceList = null;
if (!backupURLs.isEmpty()) {
// BEP 12 - Put primary first, then the others, each as the sole entry in their own list
if (announceURL == null) {
_manager.addMessage(_t("Error - Cannot include alternate trackers without a primary tracker"));
return;
}
backupURLs.add(0, announceURL);
boolean hasPrivate = false;
boolean hasPublic = false;
for (String url : backupURLs) {
if (_manager.getPrivateTrackers().contains(url))
hasPrivate = true;
else
hasPublic = true;
}
if (hasPrivate && hasPublic) {
_manager.addMessage(_t("Error - Cannot mix private and public trackers in a torrent"));
return;
}
announceList = new ArrayList<List<String>>(backupURLs.size());
for (String url : backupURLs) {
announceList.add(Collections.singletonList(url));
}
}
try {
// This may take a long time to check the storage, but since it already exists,
// it shouldn't be THAT bad, so keep it in this thread.
// TODO thread it for big torrents, perhaps a la FetchAndAdd
boolean isPrivate = _manager.getPrivateTrackers().contains(announceURL);
Storage s = new Storage(_manager.util(), baseFile, announceURL, announceList, null, isPrivate, null);
// close the files... maybe need a way to pass this Storage to addTorrent rather than starting over
s.close();
MetaInfo info = s.getMetaInfo();
File torrentFile = new File(_manager.getDataDir(), s.getBaseName() + ".torrent");
// FIXME is the storage going to stay around thanks to the info reference?
// now add it, but don't automatically start it
boolean ok = _manager.addTorrent(info, s.getBitField(), torrentFile.getAbsolutePath(), baseFile, true);
if (!ok)
return;
_manager.addMessage(_t("Torrent created for \"{0}\"", baseFile.getName()) + ": " + torrentFile.getAbsolutePath());
if (announceURL != null && !_manager.util().getOpenTrackers().contains(announceURL))
_manager.addMessage(_t("Many I2P trackers require you to register new torrents before seeding - please do so before starting \"{0}\"", baseFile.getName()));
} catch (IOException ioe) {
_manager.addMessage(_t("Error creating a torrent for \"{0}\"", baseFile.getAbsolutePath()) + ": " + ioe);
_log.error("Error creating a torrent", ioe);
}
} else {
_manager.addMessage(_t("Cannot create a torrent for the nonexistent data: {0}", baseFile.getAbsolutePath()));
}
} else {
_manager.addMessage(_t("Error creating torrent - you must enter a file or directory"));
}
} else if ("StopAll".equals(action)) {
_manager.stopAllTorrents(false);
} else if ("StartAll".equals(action)) {
_manager.startAllTorrents();
} else if ("Clear".equals(action)) {
String sid = req.getParameter("id");
if (sid != null) {
try {
int id = Integer.parseInt(sid);
_manager.clearMessages(id);
} catch (NumberFormatException nfe) {
}
}
} else {
_manager.addMessage("Unknown POST action: \"" + action + '\"');
}
}
use of net.i2p.util.SecureFile in project i2p.i2p by i2p.
the class Storage method createFileFromNames.
/**
* Note that filtering each path element individually may lead to
* things going in the wrong place if there are duplicates
* in intermediate path elements after filtering.
*
* @param names path elements
*/
private File createFileFromNames(File base, List<String> names, boolean areFilesPublic) throws IOException {
File f = null;
Iterator<String> it = names.iterator();
while (it.hasNext()) {
String name = optFilterName(it.next());
if (it.hasNext()) {
// Another dir in the hierarchy.
if (areFilesPublic)
f = new File(base, name);
else
f = new SecureFile(base, name);
if (!f.mkdir() && !f.isDirectory())
throw new IOException("Could not create directory " + f);
base = f;
} else {
// The final element (file) in the hierarchy.
if (areFilesPublic)
f = new File(base, name);
else
f = new SecureFile(base, name);
// so do it second
if (!f.exists() && !f.createNewFile())
throw new IOException("Could not create file " + f);
}
}
return f;
}
use of net.i2p.util.SecureFile in project i2p.i2p by i2p.
the class TunnelController method createPrivateKey.
/**
* @return success
*/
private boolean createPrivateKey() {
I2PClient client = I2PClientFactory.createClient();
File keyFile = getPrivateKeyFile();
if (keyFile == null) {
log("No filename specified for the private key");
return false;
}
if (keyFile.exists()) {
// log("Not overwriting existing private keys in " + keyFile.getAbsolutePath());
return true;
} else {
File parent = keyFile.getParentFile();
if ((parent != null) && (!parent.exists()))
parent.mkdirs();
}
FileOutputStream fos = null;
try {
fos = new SecureFileOutputStream(keyFile);
SigType stype = PREFERRED_SIGTYPE;
String st = _config.getProperty(OPT_SIG_TYPE);
if (st != null) {
SigType type = SigType.parseSigType(st);
if (type != null && type.isAvailable())
stype = type;
else
log("Unsupported sig type " + st + ", reverting to " + stype);
}
Destination dest = client.createDestination(fos, stype);
String destStr = dest.toBase64();
log("Private key created and saved in " + keyFile.getAbsolutePath());
log("You should backup this file in a secure place.");
log("New destination: " + destStr);
String b32 = dest.toBase32();
log("Base32: " + b32);
File backupDir = new SecureFile(I2PAppContext.getGlobalContext().getConfigDir(), KEY_BACKUP_DIR);
if (backupDir.isDirectory() || backupDir.mkdir()) {
String name = b32 + '-' + I2PAppContext.getGlobalContext().clock().now() + ".dat";
File backup = new File(backupDir, name);
if (FileUtil.copy(keyFile, backup, false, true)) {
SecureFileOutputStream.setPerms(backup);
log("Private key backup saved to " + backup.getAbsolutePath());
}
}
} catch (I2PException ie) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error creating new destination", ie);
log("Error creating new destination: " + ie.getMessage());
return false;
} catch (IOException ioe) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error creating writing the destination to " + keyFile.getAbsolutePath(), ioe);
log("Error writing the keys to " + keyFile.getAbsolutePath());
return false;
} finally {
if (fos != null)
try {
fos.close();
} catch (IOException ioe) {
}
}
return true;
}
use of net.i2p.util.SecureFile in project i2p.i2p by i2p.
the class SummaryListener method startListening.
/**
* @return success
*/
public boolean startListening() {
RateStat rs = _rate.getRateStat();
long period = _rate.getPeriod();
String baseName = rs.getName() + "." + period;
_name = createName(_context, baseName);
_eventName = createName(_context, baseName + ".events");
File rrdFile = null;
try {
RrdBackendFactory factory = RrdBackendFactory.getFactory(getBackendName());
String rrdDefName;
if (_isPersistent) {
// generate full path for persistent RRD files
File rrdDir = new SecureFile(_context.getRouterDir(), RRD_DIR);
rrdFile = new File(rrdDir, RRD_PREFIX + _name + RRD_SUFFIX);
rrdDefName = rrdFile.getAbsolutePath();
if (rrdFile.exists()) {
_db = new RrdDb(rrdDefName, factory);
Archive arch = _db.getArchive(CF, STEPS);
if (arch == null)
throw new IOException("No average CF in " + rrdDefName);
_rows = arch.getRows();
if (_log.shouldLog(Log.INFO))
_log.info("Existing RRD " + baseName + " (" + rrdDefName + ") with " + _rows + " rows consuming " + _db.getRrdBackend().getLength() + " bytes");
} else {
rrdDir.mkdir();
}
} else {
rrdDefName = _name;
}
if (_db == null) {
// not persistent or not previously existing
RrdDef def = new RrdDef(rrdDefName, now() / 1000, period / 1000);
// for info on the heartbeat, xff, steps, etc, see the rrdcreate man page, aka
// http://www.jrobin.org/support/man/rrdcreate.html
long heartbeat = period * 10 / 1000;
def.addDatasource(_name, "GAUGE", heartbeat, Double.NaN, Double.NaN);
def.addDatasource(_eventName, "GAUGE", heartbeat, 0, Double.NaN);
if (_isPersistent) {
_rows = (int) Math.max(MIN_ROWS, Math.min(MAX_ROWS, THREE_MONTHS / period));
} else {
_rows = MIN_ROWS;
}
def.addArchive(CF, XFF, STEPS, _rows);
_db = new RrdDb(def, factory);
if (_isPersistent)
SecureFileOutputStream.setPerms(new File(rrdDefName));
if (_log.shouldLog(Log.INFO))
_log.info("New RRD " + baseName + " (" + rrdDefName + ") with " + _rows + " rows consuming " + _db.getRrdBackend().getLength() + " bytes");
}
_sample = _db.createSample();
_renderer = new SummaryRenderer(_context, this);
_rate.setSummaryListener(this);
return true;
} catch (OutOfMemoryError oom) {
_log.error("Error starting RRD for stat " + baseName, oom);
} catch (RrdException re) {
_log.error("Error starting RRD for stat " + baseName, re);
// corrupt file?
if (_isPersistent && rrdFile != null)
rrdFile.delete();
} catch (IOException ioe) {
_log.error("Error starting RRD for stat " + baseName, ioe);
} catch (Throwable t) {
_log.error("Error starting RRD for stat " + baseName, t);
}
return false;
}
use of net.i2p.util.SecureFile in project i2p.i2p by i2p.
the class NewsFetcher method processBlocklistEntries.
/**
* Process blocklist entries
*
* @since 0.9.28
*/
private void processBlocklistEntries(BlocklistEntries ble) {
long oldTime = _context.getProperty(PROP_BLOCKLIST_TIME, 0L);
if (ble.updated <= oldTime) {
if (_log.shouldWarn())
_log.warn("Not processing blocklist " + new Date(ble.updated) + ", already have " + new Date(oldTime));
return;
}
Blocklist bl = _context.blocklist();
Banlist ban = _context.banlist();
DateFormat fmt = DateFormat.getDateInstance(DateFormat.SHORT);
fmt.setTimeZone(SystemVersion.getSystemTimeZone(_context));
String reason = "Blocklist feed " + new Date(ble.updated);
int banned = 0;
for (Iterator<String> iter = ble.entries.iterator(); iter.hasNext(); ) {
String s = iter.next();
if (s.length() == 44) {
byte[] b = Base64.decode(s);
if (b == null || b.length != Hash.HASH_LENGTH) {
iter.remove();
continue;
}
Hash h = Hash.create(b);
if (!ban.isBanlistedForever(h))
ban.banlistRouterForever(h, reason);
} else {
byte[] ip = Addresses.getIP(s);
if (ip == null) {
iter.remove();
continue;
}
if (!bl.isBlocklisted(ip))
bl.add(ip);
}
if (++banned >= BlocklistEntries.MAX_ENTRIES) {
// prevent somebody from destroying the whole network
break;
}
}
for (String s : ble.removes) {
if (s.length() == 44) {
byte[] b = Base64.decode(s);
if (b == null || b.length != Hash.HASH_LENGTH)
continue;
Hash h = Hash.create(b);
if (ban.isBanlistedForever(h))
ban.unbanlistRouter(h);
} else {
byte[] ip = Addresses.getIP(s);
if (ip == null)
continue;
if (bl.isBlocklisted(ip))
bl.remove(ip);
}
}
// Save the blocks. We do not save the unblocks.
File f = new SecureFile(_context.getConfigDir(), BLOCKLIST_DIR);
f.mkdirs();
f = new File(f, BLOCKLIST_FILE);
boolean fail = false;
BufferedWriter out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(f), "UTF-8"));
out.write("# ");
out.write(ble.supdated);
out.newLine();
banned = 0;
for (String s : ble.entries) {
// IPv6
s = s.replace(':', ';');
out.write(reason);
out.write(':');
out.write(s);
out.newLine();
if (++banned >= BlocklistEntries.MAX_ENTRIES)
break;
}
} catch (IOException ioe) {
_log.error("Error writing blocklist", ioe);
fail = true;
} finally {
if (out != null)
try {
out.close();
} catch (IOException ioe) {
}
}
if (!fail) {
f.setLastModified(ble.updated);
String upd = Long.toString(ble.updated);
_context.router().saveConfig(PROP_BLOCKLIST_TIME, upd);
_mgr.notifyVersionAvailable(this, _currentURI, BLOCKLIST, "", HTTP, null, upd, "");
}
if (_log.shouldWarn())
_log.warn("Processed " + ble.entries.size() + " blocks and " + ble.removes.size() + " unblocks from news feed");
}
Aggregations