diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index da60c89b03..dd52b10ad7 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -52,6 +52,7 @@ test:ant:
- echo junit.home=/usr/share/java >> override.properties
- echo hamcrest.home=/usr/share/java >> override.properties
- echo mockito.home=/usr/share/java >> override.properties
+ - echo build.built-by=GitHub Actions >> override.properties
script:
- ant test
only:
diff --git a/Dockerfile b/Dockerfile
index f4fedaea56..31da41399d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,6 +6,8 @@ WORKDIR /tmp/build
COPY . .
RUN apk add --virtual build-base gettext tar bzip2 apache-ant openjdk17 \
+ && echo "build.built-by=Docker" >> override.properties \
+
&& ant preppkg-linux-only \
&& rm -rf pkg-temp/osid pkg-temp/lib/wrapper pkg-temp/lib/wrapper.* \
&& apk del build-base gettext tar bzip2 apache-ant openjdk17
@@ -13,7 +15,8 @@ RUN apk add --virtual build-base gettext tar bzip2 apache-ant openjdk17 \
FROM alpine:latest
ENV APP_HOME="/i2p"
-RUN apk add openjdk17-jre
+RUN apk add openjdk17-jre ttf-dejavu
+
WORKDIR ${APP_HOME}
COPY --from=builder /tmp/build/pkg-temp .
diff --git a/apps/addressbook/build.xml b/apps/addressbook/build.xml
index b02dc2409e..4f165ab380 100644
--- a/apps/addressbook/build.xml
+++ b/apps/addressbook/build.xml
@@ -84,28 +84,36 @@
+
-
-
+
+
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/apps/desktopgui/build.xml b/apps/desktopgui/build.xml
index 6487bfceac..baf8d04c14 100644
--- a/apps/desktopgui/build.xml
+++ b/apps/desktopgui/build.xml
@@ -64,17 +64,24 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -108,7 +115,7 @@
-
+
diff --git a/apps/i2pcontrol/build.xml b/apps/i2pcontrol/build.xml
index cc24c7e74f..d3e4883da1 100644
--- a/apps/i2pcontrol/build.xml
+++ b/apps/i2pcontrol/build.xml
@@ -92,7 +92,29 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -108,7 +130,7 @@
-
+
@@ -124,7 +146,7 @@
-
+
diff --git a/apps/i2psnark/java/build.xml b/apps/i2psnark/java/build.xml
index b06593af08..edde6bf451 100644
--- a/apps/i2psnark/java/build.xml
+++ b/apps/i2psnark/java/build.xml
@@ -68,13 +68,20 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
@@ -111,7 +118,7 @@
-
+
diff --git a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java
index 412663b660..f51ecf64b4 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java
@@ -77,6 +77,7 @@ public class I2PSnarkUtil implements DisconnectListener {
private DHT _dht;
private long _startedTime;
private final DisconnectListener _discon;
+ private int _maxFilesPerTorrent = SnarkManager.DEFAULT_MAX_FILES_PER_TORRENT;
private static final int EEPGET_CONNECT_TIMEOUT = 45*1000;
private static final int EEPGET_CONNECT_TIMEOUT_SHORT = 5*1000;
@@ -242,6 +243,11 @@ public Map getI2CPOptions() {
/** @since 0.9.1 */
public File getTempDir() { return _tmpDir; }
+ /** @since 0.9.58 */
+ public int getMaxFilesPerTorrent() { return _maxFilesPerTorrent; }
+ /** @since 0.9.58 */
+ public void setMaxFilesPerTorrent(int max) { _maxFilesPerTorrent = Math.max(max, 1); }
+
/**
* Connect to the router, if we aren't already
*/
diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
index e703cb9f8e..d80366ca2e 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
@@ -129,7 +129,7 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
private static final String PROP_META_ACTIVITY = "activity";
private static final String CONFIG_FILE_SUFFIX = ".config";
- private static final String CONFIG_FILE = "i2psnark" + CONFIG_FILE_SUFFIX;
+ public static final String CONFIG_FILE = "i2psnark" + CONFIG_FILE_SUFFIX;
private static final String COMMENT_FILE_SUFFIX = ".comments.txt.gz";
public static final String PROP_FILES_PUBLIC = "i2psnark.filesPublic";
public static final String PROP_OLD_AUTO_START = "i2snark.autoStart"; // oops
@@ -164,6 +164,8 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
private static final String PROP_COMMENTS = "i2psnark.comments";
/** @since 0.9.31 */
private static final String PROP_COMMENTS_NAME = "i2psnark.commentsName";
+ /** @since 0.9.58 */
+ public static final String PROP_MAX_FILES_PER_TORRENT = "i2psnark.maxFilesPerTorrent";
public static final int MIN_UP_BW = 10;
public static final int DEFAULT_MAX_UP_BW = 25;
@@ -171,6 +173,7 @@ public class SnarkManager implements CompleteListener, ClientApp, DisconnectList
public static final int DEFAULT_REFRESH_DELAY_SECS = 15;
private static final int DEFAULT_PAGE_SIZE = 50;
public static final int DEFAULT_TUNNEL_QUANTITY = 3;
+ public static final int DEFAULT_MAX_FILES_PER_TORRENT = 2000;
public static final String CONFIG_DIR_SUFFIX = ".d";
private static final String SUBDIR_PREFIX = "s";
private static final String B64 = Base64.ALPHABET_I2P;
@@ -1000,6 +1003,7 @@ private void updateConfig() {
// _util.setProxy(eepHost, eepPort);
_util.setMaxUploaders(getInt(PROP_UPLOADERS_TOTAL, Snark.MAX_TOTAL_UPLOADERS));
_util.setMaxUpBW(getInt(PROP_UPBW_MAX, DEFAULT_MAX_UP_BW));
+ _util.setMaxFilesPerTorrent(getInt(PROP_MAX_FILES_PER_TORRENT, DEFAULT_MAX_FILES_PER_TORRENT));
_util.setStartupDelay(getInt(PROP_STARTUP_DELAY, DEFAULT_STARTUP_DELAY));
_util.setFilesPublic(areFilesPublic());
_util.setOpenTrackers(getListConfig(PROP_OPENTRACKERS, DEFAULT_OPENTRACKERS));
@@ -1479,9 +1483,6 @@ public void saveConfig() {
}
}
- /** hardcoded for sanity. perhaps this should be customizable, for people who increase their ulimit, etc. */
- public static final int MAX_FILES_PER_TORRENT = 2000;
-
/**
* Set of canonical .torrent filenames that we are dealing with.
* An unsynchronized copy.
@@ -2450,8 +2451,11 @@ public void removeMagnetStatus(byte[] ih) {
*/
private String validateTorrent(MetaInfo info) {
List> files = info.getFiles();
- if ( (files != null) && (files.size() > MAX_FILES_PER_TORRENT) ) {
- return _t("Too many files in \"{0}\" ({1})!", info.getName(), files.size());
+ if (files != null && files.size() > _util.getMaxFilesPerTorrent()) {
+ return _t("Too many files in \"{0}\" ({1})!", info.getName(), files.size()) +
+ " - limit is " + _util.getMaxFilesPerTorrent() + ", zip them or set " +
+ PROP_MAX_FILES_PER_TORRENT + '=' + files.size() + " in " +
+ _configFile.getAbsolutePath() + " and restart";
} else if ( (files == null) && (info.getName().endsWith(".torrent")) ) {
return _t("Torrent file \"{0}\" cannot end in \".torrent\"!", info.getName());
} else if (info.getPieces() <= 0) {
diff --git a/apps/i2psnark/java/src/org/klomp/snark/Storage.java b/apps/i2psnark/java/src/org/klomp/snark/Storage.java
index e74cecb50e..5ae3e27fca 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/Storage.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/Storage.java
@@ -288,9 +288,13 @@ private List getFiles(File base) throws IOException
* @throws IOException if too many total files
*/
private void addFiles(List l, File f) throws IOException {
+ int max = _util.getMaxFilesPerTorrent();
if (!f.isDirectory()) {
- if (l.size() >= SnarkManager.MAX_FILES_PER_TORRENT)
- throw new IOException("Too many files, limit is " + SnarkManager.MAX_FILES_PER_TORRENT + ", zip them?");
+ if (l.size() >= max)
+ throw new IOException(_util.getString("Too many files in \"{0}\" ({1})!", metainfo.getName(), l.size()) +
+ " - limit is " + max + ", zip them or set " +
+ SnarkManager.PROP_MAX_FILES_PER_TORRENT + '=' + l.size() + " in " +
+ SnarkManager.CONFIG_FILE + " and restart");
l.add(f);
} else {
File[] files = f.listFiles();
diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
index 80b268ac10..98247aa748 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
@@ -326,7 +326,8 @@ else if (method.equals("POST"))
out.write("\n");
} else {
delay = _manager.getRefreshDelaySeconds();
- if (delay > 0) {
+ // init for search even if refresh disabled
+ //if (delay > 0) {
String jsPfx = _context.isRouterContext() ? "" : ".resources";
String downMsg = _context.isRouterContext() ? _t("Router is down") : _t("I2PSnark has stopped");
// fallback to metarefresh when javascript is disabled
@@ -337,7 +338,7 @@ else if (method.equals("POST"))
"var ajaxDelay = " + (delay * 1000) + ";\n" +
"\n" +
"\n");
- }
+ //}
out.write("