From 8f46219ea460b909b6e70a39ea892d7250f21505 Mon Sep 17 00:00:00 2001
From: Ben Longbons <b.r.longbons@gmail.com>
Date: Sun, 11 Jan 2015 00:55:31 -0800
Subject: Use generated config for monitor

---
 src/monitor/fwd.hpp     |   1 +
 src/monitor/globals.cpp |  33 ++++++++++
 src/monitor/globals.hpp |  33 ++++++++++
 src/monitor/main.cpp    | 161 ++++++++++++++++++++++--------------------------
 4 files changed, 139 insertions(+), 89 deletions(-)
 create mode 100644 src/monitor/globals.cpp
 create mode 100644 src/monitor/globals.hpp

(limited to 'src')

diff --git a/src/monitor/fwd.hpp b/src/monitor/fwd.hpp
index 425e5e9..6900e8e 100644
--- a/src/monitor/fwd.hpp
+++ b/src/monitor/fwd.hpp
@@ -32,5 +32,6 @@ namespace tmwa
 {
 namespace monitor
 {
+    struct MonitorConf;
 } // namespace monitor
 } // namespace tmwa
diff --git a/src/monitor/globals.cpp b/src/monitor/globals.cpp
new file mode 100644
index 0000000..49e814d
--- /dev/null
+++ b/src/monitor/globals.cpp
@@ -0,0 +1,33 @@
+#include "globals.hpp"
+//    globals.cpp - Evil global variables for tmwa-monitor.
+//
+//    Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com>
+//
+//    This file is part of The Mana World (Athena server)
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#include "monitor_conf.hpp"
+
+#include "../poison.hpp"
+
+
+namespace tmwa
+{
+    namespace monitor
+    {
+        MonitorConf monitor_conf;
+        pid_t pid_login, pid_char, pid_map;
+    } // namespace monitor
+} // namespace tmwa
diff --git a/src/monitor/globals.hpp b/src/monitor/globals.hpp
new file mode 100644
index 0000000..aa797d3
--- /dev/null
+++ b/src/monitor/globals.hpp
@@ -0,0 +1,33 @@
+#pragma once
+//    globals.hpp - Evil global variables for tmwa-monitor.
+//
+//    Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com>
+//
+//    This file is part of The Mana World (Athena server)
+//
+//    This program is free software: you can redistribute it and/or modify
+//    it under the terms of the GNU General Public License as published by
+//    the Free Software Foundation, either version 3 of the License, or
+//    (at your option) any later version.
+//
+//    This program is distributed in the hope that it will be useful,
+//    but WITHOUT ANY WARRANTY; without even the implied warranty of
+//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//    GNU General Public License for more details.
+//
+//    You should have received a copy of the GNU General Public License
+//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#include "fwd.hpp"
+
+#include <sys/types.h>
+
+
+namespace tmwa
+{
+    namespace monitor
+    {
+        extern MonitorConf monitor_conf;
+        extern pid_t pid_login, pid_char, pid_map;
+    } // namespace monitor
+} // namespace tmwa
diff --git a/src/monitor/main.cpp b/src/monitor/main.cpp
index 75bf827..f21a4a7 100644
--- a/src/monitor/main.cpp
+++ b/src/monitor/main.cpp
@@ -37,33 +37,20 @@
 #include "../io/line.hpp"
 
 #include "../mmo/config_parse.hpp"
+#include "../mmo/version.hpp"
 
 #include "../net/timestamp-utils.hpp"
 
-#include "../poison.hpp"
+#include "globals.hpp"
+#include "monitor_conf.hpp"
 
