257 lines
7.2 KiB
Go
257 lines
7.2 KiB
Go
package checki2p
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"os/user"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/eyedeekay/go-i2cp"
|
|
)
|
|
|
|
func inithome(str string) string {
|
|
s, e := os.UserHomeDir()
|
|
if e != nil {
|
|
panic(e)
|
|
}
|
|
return s + str
|
|
}
|
|
|
|
func checkfileexists(path string) bool {
|
|
if _, err := os.Stat(path); err == nil {
|
|
return true
|
|
} else if os.IsNotExist(err) {
|
|
return false
|
|
}
|
|
return false
|
|
}
|
|
|
|
func home() string {
|
|
if runtime.GOOS == "windows" {
|
|
return "\\i2p"
|
|
} else if runtime.GOOS == "darwin" {
|
|
return "/Library/Application Support/i2p"
|
|
}
|
|
return "/.i2p"
|
|
}
|
|
|
|
var (
|
|
// I2CP_HOST is the i2cp host
|
|
I2CP_HOST string
|
|
// I2CP_PORT is the i2cp port
|
|
I2CP_PORT string
|
|
// WINDOWS_DEFAULT_LOCATION
|
|
WINDOWS_DEFAULT_LOCATION string = `C:\\Program Files\i2p\i2psvc.exe`
|
|
// I2PD_WINDOWS_DEFAULT_LOCATION
|
|
I2PD_WINDOWS_DEFAULT_LOCATION string = `C:\\Program Files\I2Pd\i2pd.exe`
|
|
// LINUX_SYSTEM_LOCATION
|
|
LINUX_SYSTEM_LOCATION []string = []string{"/usr/bin/i2prouter", "/usr/sbin/i2prouter"}
|
|
// I2PD_LINUX_SYSTEM_LOCATION
|
|
I2PD_LINUX_SYSTEM_LOCATION string = "/usr/sbin/i2pd"
|
|
// I2P_ASUSER_HOME_LOCATION This is the path to the default I2P config directory when running as a user
|
|
I2P_ASUSER_HOME_LOCATION string = inithome(home())
|
|
// HOME_DIRECTORY_LOCATION can use config/run from a user's $HOME directory, this is the path to that router
|
|
HOME_DIRECTORY_LOCATION string = inithome("/i2p/i2prouter")
|
|
// OSX_DEFAULT_LOCATION
|
|
OSX_DEFAULT_LOCATION string = inithome("/Library/Application Support/i2p/clients.config")
|
|
)
|
|
|
|
func i2pdArgs() ([]string, error) {
|
|
return []string{""}, nil
|
|
}
|
|
|
|
// CheckI2PIsRunning is frequently the only thing I need a reliable, non-SAM
|
|
// way to test at runtime.
|
|
func CheckI2PIsRunning() (bool, error) {
|
|
client := go_i2cp.NewClient(nil)
|
|
err := client.Connect()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
destination, err := go_i2cp.NewDestination()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if destination == nil {
|
|
return false, fmt.Errorf("")
|
|
}
|
|
client.Disconnect()
|
|
return true, nil
|
|
}
|
|
|
|
// CheckI2PIsInstalledDefaultLocation looks in various locations for the
|
|
// presence of an I2P router.
|
|
func CheckI2PIsInstalledDefaultLocation() (bool, error) {
|
|
if checkfileexists(I2PD_WINDOWS_DEFAULT_LOCATION) {
|
|
log.Println("Windows i2pd router detected")
|
|
return true, nil
|
|
}
|
|
if checkfileexists(I2PD_LINUX_SYSTEM_LOCATION) {
|
|
log.Println("Linux i2pd router detected")
|
|
return true, nil
|
|
}
|
|
if checkfileexists(WINDOWS_DEFAULT_LOCATION) {
|
|
log.Println("Windows i2p router detected")
|
|
return true, nil
|
|
}
|
|
if checkfileexists(LINUX_SYSTEM_LOCATION[0]) {
|
|
log.Println("Linux i2p router detected")
|
|
return true, nil
|
|
}
|
|
if checkfileexists(LINUX_SYSTEM_LOCATION[1]) {
|
|
log.Println("Linux i2p router detected")
|
|
return true, nil
|
|
}
|
|
if checkfileexists(HOME_DIRECTORY_LOCATION) {
|
|
log.Println("Linux i2p router detected")
|
|
return true, nil
|
|
}
|
|
if checkfileexists(OSX_DEFAULT_LOCATION) {
|
|
log.Println("OSX i2p router detected")
|
|
return true, nil
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
// UserFind makes sure that we never mis-identify the user account because of
|
|
// sudo
|
|
func UserFind() string {
|
|
if os.Geteuid() == 0 {
|
|
str := os.Getenv("SUDO_USER")
|
|
return str
|
|
}
|
|
if un, err := user.Current(); err == nil {
|
|
return un.Name
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// CheckI2PUserName looks in various locations for the
|
|
// presence of an I2P router and guesses the username it
|
|
// should run under. On Windows it returns the EXE name.
|
|
func CheckI2PUserName() (string, error) {
|
|
if checkfileexists(I2PD_WINDOWS_DEFAULT_LOCATION) {
|
|
log.Println("Windows i2pd router detected")
|
|
return "i2pd", nil
|
|
}
|
|
if checkfileexists(I2PD_LINUX_SYSTEM_LOCATION) {
|
|
log.Println("Linux i2pd router detected")
|
|
return "i2pd", nil
|
|
}
|
|
if checkfileexists(WINDOWS_DEFAULT_LOCATION) {
|
|
log.Println("Windows i2p router detected")
|
|
return "i2psvc", nil
|
|
}
|
|
if checkfileexists(LINUX_SYSTEM_LOCATION[0]) {
|
|
log.Println("Linux i2p router detected")
|
|
return "i2psvc", nil
|
|
}
|
|
if checkfileexists(LINUX_SYSTEM_LOCATION[1]) {
|
|
log.Println("Linux i2p router detected")
|
|
return "i2psvc", nil
|
|
}
|
|
if checkfileexists(HOME_DIRECTORY_LOCATION) {
|
|
log.Println("Linux i2p router detected")
|
|
return UserFind(), nil
|
|
}
|
|
if checkfileexists(OSX_DEFAULT_LOCATION) {
|
|
log.Println("OSX i2p router detected")
|
|
return UserFind(), nil
|
|
}
|
|
return "", nil
|
|
}
|
|
|
|
// GetFirewallPort finds the configured UDP port of your I2P router to help
|
|
// configure firewalls. It does this by finding the router.config and reading
|
|
// it. This function will not work on I2Pd routers yet but it should be easy
|
|
// to add support once I get some more time to test and research it.
|
|
func GetFirewallPort() (string, error) {
|
|
log.Println(I2P_ASUSER_HOME_LOCATION)
|
|
file, err := ioutil.ReadFile(I2P_ASUSER_HOME_LOCATION + "/router.config")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
lines := strings.Split(string(file), "\n")
|
|
for index, line := range lines {
|
|
if strings.HasPrefix(line, "i2np.udp.port") {
|
|
log.Println(line, index)
|
|
return strings.Replace(line, "i2np.udp.port=", "", -1), nil
|
|
}
|
|
}
|
|
return "", fmt.Errorf("Improperly formed router.config file")
|
|
}
|
|
|
|
// FindI2PIsInstalledDefaultLocation looks in various locations for the
|
|
// presence of an I2P router, reporting back the location
|
|
func FindI2PIsInstalledDefaultLocation() (string, error) {
|
|
if checkfileexists(I2PD_WINDOWS_DEFAULT_LOCATION) {
|
|
log.Println("Windows i2pd router detected")
|
|
return I2PD_WINDOWS_DEFAULT_LOCATION, nil
|
|
}
|
|
if checkfileexists(I2PD_LINUX_SYSTEM_LOCATION) {
|
|
log.Println("Linux i2pd router detected")
|
|
return I2PD_LINUX_SYSTEM_LOCATION, nil
|
|
}
|
|
if checkfileexists(WINDOWS_DEFAULT_LOCATION) {
|
|
log.Println("Windows i2p router detected")
|
|
return WINDOWS_DEFAULT_LOCATION, nil
|
|
}
|
|
if checkfileexists(LINUX_SYSTEM_LOCATION[0]) {
|
|
log.Println("Linux i2p router detected")
|
|
return LINUX_SYSTEM_LOCATION[0], nil
|
|
}
|
|
if checkfileexists(LINUX_SYSTEM_LOCATION[1]) {
|
|
log.Println("Linux i2p router detected")
|
|
return LINUX_SYSTEM_LOCATION[1], nil
|
|
}
|
|
if checkfileexists(HOME_DIRECTORY_LOCATION) {
|
|
log.Println("Linux i2p router detected")
|
|
return HOME_DIRECTORY_LOCATION, nil
|
|
}
|
|
if checkfileexists(OSX_DEFAULT_LOCATION) {
|
|
log.Println("OSX i2p router detected")
|
|
return OSX_DEFAULT_LOCATION, nil
|
|
}
|
|
return "", fmt.Errorf("i2p router not found.")
|
|
}
|
|
|
|
// ConditionallyLaunchI2P If an already-installed I2P router is present, then
|
|
// make sure that it is started, i.e. launch the router *only* if it is not
|
|
// already running.
|
|
func ConditionallyLaunchI2P() (bool, error) {
|
|
ok, err := CheckI2PIsInstalledDefaultLocation()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if ok {
|
|
ok, err := CheckI2PIsRunning()
|
|
if err == nil {
|
|
if !ok {
|
|
path, err := FindI2PIsInstalledDefaultLocation()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if strings.HasSuffix(path, "i2prouter") {
|
|
cmd := exec.Command(path, "start")
|
|
if err := cmd.Start(); err != nil {
|
|
return false, fmt.Errorf("I2P router startup failure %s", err)
|
|
}
|
|
} else {
|
|
cmd := exec.Command(path, "--daemon")
|
|
if err := cmd.Start(); err != nil {
|
|
return false, fmt.Errorf("I2P router startup failure %s", err)
|
|
}
|
|
}
|
|
return true, nil
|
|
}
|
|
return true, nil
|
|
}
|
|
return false, err
|
|
}
|
|
return false, fmt.Errorf("I2P is not a default location, please set $I2P environment variable")
|
|
}
|