Compare commits

...

13 Commits

7 changed files with 200 additions and 285 deletions

View File

@ -27,10 +27,10 @@ jobs:
distribution: 'temurin'
- name: build with script
run: bash -c "./buildscripts/unsigned.sh; ls *.exe"
- name: Upload I2P-Easy-Install-Bundle-${{ github.sha }}-unsigned.exe
- name: Upload I2P-Easy-Install-Bundle-unsigned.exe
uses: actions/upload-artifact@v4
with:
name: I2P-Easy-Install-Bundle-${{ github.sha }}-unsigned.exe
name: I2P-Easy-Install-Bundle-unsigned.exe
path: I2P-Easy-Install-Bundle-2.4.0.exe
buildjpackagexe:
@ -44,10 +44,10 @@ jobs:
distribution: 'temurin'
- name: build with script
run: bash -c "./buildscripts/exe.sh; ls *.exe"
- name: Upload I2P-Easy-Install-Bundle-${{ github.sha }}-unsigned.exe
- name: Upload I2P-Easy-Install-Bundle-unsigned.exe
uses: actions/upload-artifact@v4
with:
name: I2P-EXE-${{ github.sha }}-unsigned.exe
name: I2P-EXE-unsigned.exe
path: I2P-EXE-2.4.0.exe
buildjpackagmsi:
@ -61,10 +61,10 @@ jobs:
distribution: 'temurin'
- name: build with script
run: bash -c "./buildscripts/msi.sh; ls *.msi"
- name: Upload I2P-Easy-Install-Bundle-${{ github.sha }}-unsigned.msi
- name: Upload I2P-Easy-Install-Bundle-unsigned.msi
uses: actions/upload-artifact@v4
with:
name: I2P-MSI-${{ github.sha }}-unsigned.msi
name: I2P-MSI-unsigned.msi
path: I2P-MSI-2.4.0.msi
buildzip:
@ -90,10 +90,10 @@ jobs:
distribution: 'temurin'
- name: build with script
run: bash -c "./buildscripts/zip.sh; ls *.zip"
- name: Upload I2P-windows-portable-${{ github.sha }}.zip
- name: Upload I2P-windows-portable.zip
uses: actions/upload-artifact@v4
with:
name: I2P-windows-portable-${{ github.sha }}.zip
name: I2P-windows-portable.zip
path: I2P-windows-portable.zip
buildtgz:
@ -110,8 +110,8 @@ jobs:
sudo apt-get install -y nsis nsis-common nsis-pluginapi wget dos2unix curl jq gpg gettext
- name: build with script
run: ./buildscripts/targz.sh; ls *.tar.gz
- name: Upload I2P-${{ github.sha }}.tar.gz
- name: Upload I2P.tar.gz
uses: actions/upload-artifact@v4
with:
name: I2P-${{ github.sha }}.tar.gz
name: I2P.tar.gz
path: I2P.tar.gz

View File

@ -60,7 +60,7 @@ jobs:
workflow: ant.yml
if_no_artifact_found: fail
# remove .zip file extension
- run: for f in *.zip; do mv "$f" "${f%.zip}"; done
- run: for f in *.zip; do unzip "$f"; rm "$f"; done
- run: echo "" | tee -a changelog.txt
- run: echo "## Checksums" | tee -a changelog.txt
- run: echo "" | tee -a changelog.txt
@ -68,6 +68,10 @@ jobs:
- run: sha256sum * | tee -a changelog.txt
- run: echo '```' | tee -a changelog.txt
- run: echo "" | tee -a changelog.txt
- run: echo '```' | tee -a changelog.txt
- run: file * | tee -a changelog.txt
- run: echo '```' | tee -a changelog.txt
- run: echo "" | tee -a changelog.txt
- name: Upload artifacts
uses: ncipollo/release-action@v1
with:

View File

