diff --git a/Makefile b/Makefile index 818ea36..6af1fe0 100755 --- a/Makefile +++ b/Makefile @@ -45,9 +45,13 @@ else endif -all: $(I2PD_LIB) vain keygen keyinfo famtool routerinfo regaddr regaddr_3ld i2pbase64 offlinekeys b33address regaddralias x25519 verifyhost +all: $(I2PD_LIB) vain keygen keyinfo famtool routerinfo regaddr regaddr_3ld i2pbase64 offlinekeys b33address regaddralias x25519 verifyhost autoconf vain: vain.o $(I2PD_LIB) $(CXX) -o vain $(LDFLAGS) vain.o $(LDLIBS) + +autoconf: autoconf.o $(I2PD_LIB) + $(CXX) -o autoconf $(DEFINES) $(LDFLAGS) autoconf.o $(LDLIBS) + routerinfo: routerinfo.o $(I2PD_LIB) $(CXX) -o routerinfo $(LDFLAGS) routerinfo.o $(LDLIBS) -latomic @@ -103,7 +107,7 @@ clean-obj: rm -f $(wildcard *.o) clean-bin: - rm -f b33address famtool i2pbase64 keygen keyinfo offlinekeys regaddr regaddr_3ld regaddralias routerinfo x25519 verifyhost vain + rm -f b33address famtool i2pbase64 keygen keyinfo offlinekeys regaddr regaddr_3ld regaddralias routerinfo x25519 verifyhost vain autoconf clean: clean-i2pd clean-obj clean-bin diff --git a/README.md b/README.md index f9e2172..e5921ee 100755 --- a/README.md +++ b/README.md @@ -188,3 +188,9 @@ verify signed router.info xLSOIwih0Jx3JObPRCBJexYOpPYJsEwQ1A== -----END EC PRIVATE KEY----- +#### AutoConf +A program for help create the config file for i2pd + +For a now a better way to manual write the config file + +For usage just run ./AutoConf or AutoConf.exe diff --git a/autoconf.cpp b/autoconf.cpp new file mode 100644 index 0000000..c687ab5 --- /dev/null +++ b/autoconf.cpp @@ -0,0 +1,248 @@ +#ifndef AUTOCONFC +#define AUTOCONFC +#include +#include +#include +#include +#include +#include +#include + +#define CIN_CLEAR std::cin.clear(); std::cin.ignore(std::numeric_limits::max(), '\n'); +#define HTTP_SUPPORTS_LANGUAGE "german, italian, polish, portuguese, russian, spanish, turkish, turkmen, ukrainian, uzbek" +namespace AutoConf { + // + namespace Regexps { + //const std::regex port("\\d{1,5}"); + std::regex path(R"([a-zA-Z0-9_\.\/\\]+)"); // (\w|\.|\\|\/)+ + //std::regex proxy("\\w+:\\/\\/(\\w|\\d|\\.|\\-)+\\:\\d+"); + std::regex any(".*"); + + } +namespace PreInitConfigs { + constexpr const char * yggOnlyConf = "ipv4=false\r\n" + "ipv6=false\r\n" + "ssu=false\r\n" + "ntcp2.enabled=false\r\n" + "ssu2.enabled=false\r\n" + "meshnets.yggdrasil=true\r\n"; +} + +// Texts +using AsksT = std::map; +const std::map Texts = // maybe vector better + { + {"ru", { + {"WelcomeText","Привет. Выбери тип конфига\r\n1 - клирнет\r\n2 - только yggdrasil"}, + // Without section + {"TunConfYN", "Использовать другой путь для туннелей?"}, + {"TunConf", "Введите путь для туннелей"}, + {"TunnelsDirYN", "Использовать другой путь для папки туннелей?"}, + {"TunnelsDir","Введите путь для папки с туннелями"}, + {"certsdirYN", "Использовать другой путь для папки с сертификатами?"}, + {"certsdir", "Введите путь для папки с сертификатами"}, + {"pidfileYN","использовать другой путь для PID файла?"}, + {"pidfile", "Введите путь для pidfile"}, + {"logYN","Нужно ли изменить путь лога?"}, + {"log", "Введите тип лога(file,stdout,syslog)"}, + {"logfileYN","Нужно ли изменить путь logfile?"}, + {"logfile", "Введите путь logfile"}, + {"loglevelYN","Нужно ли изменить стандартный уровень логирования?"}, + {"loglevel","Введите уровень лога(warn,info,none,critical,error,debug)"}, + {"logCFLYN", "Использовать полный CFL-форму даты в логах? ПО умолчанию только время"}, + {"daemonYN", "Использовать режим демона?"}, + {"FamilyUsing", "Введите название фамилии или -"}, + //TODO: an another + {"UseIPv6", "Использовать ipv6?"}, + {"UseIPv4", "Использовать ipv4?"}, + {"BeFloodfillYN", "Быть флудфиллом?"}, + {"NoTransitYN", "Отключить транзит? (это уменьшит анонимность)"}, + {"Bandwidth", "Напиши пропускную способность (- для по умолчанию) [L-32kbs,O-256kbs,P-2048kbs,X-unlimited]"}, + {"Share", "Процент шары (- для по умолчанию) [0-100]"}, + // + {"NTCPEnabledYN", "Использовать NTCP?"}, + {"NTCPPublishedYN", "Опубликовать IP В NTCP?"}, + {"NTCPPPort", "NTCP Порт. Либо - для пропуска"}, + {"NTCPPProxy", "NTCP Proxy, пример (socks://localhost:4545) или - для по умолчанию (неиспользуется)"}, + {"SSUEnabledYN", "Использовать SSU?"}, + {"SSUPPort", "SSU Порт. Либо - для пропуска"}, + {"SSUProxy", "SSU Proxy, пример (socks://localhost:4545) или - для по умолчанию (неиспользуется)"}, + {"HTTPLang", "Выбрите язык веб-интерфейса, либо - для опции по умолчанию (" HTTP_SUPPORTS_LANGUAGE ")" } + }}, + {"en", { + {"WelcomeText","Hello. Select type of config\r\n1 - clearnet\r\n2 - only yggdrasil"}, + {"TunConfYN", "Use a different path for tunnels?"}, + {"TunConf", "Enter path for tunnels"}, + {"TunnelsDirYN", "Use a different path for the tunnels folder?"}, + {"TunnelsDir", "Enter path for the tunnels folder"}, + {"certsdirYN", "Use a different path for the certificates folder?"}, + {"certsdir", "Enter path for the certificates folder"}, + {"pidfileYN", "Use a different path for the PID file?"}, + {"pidfile", "Enter path for pidfile"}, + {"logYN", "Do you need to change the log path?"}, + {"log", "Enter log type (file, stdout, syslog)"}, + {"logfileYN", "Do you need to change the logfile path?"}, + {"logfile", "Enter path for logfile"}, + {"loglevelYN", "Do you need to change the default log level?"}, + {"loglevel", "Enter log level (warn, info, none, critical, error, debug)"}, + {"logCFLYN", "Use full CFL format for date in logs? Default is only time."}, + {"daemonYN", "Use daemon mode?"}, + {"FamilyUsing", "Enter your netfamily or just hit -."}, + //TODO: an another + {"UseIPv6", "Use ipv6?"}, + {"UseIPv4", "Use ipv4?"}, + {"BeFloodfillYN", "Be a floodfill?"}, + {"NoTransitYN", "Disable transit? (this will reduce anonymity)"}, + {"Bandwidth", "Write bandwidth (- for default) [L-32kbs,O-256kbs,P-2048kbs,X-unlimited]"}, + {"Share", "Share percents (- for default) [0-100]"}, + {"HTTPLang", "Select Web-interface language or - for default (" HTTP_SUPPORTS_LANGUAGE ")" }, + // + {"NTCPEnabledYN", "Use NTCP?"}, + {"NTCPPublishedYN", "Publish IP in NTCP?"}, + {"NTCPPPort", "NTCP Port or - for auto port (random)"}, + {"NTCPPProxy", "NTCP Proxy, example (socks://localhost:4545) or - for default"}, + {"SSUEnabledYN", "Use SSU?"}, + {"SSUPPort", "SSU Port or - for auto port (random)"}, + {"SSUProxy", "SSU Proxy, example (socks://localhost:4545) or - for default"} + + }} + }; + +// Functions +bool AskYN(void) noexcept { + char answ; + std::cout << " ? (y/n) "; + std::cin >> answ; + CIN_CLEAR; + switch(answ) { + case 'y': + case 'Y': + return true; + case 'n': + case 'N': + return false; + default: + return AskYN(); // stack overflow, would use while(true) + } +} +std::string GetLanguage(void) noexcept { + std::string lang; + std::cout << "Language/Язык:\r\nru - русский\r\nen - английский\r\n"; + std::cin >> lang; + CIN_CLEAR; + if (Texts.find(lang) != Texts.end()) { + return lang; + } else { + std::cerr << "Not correct language, try again" << std::endl; + return GetLanguage(); // stack overflow + } +} + +bool IsOnlyYggdrasil(const std::string & lang) noexcept { + unsigned short answ; + std::cout << AutoConf::Texts.at(lang).at("WelcomeText") << std::endl; + std::cin >> answ; + CIN_CLEAR; + switch(answ) { + case 1: + return false; + case 2: + return true; + default: + return IsOnlyYggdrasil(lang); + } +} + +} + +int +main(void) { + std::cout << "https://i2pd.readthedocs.io/en/latest/user-guide/configuration/\r\nhttps://github.com/PurpleI2P/i2pd/blob/openssl/contrib/i2pd.conf\r\n"; + std::ostringstream conf; + auto lang = AutoConf::GetLanguage(); + auto isOnlyYgg = AutoConf::IsOnlyYggdrasil(lang); + if (isOnlyYgg) { + #ifndef _WIN32 + conf << "daemon=true\r\n"; + #endif + conf << AutoConf::PreInitConfigs::yggOnlyConf; + } else { + // Asks + using namespace AutoConf; + [](std::ostringstream &conf, const std::string &lang) { + #define ASKYN_MACRO(A,B,C, REGEX) { \ + std::cout << AutoConf::Texts.at(lang).at(A); \ + if(AskYN()) { \ + while(1) {\ + std::cout << AutoConf::Texts.at(lang).at(B) << "\r\n"; \ + std::string inp; \ + std::cin >> inp;\ + CIN_CLEAR; \ + std::smatch bmatch;\ + std::regex_match(inp, bmatch, REGEX);\ + if (bmatch.length() > 0) {\ + conf << C "=" << inp << "\r\n"; \ + break;\ + }else {std::cerr<<"No correct input"<> inp;CIN_CLEAR; if (inp != "-") {\ + conf << B "=" << inp << "\r\n";\ + }\ + } + ASK_TEXT("FamilyUsing","family"); + ASK_BOOL("BeFloodfillYN", "floodfill"); + ASK_BOOL("NoTransitYN", "notransit"); + ASK_TEXT("Bandwidth","bandwidth"); + ASK_TEXT("Share","share"); + ///// With sections + conf << "[ntcp2]\r\n"; + ASK_BOOL("NTCPEnabledYN", "enabled"); + ASK_BOOL("NTCPPublishedYN", "published"); + ASK_TEXT("NTCPPPort", "port"); + ASK_TEXT("NTCPPProxy", "proxy"); + conf << "[ssu2]\r\n"; + ASK_BOOL("SSUEnabledYN", "enabled"); + ASK_TEXT("SSUPPort", "port"); + ASK_TEXT("SSUProxy", "proxy"); + conf << "[http]\r\n"; + ASK_TEXT("HTTPLang", "lang"); + #undef ASK_TEXT + #undef ASK_BOOL + #undef ASKYN_MACRO + + }(conf, lang); + } + std::cout << "Config: " << std::endl; + std::cout << conf.str() << std::endl; + //TODO: To Constexpr + std::cout << "Save File: (\"i2pd_.conf\"):"; + std::string outFileName; + std::cin.clear(); + std::getline(std::cin, outFileName); + //TODO: to constxpr + if (outFileName.length() == 0) outFileName = "i2pd_.conf"; + std::ofstream confFile(outFileName); + confFile << conf.str(); + confFile.close(); +} +#endif