summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/poison.hpp1
-rw-r--r--src/tool/eathena-monitor.cpp204
2 files changed, 87 insertions, 118 deletions
diff --git a/src/poison.hpp b/src/poison.hpp
index 282d04d..d196bc6 100644
--- a/src/poison.hpp
+++ b/src/poison.hpp
@@ -21,4 +21,5 @@
#pragma GCC poison calloc
#pragma GCC poison realloc
#pragma GCC poison free
+#pragma GCC poison strdup
#endif
diff --git a/src/tool/eathena-monitor.cpp b/src/tool/eathena-monitor.cpp
index 30e7184..2a3e117 100644
--- a/src/tool/eathena-monitor.cpp
+++ b/src/tool/eathena-monitor.cpp
@@ -13,9 +13,8 @@
#include <unistd.h>
#include <csignal>
-#include <cstdlib>
-#include <cstring>
-#include <ctime>
+
+#include <fstream>
#include "../common/cxxstdio.hpp"
#include "../common/utils.hpp"
@@ -29,138 +28,80 @@
#define LOGFILE "log/eathena-monitor.log"
-static
-void SKIP_BLANK(char *& ptr)
-{
- while (
- (*ptr == ' ') ||
- (*ptr == '\b') ||
- (*ptr == '\n') ||
- (*ptr == '\r')
- )
- ptr++;
-}
-
-static
-void GOTO_EQL(char *& ptr) {
- while (
- (*ptr != '\0') &&
- (*ptr != '=') &&
- (*ptr != '\n') &&
- (*ptr != '\r')
- )
- ptr++;
-}
-
-static
-void GOTO_EOL(char *& ptr) {
- while (
- (*ptr != '\0') &&
- (*ptr != '\n') &&
- (*ptr != '\r')
- )
- ptr++;
-}
-
// initialiized to $HOME/tmwserver
static
-const char *workdir;
+std::string workdir;
//the rest are relative to workdir
static
-const char *login_server = LOGIN_SERVER;
-static
-const char *map_server = MAP_SERVER;
-static
-const char *char_server = CHAR_SERVER;
+std::string login_server = LOGIN_SERVER;
static
-const char *logfile = LOGFILE;
-// this variable is hard-coded, but the command-line is checked first
+std::string map_server = MAP_SERVER;
static
-const char *config = CONFIG;
+std::string char_server = CHAR_SERVER;
static
pid_t pid_login, pid_map, pid_char;
static
-const char* make_path(const char* base, const char* path) {
- size_t base_len = strlen(base);
- size_t path_len = strlen(path);
- char* out = (char *)malloc(base_len + 1 + path_len + 1);
- memcpy(out, base, base_len);
- out[base_len] = '/';
- memcpy(out + base_len + 1, path, path_len);
- out[base_len + 1 + path_len] = '\0';
+std::string make_path(const std::string& base, const std::string& path)
+{
+ std::string out(base.size() + 1 + path.size(), '\0');
+ std::string::iterator it = std::copy(base.begin(), base.end(), out.begin());
+ *it++ = '/';
+ std::copy(path.begin(), path.end(), it);
return out;
}
static
-void parse_option(char *name, char *value) {
- if (!strcasecmp(name, "login_server")) {
- login_server = strdup(value);
- } else if (!strcasecmp(name, "map_server")) {
- map_server = strdup(value);
- } else if (!strcasecmp(name, "char_server")) {
- char_server = strdup(value);
- } else if (!strcasecmp(name, "workdir")) {
- workdir = strdup(value);
- } else if (!strcasecmp(name, "logfile")) {
- logfile = strdup(value);
- } else {
- FPRINTF(stderr, "WARNING: ingnoring invalid option '%s' = '%s'\n", name, value);
- }
+void parse_option(const std::string& name, const std::string& value)
+{
+ if (name == "login_server")
+ login_server = value;
+ else if (name == "map_server")
+ map_server = value;
+ else if (name == "char_server")
+ char_server = value;
+ else if (name == "workdir")
+ workdir = value;
+ else
+ FPRINTF(stderr, "WARNING: ingnoring invalid option '%s' : '%s'\n", name, value);
}
static
-void read_config(const char *filename) {
- FILE *input;
- char string[1000];
-
- if (!(input = fopen(filename,"r")) && !(input = fopen(config, "r"))) {
- perror("Unable to load config file");
- return;
+void read_config(const std::string& filename)
+{
+ std::ifstream in(filename);
+ if (!in.is_open())
+ {
+ FPRINTF(stderr, "Monitor config file not found: %s\n", filename);
+ exit(1);
}
- while (1) {
- if (fgets(string, sizeof(string) - 1, input) == NULL)
- break;
- char *str = string, *name, *value;
- SKIP_BLANK(str);
- string[sizeof(string) - 1] = '\0';
- if (*str == '#')
- continue;
- if (*str == '\0')
- continue;
- name = str;
-
- GOTO_EQL(str);
-
- if (*str != '=') {
+ std::string line;
+ while (std::getline(in, line))
+ {
+ std::string name, value;
+ if (!split_key_value(line, &name, &value))
continue;
- }
- *str++ = '\0';
- SKIP_BLANK(str);
- value = str;
- GOTO_EOL(str);
- *str = '\0';
parse_option(name, value);
}
-
- fclose(input);
}
static
-pid_t start_process(const char *exec) {
- const char *args[2] = {exec, NULL};
+pid_t start_process(const std::string& exec) {
+ const char *args[2] = {exec.c_str(), NULL};
pid_t pid = fork();
- if (pid == -1) {
+ if (pid == -1)
+ {
FPRINTF(stderr, "Failed to fork");
return 0;
}
- if (pid == 0) {
+ if (pid == 0)
+ {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
- execv(exec, (char**)args);
+ execv(exec.c_str(), (char**)args);
#pragma GCC diagnostic pop
perror("Failed to exec");
kill(getppid(), SIGABRT);
@@ -171,15 +112,20 @@ pid_t start_process(const char *exec) {
// Kill all children with the same signal we got, then ourself.
static
-void stop_process(int sig) {
- if (pid_map) kill(pid_map, sig);
- if (pid_login) kill(pid_login, sig);
- if (pid_char) kill(pid_char, sig);
+void stop_process(int sig)
+{
+ if (pid_map)
+ kill(pid_map, sig);
+ if (pid_login)
+ kill(pid_login, sig);
+ if (pid_char)
+ kill(pid_char, sig);
signal(sig, SIG_DFL);
raise(sig);
}
-int main(int argc, char *argv[]) {
+int main(int argc, char *argv[])
+{
// These are all the signals we are likely to get
// The shell handles stop/cont
signal(SIGTERM, stop_process);
@@ -189,9 +135,16 @@ int main(int argc, char *argv[]) {
workdir = make_path(getenv("HOME"), "tmwserver");
- read_config(argc>1 ? argv[1] : NULL);
+ std::string config = CONFIG;
+ if (argc > 1)
+ config = argv[1];
+ read_config(config);
- if (chdir(workdir) < 0) perror("Failed to change directory"), exit(1);
+ if (chdir(workdir.c_str()) < 0)
+ {
+ perror("Failed to change directory");
+ exit(1);
+ }
PRINTF("Starting:\n");
PRINTF("* workdir: %s\n", workdir);
@@ -206,32 +159,47 @@ int main(int argc, char *argv[]) {
if (close(fd) == 0)
FPRINTF(stderr, "close fd %d\n", fd);
fd = open("/dev/null", O_RDWR);
- if (fd < 0) perror("open /dev/null"), exit(1);
+ if (fd < 0)
+ {
+ perror("open /dev/null");
+ exit(1);
+ }
dup2(fd, 0);
dup2(fd, 1);
close(fd);
}
- while (1) {
+ while (1)
+ {
// write stuff to stderr
timestamp_seconds_buffer timestamp;
stamp_time(timestamp);
- if (!pid_login) {
+ if (!pid_login)
+ {
pid_login = start_process(login_server);
FPRINTF(stderr, "[%s] forked login server: %lu\n", timestamp, (unsigned long)pid_login);
}
- if (!pid_char) {
+ if (!pid_char)
+ {
pid_char = start_process(char_server);
FPRINTF(stderr, "[%s] forked char server: %lu\n", timestamp, (unsigned long)pid_char);
}
- if (!pid_map) {
+ if (!pid_map)
+ {
pid_map = start_process(map_server);
FPRINTF(stderr, "[%s] forked map server: %lu\n", timestamp, (unsigned long)pid_map);
}
pid_t dead = wait(NULL);
- if (dead < 0) perror("Failed to wait for child"), exit(1);
- if (pid_login == dead) pid_login = 0;
- if (pid_char == dead) pid_char = 0;
- if (pid_map == dead) pid_map = 0;
+ if (dead == -1)
+ {
+ perror("Failed to wait for child");
+ exit(1);
+ }
+ if (pid_login == dead)
+ pid_login = 0;
+ if (pid_char == dead)
+ pid_char = 0;
+ if (pid_map == dead)
+ pid_map = 0;
}
}