@ -104,9 +104,16 @@ if [ ! -f "$SCRIPT_DIR/build/jna-platform.jar" ]; then
wget_download "https://repo1.maven.org/maven2/net/java/dev/jna/jna-platform/$JNA_VERSION/jna-platform-$JNA_VERSION.jar" -O "$SCRIPT_DIR/build/jna-platform.jar"
fi
if [ ! -f "$SCRIPT_DIR/build/i2pfirefox.jar" ]; then
if [ ! -f "$SCRIPT_DIR/build/i2pfirefox.zip" ]; then
echo "downloading i2pfirefox jars"
wget_download "https://github.com/eyedeekay/i2p.plugins.firefox/releases/download/$I2PFIREFOX_VERSION/i2pfirefox.jar" -O "$SCRIPT_DIR/build/i2pfirefox.jar"
wget_download "https://github.com/eyedeekay/i2p.plugins.firefox/releases/download/$I2PFIREFOX_VERSION/plugin.zip" -O "$SCRIPT_DIR/build/i2pfirefox.zip"
fi
if [ ! -d "$SCRIPT_DIR/build/I2P/config/plugins/i2pfirefox" ]; then
mkdir -p "$SCRIPT_DIR/build/I2P/config/plugins/"
unzip "$SCRIPT_DIR/build/i2pfirefox.zip" -d "$SCRIPT_DIR/build/I2P/config/plugins/"
rm -rf "$SCRIPT_DIR/build/I2P/config/plugins/i2pfirefox"
mv "$SCRIPT_DIR/build/I2P/config/plugins/plugin" "$SCRIPT_DIR/build/I2P/config/plugins/i2pfirefox"
fi
for dll in "$I2P_JBIGI/"*windows*.dll; do
@ -117,6 +124,7 @@ cd "$SCRIPT_DIR"/java
"$JAVA_HOME"/bin/javac -Xlint:deprecation -d ../build -classpath "$SCRIPT_DIR/build/i2pfirefox.jar:$SCRIPT_DIR/build/jna.jar:$SCRIPT_DIR/build/jna-platform.jar":"$SCRIPT_DIR/build/i2p.jar:$SCRIPT_DIR/build/router.jar:$SCRIPT_DIR/build/routerconsole.jar:$SCRIPT_DIR/build/jbigi.jar" \
net/i2p/router/CopyConfigDir.java \
net/i2p/router/WindowsServiceUtil.java \
net/i2p/router/WindowsAppUtil.java \
net/i2p/router/WindowsUpdatePostProcessor.java \
net/i2p/router/WinLauncher.java \
net/i2p/router/WinUpdateProcess.java \

View File

@ -2,8 +2,8 @@
JNA_VERSION=5.12.1
export JNA_VERSION=5.12.1
I2PFIREFOX_VERSION=1.0.9
export I2PFIREFOX_VERSION=1.0.9
I2PFIREFOX_VERSION=1.4.7
export I2PFIREFOX_VERSION=1.4.7
# Comment this out to build from an alternate branch or
# the tip of the master branch.
VERSIONMAJOR=2

View File

