main.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include <iostream>
  2. #include <sys/stat.h>
  3. #include "httpserver/http-server.h"
  4. #include "utils/utils.h"
  5. #include "processor/processor.h"
  6. #include "fs.hpp"
  7. #include "thirdparty/sha256.hpp"
  8. #include "frp.h"
  9. using namespace xc;
  10. using namespace xc::httpserver;
  11. using namespace xc::processor;
  12. const static strcmd reg("reg", "reg <User> <Pwd>", "注册用户", 2, [] (auto args) {
  13. INI ini;
  14. ini.getMust("info")->set("password", sha256(args[1] + conf::userPasswordSalt));
  15. saveTextFile(conf::getUserDataDir() + "/" + args[0], ini.getINIString());
  16. cout << "成功创建用户 " << args[0] << endl;
  17. });
  18. const static strcmd createFrp("frp", "frp <Name> <Server-Addr> <Server-Port> <Token>", "创建Frpc配置文件", 4, [] (auto args) {
  19. frp::addProfile(args[0], args[1], args[2], args[3]);
  20. cout << "成功创建Frpc配置文件 " << args[0] << endl;
  21. });
  22. const static strcmd assign("assign", "assign <UserName> <Profile>", "使用户有权访问配置文件", 2, [] (auto args) {
  23. frp::ProfileInfo profile(args[1]);
  24. profile.addUser(args[0]);
  25. profile.save();
  26. cout << "成功将配置文件 " << args[1] << " 绑定到用户 " << args[0] << endl;
  27. });
  28. int call_shell(string cmd) {
  29. cout << "$ " << cmd << endl;
  30. ::system(cmd.c_str());
  31. }
  32. const static strcmd install("install", "install", "安装", 0, [] (auto args) {
  33. uid_t uid = getuid();
  34. if (setuid(0)) {
  35. cerr << "安装失败,无法获取root权限。" << endl;
  36. return;
  37. }
  38. char selfPath[1024];
  39. int len;
  40. if ((len = readlink("/proc/self/exe", selfPath, sizeof(selfPath))) <= 0) {
  41. cerr << "安装失败,无法获取自身位置。" << endl;
  42. return;
  43. }
  44. selfPath[len] = 0;
  45. string programPath(selfPath);
  46. replace_all(programPath, " ", "\\ ");
  47. string cpCmd = "cp " + programPath + " /usr/local/bin/fpw";
  48. if (call_shell(cpCmd)) {
  49. cerr << "安装失败,无法将自身拷贝到 /usr/local/bin/fpw。" << endl;
  50. return;
  51. }
  52. cout << "$ vi /usr/lib/systemd/system/fpw.service" << endl;
  53. INIFile systemd("/usr/lib/systemd/system/fpw.service");
  54. systemd.getMust("Unit")->set("Description", "FRPCWebUI Daemon");
  55. systemd.getMust("Unit")->set("After", "network.target");
  56. systemd.getMust("Service")->set("Type", "Simple");
  57. systemd.getMust("Service")->set("User", "root");
  58. systemd.getMust("Service")->set("Restart", "on-failure");
  59. systemd.getMust("Service")->set("RestartSec", "1s");
  60. systemd.getMust("Service")->set("ExecStart", "fpw");
  61. systemd.getMust("Service")->set("LimitNOFILE", "1048576");
  62. systemd.getMust("Install")->set("WantedBy", "multi-user.target");
  63. systemd.save();
  64. if (call_shell("systemctl daemon-reload")) {
  65. cerr << "安装失败,无法调用systemctl。" << endl;
  66. return;
  67. }
  68. if (call_shell("systemctl enable fpw")) {
  69. cerr << "安装失败,无法调用systemctl。" << endl;
  70. return;
  71. }
  72. if (call_shell("systemctl start fpw")) {
  73. cerr << "安装失败,无法调用systemctl。" << endl;
  74. return;
  75. }
  76. setuid(uid);
  77. cout << "安装成功。" << endl;
  78. });
  79. namespace xc::conf {
  80. string userJWTSecret;
  81. }
  82. int main(int argc, char **argv) {
  83. conf::userJWTSecret = create_uuid();
  84. std::cout << "FRPC WebUI HelloWorld!" << std::endl;
  85. CommandLineWorker cmdLine;
  86. conf::getRootDir();
  87. conf::getUserDataDir();
  88. conf::getFrpcDir();
  89. if (argc > 1) {
  90. ostringstream cmd;
  91. for (int i = 1; i < argc; i++) {
  92. cmd << argv[i];
  93. cmd << " ";
  94. }
  95. cmdLine.processCommand(cmd.str());
  96. return 0;
  97. }
  98. ostringstream oss;
  99. oss << "ps -ef | grep " << argv[0] << " | grep -v grep";
  100. ::FILE *psStdoutFd = popen(oss.str().c_str(), "r");
  101. ostringstream w_oss;
  102. while (true) {
  103. int ch = ::fgetc(psStdoutFd);
  104. if (ch == -1) break;
  105. w_oss << (char) ch;
  106. }
  107. ::pclose(psStdoutFd);
  108. if (utils::split(w_oss.str(), "\n").size() > 1) {
  109. cerr << "FrpcWebUI只能运行一个进程,您已启动了多个。" << endl;
  110. return -1;
  111. }
  112. if (fs::contentsOfDirectory(conf::getUserDataDir()).empty()) {
  113. cout << "看起来您没有设置任何一个账号,您可以输入 reg <账号> <密码> 来注册。" << endl;
  114. }
  115. HTTPServer server(8192);
  116. thread([&server] { server.serverLoop(); }).detach();
  117. RequestProcessWorker worker;
  118. thread([&worker] { worker.workerLoop(); }).detach();
  119. thread([] { frp::frpDaemon(); }).detach();
  120. cmdLine.workerLoop();
  121. while (true) {
  122. sleep(1);
  123. }
  124. }