-#define LOGIN_SERVER "./login-server"_s
-#define MAP_SERVER "./map-server"_s
-#define CHAR_SERVER "./char-server"_s
-#define CONFIG "conf/eathena-monitor.conf"_s
+#include "../poison.hpp"
 
 
 namespace tmwa
 {
-// initialiized to $HOME/tmwserver
-static
-AString workdir;
-//the rest are relative to workdir
-static
-AString login_server = LOGIN_SERVER;
-static
-AString map_server = MAP_SERVER;
-static
-AString char_server = CHAR_SERVER;
-
-static
-pid_t pid_login, pid_map, pid_char;
-
+namespace monitor
+{
 static
 AString make_path(XString base, XString path)
 {
@@ -74,60 +61,6 @@ AString make_path(XString base, XString path)
     return AString(m);
 }
 
-static
-bool parse_option(io::Spanned<XString> name, io::Spanned<ZString> value)
-{
-    if (name.data == "login_server"_s)
-        login_server = value.data;
-    else if (name.data == "map_server"_s)
-        map_server = value.data;
-    else if (name.data == "char_server"_s)
-        char_server = value.data;
-    else if (name.data == "workdir"_s)
-        workdir = value.data;
-    else
-    {
-        name.span.error("invalid option key"_s);
-        return false;
-    }
-    return true;
-}
-
-static
-bool read_config(ZString filename)
-{
-    bool rv = true;
-    io::LineReader in(filename);
-    if (!in.is_open())
-    {
-        FPRINTF(stderr, "Monitor config file not found: %s\n"_fmt, filename);
-        exit(1);
-    }
-
-    io::Line line_;
-    while (in.read_line(line_))
-    {
-        io::Spanned<ZString> line = respan(line_.to_span(), ZString(line_.text));
-        if (is_comment(line.data))
-            continue;
-        io::Spanned<XString> name;
-        io::Spanned<ZString> value;
-        if (!config_split(line, &name, &value))
-        {
-            line.span.error("Unable to split config key: value"_s);
-            rv = false;
-            continue;
-        }
-
-        if (!parse_option(name, value))
-        {
-            rv = false;
-            continue;
-        }
-    }
-    return rv;
-}
-
 static
 pid_t start_process(ZString exec)
 {
@@ -155,12 +88,12 @@ pid_t start_process(ZString exec)
 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);
+    if (pid_map)
+        kill(pid_map, sig);
     DIAG_PUSH();
     DIAG_I(old_style_cast);
     DIAG_I(zero_as_null_pointer_constant);
@@ -168,11 +101,30 @@ void stop_process(int sig)
     DIAG_POP();
     raise(sig);
 }
+
+static
+bool monitor_config(io::Spanned<XString> key, io::Spanned<ZString> value)
+{
+    return parse_monitor_conf(monitor_conf, key, value);
+}
+
+static
+bool monitor_confs(io::Spanned<XString> key, io::Spanned<ZString> value)
+{
+    if (key.data == "monitor_conf"_s)
+    {
+        return load_config_file(value.data, monitor_config);
+    }
+    key.span.error("Unknown meta-key for monitor nonserver"_s);
+    return false;
+}
+} // namespace monitor
 } // namespace tmwa
 
 int main(int argc, char *argv[])
 {
     using namespace tmwa;
+    using namespace tmwa::monitor;
     // These are all the signals we are likely to get
     // The shell handles stop/cont
     signal(SIGTERM, stop_process);
@@ -180,27 +132,58 @@ int main(int argc, char *argv[])
     signal(SIGQUIT, stop_process);
     signal(SIGABRT, stop_process);
 
-    workdir = make_path(ZString(strings::really_construct_from_a_pointer, getenv("HOME"), nullptr), "tmwserver"_s);
+    monitor_conf.workdir = make_path(ZString(strings::really_construct_from_a_pointer, getenv("HOME"), nullptr), "tmwserver"_s);
 
-    ZString config = CONFIG;
-    if (argc > 1)
-        config = ZString(strings::really_construct_from_a_pointer, argv[1], nullptr);
-    if (!read_config(config))
+    ZString argv0 = ZString(strings::really_construct_from_a_pointer, argv[0], nullptr);
+    bool loaded_config_yet = false;
+    bool runflag = true;
+
+    for (int ai = 1; ai < argc; ++ai)
     {
-        exit(1);
+        ZString argvi = ZString(strings::really_construct_from_a_pointer, argv[ai], nullptr);
+        if (argvi.startswith('-'))
+        {
+            if (argvi == "--help"_s)
+            {
+                PRINTF("Usage: %s [--help] [--version] [files...]\n"_fmt,
+                        argv0);
+                exit(0);
+            }
+            else if (argvi == "--version"_s)
+            {
+                PRINTF("%s\n"_fmt, CURRENT_VERSION_STRING);
+                exit(0);
+            }
+            else
+            {
+                FPRINTF(stderr, "Unknown argument: %s\n"_fmt, argvi);
+                runflag = false;
+            }
+        }
+        else
+        {
+            loaded_config_yet = true;
+            runflag &= load_config_file(argvi, monitor_confs);
+        }
     }
 
-    if (chdir(workdir.c_str()) < 0)
+    if (!loaded_config_yet)
+        runflag &= load_config_file("conf/tmwa-monitor.conf"_s, monitor_confs);
+
+    if (!runflag)
+        exit(1);
+
+    if (chdir(monitor_conf.workdir.c_str()) < 0)
     {
         perror("Failed to change directory");
         exit(1);
     }
 
     PRINTF("Starting:\n"_fmt);
-    PRINTF("* workdir: %s\n"_fmt,  workdir);
-    PRINTF("* login_server: %s\n"_fmt, login_server);
-    PRINTF("* char_server: %s\n"_fmt, char_server);
-    PRINTF("* map_server: %s\n"_fmt, map_server);
+    PRINTF("* workdir: %s\n"_fmt, monitor_conf.workdir);
+    PRINTF("* login_server: %s\n"_fmt, monitor_conf.login_server);
+    PRINTF("* char_server: %s\n"_fmt, monitor_conf.char_server);
+    PRINTF("* map_server: %s\n"_fmt, monitor_conf.map_server);
     {
         //make sure all possible file descriptors are free for use by the servers
         //if there are file descriptors higher than the max open from before the limit dropped, that's not our problem
@@ -228,19 +211,19 @@ int main(int argc, char *argv[])
 
         if (!pid_login)
         {
-            pid_login = start_process(login_server);
+            pid_login = start_process(monitor_conf.login_server);
             FPRINTF(stderr, "[%s] forked login server: %lu\n"_fmt,
                     timestamp, static_cast<unsigned long>(pid_login));
         }
         if (!pid_char)
         {
-            pid_char = start_process(char_server);
+            pid_char = start_process(monitor_conf.char_server);
             FPRINTF(stderr, "[%s] forked char server: %lu\n"_fmt,
                     timestamp, static_cast<unsigned long>(pid_char));
         }
         if (!pid_map)
         {
-            pid_map = start_process(map_server);
+            pid_map = start_process(monitor_conf.map_server);
             FPRINTF(stderr, "[%s] forked map server: %lu\n"_fmt,
                     timestamp, static_cast<unsigned long>(pid_map));
         }
-- 
cgit v1.2.3-70-g09d2