@ -9,26 +9,14 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import net.i2p.util.Log;
public class CopyConfigDir extends WindowsServiceUtil {
final Logger logger = Logger.getLogger("configlog");
public class CopyConfigDir extends WindowsAppUtil {
final Log logger;
public void initLogger() {
try {
// This block configure the logger with handler and formatter
FileHandler fh = new FileHandler(logFile().toString());
logger.addHandler(fh);
SimpleFormatter formatter = new SimpleFormatter();
fh.setFormatter(formatter);
// the following statement is used to log any messages
logger.info("My first log");
} catch (SecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
public CopyConfigDir(RouterContext ctx) {
logger = ctx.logManager().getLog(CopyConfigDir.class);
}
public boolean copyDirectory(String baseDir, String workDir) {
@ -73,7 +61,7 @@ public class CopyConfigDir extends WindowsServiceUtil {
try {
jpackagedConfigsInUse.createNewFile();
} catch (IOException e) {
logger.warning(
logger.warn(
"Error creating jpackaged file, delete config files manually when uninstalling");
}
}
@ -128,164 +116,19 @@ public class CopyConfigDir extends WindowsServiceUtil {
out.close();
return 1;
} catch (Throwable e) {
logger.warning(e.toString());
logger.warning("failed to copy " + basePath.getAbsolutePath() + " to " +
workPath.getAbsolutePath());
logger.warn(e.toString());
logger.warn("failed to copy " + basePath.getAbsolutePath() + " to " +
workPath.getAbsolutePath());
return 0;
}
}
protected File selectHome() { // throws Exception {
String path_override = System.getenv("I2P_CONFIG");
if (path_override != null) {
File path = new File(path_override);
if (path != null && path.exists()) {
if (path.isDirectory())
return path.getAbsoluteFile();
else
throw new RuntimeException("I2P_CONFIG is not a directory: " + path);
}
}
File i2p = appImageHome();
logger.info("Checking for signs of life in I2P_CONFIG directory: " + i2p);
return i2p;
}
protected File selectProgramFile() {
String path_override = System.getenv("I2P");
if (path_override != null) {
File path = new File(path_override);
if (path.exists()) {
if (path.isDirectory())
return path.getAbsoluteFile();
else
throw new RuntimeException("I2P is not a directory: " + path);
}
}
File i2p = appImageHome();
logger.info("Checking for signs of life in I2P directory: " + i2p);
return i2p;
}
/**
* get the path to the java home, for jpackage this is related to the
* executable itself, which is handy to know. It's a directory called runtime,
* relative to the root of the app-image on each platform:
*
* Windows - Root of appimage is 1 directory above directory named runtime
* ./runtime
*
* Linux - Root of appimage is 2 directories above directory named runtime
* ./lib/runtime
*
* Mac OSX - Unknown for now
*
* @return
*/
protected File javaHome() {
File jrehome = new File(System.getProperty("java.home"));
if (jrehome != null) {
if (jrehome.exists()) {
return jrehome;
}
}
return null;
}
/**
* get the path to the root of the app-image root by getting the path to
* java.home and the OS, and traversing up to the app-image root based on that
* information.
*
* @return the app-image root
*/
protected File appImageHome() {
File jreHome = javaHome();
if (jreHome != null) {
switch (osName()) {
case "windows":
return jreHome.getAbsoluteFile().getParentFile();
case "mac":
case "linux":
return jreHome.getAbsoluteFile().getParentFile().getParentFile();
}
}
return null;
}
/**
* get the path to the binary of the app-image root by getting the path to
* java.home and the OS, and traversing up to the app-image root based on that
* information, then getting the binary path on a per-platform basis. The path
* returned will be relative to the root.
*
* @return the app-image root
*/
protected String appImageExe() {
File aih = appImageHome();
if (aih != null) {
switch (osName()) {
case "windows":
return "I2P.exe";
case "mac":
case "linux":
return "./bin/I2P";
}
}
return null;
}
/**
* get the path to the default config of the app-image by getting the path to
* java.home and the OS, and traversing up to the app-image root based on that
* information, then appending the config directory to the end onn a
* per-platform basis
*
* @return the app-image root
*/
protected File appImageConfig() {
File aih = appImageHome();
if (aih == null) {
return null;
}
String osName = osName();
switch (osName) {
case "windows":
File winConfigDir = new File(aih, "config");
if (winConfigDir != null) {
if (winConfigDir.exists()) {
return winConfigDir;
}
}
case "mac":
case "linux":
File linConfigDir = new File(aih, "lib/config");
if (linConfigDir != null) {
if (linConfigDir.exists()) {
return linConfigDir;
}
}
}
return null;
}
protected boolean copyConfigDir() {
File appImageConfigDir = appImageConfig();
File appImageHomeDir = selectHome();
return copyConfigDirectory(appImageConfigDir, appImageHomeDir);
}
protected String routerConfig() {
File appImageHomeDir = selectHome();
File routerConf = new File(appImageHomeDir, "router.config");
if (routerConf != null) {
if (routerConf.exists()) {
return routerConf.getAbsolutePath();
}
}
return null;
}
/**
* set up the path to the log file
*

View File

@ -5,18 +5,14 @@ import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import net.i2p.app.ClientAppManager;
import net.i2p.crypto.*;
//import net.i2p.i2pfirefox.*;
import net.i2p.router.Router;
import net.i2p.router.RouterLaunch;
import net.i2p.update.*;
import net.i2p.update.UpdateManager;
import net.i2p.update.UpdatePostProcessor;
import net.i2p.update.UpdateType.*;
import net.i2p.util.Log;
/**
* Launches a router from %WORKINGDIR%/I2P using configuration data in
@ -28,14 +24,20 @@ import net.i2p.update.UpdateType.*;
* appdata
* router.pid - the pid of the java process.
*/
public class WinLauncher extends CopyConfigDir {
public class WinLauncher extends WindowsAppUtil {
private final CopyConfigDir copyConfigDir;
WindowsUpdatePostProcessor wupp = null;
private Router i2pRouter;
private final Log logger;
public WinLauncher() {
i2pRouter = new Router(routerConfig(), System.getProperties());
copyConfigDir = new CopyConfigDir(i2pRouter.getContext());
logger = i2pRouter.getContext().logManager().getLog(WinLauncher.class);
}
public static void main(String[] args) {
var launcher = new WinLauncher();
launcher.setupLauncher();
launcher.initLogger();
int proxyTimeoutTime = 200;
ArrayList<String> newArgsList = new ArrayList<String>();
@ -101,25 +103,23 @@ public class WinLauncher extends CopyConfigDir {
launcher.logger.info("\t" + System.getProperty("router.pid"));
boolean continuerunning = launcher.promptServiceStartIfAvailable("i2p");
if (!continuerunning) {
launcher.logger.severe(
launcher.logger.error(
"Service startup failure, please start I2P service with services.msc");
System.exit(2);
}
continuerunning = launcher.promptUserInstallStartIfAvailable();
if (!continuerunning) {
launcher.logger.severe("User-install startup required.");
launcher.logger.error("User-install startup required.");
System.exit(2);
}
// This actually does most of what we use NSIS for if NSIS hasn't
// already done it, which essentially makes this whole thing portable.
if (!launcher.copyConfigDir()) {
launcher.logger.severe("Cannot copy the configuration directory");
if (!launcher.copyConfigDir.copyConfigDir()) {
launcher.logger.error("Cannot copy the configuration directory");
System.exit(1);
}
launcher.i2pRouter =
new Router(launcher.routerConfig(), System.getProperties());
if (!launcher.isInstalled("i2p")) {
if (launcher.i2pRouter.saveConfig("routerconsole.browser", null)) {
launcher.logger.info("removed routerconsole.browser config");
@ -138,8 +138,6 @@ public class WinLauncher extends CopyConfigDir {
registrationThread.setDaemon(true);
registrationThread.start();
launcher.setNotStarting();
launcher.i2pRouter.runRouter();
}
@ -155,7 +153,7 @@ public class WinLauncher extends CopyConfigDir {
if (!programs.exists())
programs.mkdirs();
else if (!programs.isDirectory()) {
logger.warning(
logger.warn(
programs +
" exists but is not a directory. Please get it out of the way");
System.exit(1);
@ -168,7 +166,7 @@ public class WinLauncher extends CopyConfigDir {
if (!home.exists())
home.mkdirs();
else if (!home.isDirectory()) {
logger.warning(
logger.warn(
home +
" exists but is not a directory. Please get it out of the way");
System.exit(1);
@ -188,93 +186,6 @@ public class WinLauncher extends CopyConfigDir {
return portFree;
}
private boolean i2pIsRunningCheck() {
// check if there's something listening on port 7657(Router Console)
if (!isAvailable(7657))
return true;
// check if there's something listening on port 7654(I2CP)
if (!isAvailable(7654))
return true;
if (checkPing())
return true;
return false;
}
private void setNotStarting() {
logger.info("removing startup file, the application has started");
File home = selectHome();
File starting = new File(home, "starting");
if (starting.exists()) {
starting.delete();
}
}
private void setStarting() {
logger.info("creating startup file, router is starting up");
File home = selectHome();
File starting = new File(home, "starting");
if (!starting.exists()) {
try {
starting.createNewFile();
} catch (IOException e) {
logger.info(e.toString());
}
}
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
setNotStarting();
}
});
}
private boolean checkStarting() {
logger.info("checking startup file");
File home = selectHome();
File starting = new File(home, "starting");
if (starting.exists()) {
logger.info("startup file exists, I2P is already starting up");
return true;
}
logger.info("startup file does not exist but we're running now");
setStarting();
return false;
}
// check for the existence of router.ping file, if it's less then 2
// minutes old, exit
private boolean checkPing() {
File home = selectHome();
File ping = new File(home, "router.ping");
if (ping.exists()) {
long diff = System.currentTimeMillis() - ping.lastModified();
if (diff > 60 * 1000) {
logger.info(
"router.ping exists and is more than 1 minute old, I2P does not appear to be running.");
logger.info("If I2P is running, report this as a bug.");
return false;
} else {
return true;
}
}
return false;
}
private boolean i2pIsRunning() {
if (checkStarting())
return true;
if (checkPing())
return true;
if (i2pIsRunningCheck())
return true;
for (int i = 0; i < 10; i++) {
if (i2pIsRunningCheck())
return true;
sleep(1000);
}
return false;
}
private final Runnable REGISTER_UPP = () -> {
RouterContext ctx;
while ((ctx = i2pRouter.getContext()) == null) {

View File

@ -0,0 +1,149 @@
package net.i2p.router;
import java.io.File;
import net.i2p.util.Log;
public class WindowsAppUtil extends WindowsServiceUtil {
protected File selectHome() { // throws Exception {
String path_override = System.getenv("I2P_CONFIG");
if (path_override != null) {
File path = new File(path_override);
if (path != null && path.exists()) {
if (path.isDirectory())
return path.getAbsoluteFile();
else
throw new RuntimeException("I2P_CONFIG is not a directory: " + path);
}
}
File i2p = appImageHome();
return i2p;
}
protected File selectProgramFile() {
String path_override = System.getenv("I2P");
if (path_override != null) {
File path = new File(path_override);
if (path.exists()) {
if (path.isDirectory())
return path.getAbsoluteFile();
else
throw new RuntimeException("I2P is not a directory: " + path);
}
}
File i2p = appImageHome();
return i2p;
}
/**
* get the path to the java home, for jpackage this is related to the
* executable itself, which is handy to know. It's a directory called runtime,
* relative to the root of the app-image on each platform:
*
* Windows - Root of appimage is 1 directory above directory named runtime
* ./runtime
*
* Linux - Root of appimage is 2 directories above directory named runtime
* ./lib/runtime
*
* Mac OSX - Unknown for now
*
* @return
*/
protected File javaHome() {
File jrehome = new File(System.getProperty("java.home"));
if (jrehome != null) {
if (jrehome.exists()) {
return jrehome;
}
}
return null;
}
/**
* get the path to the root of the app-image root by getting the path to
* java.home and the OS, and traversing up to the app-image root based on that
* information.
*
* @return the app-image root
*/
protected File appImageHome() {
File jreHome = javaHome();
if (jreHome != null) {
switch (osName()) {
case "windows":
return jreHome.getAbsoluteFile().getParentFile();
case "mac":
case "linux":
return jreHome.getAbsoluteFile().getParentFile().getParentFile();
}
}
return null;
}
/**
* get the path to the binary of the app-image root by getting the path to
* java.home and the OS, and traversing up to the app-image root based on that
* information, then getting the binary path on a per-platform basis. The path
* returned will be relative to the root.
*
* @return the app-image root
*/
protected String appImageExe() {
File aih = appImageHome();
if (aih != null) {
switch (osName()) {
case "windows":
return "I2P.exe";
case "mac":
case "linux":
return "./bin/I2P";
}
}
return null;
}
/**
* get the path to the default config of the app-image by getting the path to
* java.home and the OS, and traversing up to the app-image root based on that
* information, then appending the config directory to the end onn a
* per-platform basis
*
* @return the app-image root
*/
protected File appImageConfig() {
File aih = appImageHome();
if (aih == null) {
return null;
}
String osName = osName();
switch (osName) {
case "windows":
File winConfigDir = new File(aih, "config");
if (winConfigDir != null) {
if (winConfigDir.exists()) {
return winConfigDir;
}
}
case "mac":
case "linux":
File linConfigDir = new File(aih, "lib/config");
if (linConfigDir != null) {
if (linConfigDir.exists()) {
return linConfigDir;
}
}
}
return null;
}
protected String routerConfig() {
File appImageHomeDir = selectHome();
File routerConf = new File(appImageHomeDir, "router.config");
if (routerConf != null) {
if (routerConf.exists()) {
return routerConf.getAbsolutePath();
}
}
return null;
}
}