diff options
author | Treeki <treeki@gmail.com> | 2014-01-28 00:08:33 +0100 |
---|---|---|
committer | Treeki <treeki@gmail.com> | 2014-01-28 00:08:33 +0100 |
commit | b95ed984f8bd2fe413d53d4b8677fe3d04bc1ad9 (patch) | |
tree | 5da2f4d891215fb709f7165644fd4a0c92f1aefd /bouncer | |
parent | 277c08cbc35f4cb2b72f1b00ab3e5f8efd2f8fb2 (diff) | |
download | bounce4-b95ed984f8bd2fe413d53d4b8677fe3d04bc1ad9.tar.gz bounce4-b95ed984f8bd2fe413d53d4b8677fe3d04bc1ad9.zip |
implement server configuration loading/saving
Diffstat (limited to '')
-rwxr-xr-x | bouncer/build.sh | 2 | ||||
-rwxr-xr-x | bouncer/build_static.sh | 2 | ||||
-rw-r--r-- | bouncer/core.h | 11 | ||||
-rw-r--r-- | bouncer/ini.cpp | 110 | ||||
-rw-r--r-- | bouncer/ini.h | 18 | ||||
-rw-r--r-- | bouncer/ircserver.cpp | 28 | ||||
-rw-r--r-- | bouncer/main.cpp | 1 | ||||
-rw-r--r-- | bouncer/mobileclient.cpp | 6 | ||||
-rw-r--r-- | bouncer/netcore.cpp | 40 |
9 files changed, 216 insertions, 2 deletions
diff --git a/bouncer/build.sh b/bouncer/build.sh index 935cae6..092cca1 100755 --- a/bouncer/build.sh +++ b/bouncer/build.sh @@ -2,7 +2,7 @@ mkdir -p binary NETCODE="socketcommon.cpp client.cpp mobileclient.cpp server.cpp ircserver.cpp netcore.cpp" -SOURCES="$NETCODE main.cpp window.cpp dns.cpp" +SOURCES="$NETCODE main.cpp window.cpp dns.cpp ini.cpp" FLAGS="-std=c++11 -DUSE_GNUTLS -lgnutls -pthread -g" g++ -o binary/nb4 $FLAGS $SOURCES diff --git a/bouncer/build_static.sh b/bouncer/build_static.sh index 6ed9183..e75d469 100755 --- a/bouncer/build_static.sh +++ b/bouncer/build_static.sh @@ -2,7 +2,7 @@ mkdir -p binary NETCODE="socketcommon.cpp client.cpp mobileclient.cpp server.cpp ircserver.cpp netcore.cpp" -SOURCES="$NETCODE main.cpp window.cpp dns.cpp" +SOURCES="$NETCODE main.cpp window.cpp dns.cpp ini.cpp" FLAGS="-static -static-libgcc -static-libstdc++ -std=c++11 -pthread" g++ -o binary/nb4_static $FLAGS $SOURCES diff --git a/bouncer/core.h b/bouncer/core.h index 8817b77..1a13a1d 100644 --- a/bouncer/core.h +++ b/bouncer/core.h @@ -284,6 +284,9 @@ public: Server(NetCore *_netCore); virtual ~Server(); + virtual void loadFromConfig(std::map<std::string, std::string> &data) = 0; + virtual void saveToConfig(std::map<std::string, std::string> &data) = 0; + protected: void connect(const char *hostname, int _port, bool _useTls); @@ -361,6 +364,9 @@ private: public: // This probably *shouldn't* be public... >< void deleteQuery(Query *query); + + virtual void loadFromConfig(std::map<std::string, std::string> &data); + virtual void saveToConfig(std::map<std::string, std::string> &data); }; @@ -389,8 +395,12 @@ public: Client *findClientWithSessionKey(uint8_t *key) const; private: virtual Client *constructClient() = 0; + virtual Server *constructServer(const char *type) = 0; public: + void loadConfig(); + void saveConfig(); + int registerServer(Server *server); // THIS FUNCTION WILL BE PROTECTED LATER protected: void deregisterServer(int id); @@ -400,6 +410,7 @@ protected: class Bouncer : public NetCore { private: virtual Client *constructClient(); + virtual Server *constructServer(const char *type); }; diff --git a/bouncer/ini.cpp b/bouncer/ini.cpp new file mode 100644 index 0000000..49ca38c --- /dev/null +++ b/bouncer/ini.cpp @@ -0,0 +1,110 @@ +#include "ini.h" +#include <stdio.h> +#include <string.h> + + +std::list<INI::Section> INI::load(const char *path) { + std::list<Section> sections; + + FILE *f = fopen(path, "r"); + if (!f) + return sections; + + Section *section = 0; + + for (;;) { + char line[4096]; + if (!fgets(line, sizeof(line), f)) + break; + + int length = strlen(line); + + // Get rid of the newline + if ((length > 0) && (line[length - 1] == '\n')) { + line[length - 1] = 0; + --length; + } + + // Ignore empty lines, comments + if (!length) + continue; + if (line[0] == ';') + continue; + if (line[0] == '#') + continue; + + // New section? + if ((length > 2) && (line[0] == '[') && (line[length - 1] == ']')) { + line[length - 1] = 0; + + sections.push_back(Section()); + section = §ions.back(); + section->title = &line[1]; + + } else if (section) { + // We can only add values to a section if we have one :p + + char *eq = strchr(line, '='); + if (eq) { + *eq = 0; + char *value = eq + 1; + + section->data[line] = value; + } + } + } + + fclose(f); + + return sections; +} + + +bool INI::save(const char *path, const std::list<INI::Section> §ions) { + FILE *f = fopen(path, "w"); + if (!f) + return false; + + + for (auto §ion : sections) { + fputc('[', f); + fputs(section.title.c_str(), f); + fputs("]\n\n", f); + + for (auto &i : section.data) { + fputs(i.first.c_str(), f); + fputc('=', f); + fputs(i.second.c_str(), f); + fputc('\n', f); + } + + fputc('\n', f); + } + + + fclose(f); + + return true; +} + + + +/* +int main(int argc, char **argv) { + INI::Section a, b; + + a.title = "boop"; + a.data["a"] = "b"; + a.data["c"] = "d"; + + b.title = "boop2"; + b.data["a"] = "b"; + b.data["c"] = "d"; + + std::list<INI::Section> sections = { a, b }; + INI::save("tryme.ini", sections); + + std::list<INI::Section> munged = INI::load("tryme.ini"); + INI::save("tryme2.ini", munged); +} +*/ diff --git a/bouncer/ini.h b/bouncer/ini.h new file mode 100644 index 0000000..72a0e29 --- /dev/null +++ b/bouncer/ini.h @@ -0,0 +1,18 @@ +#ifndef INI_H +#define INI_H + +#include <string> +#include <list> +#include <map> + +namespace INI { + struct Section { + std::string title; + std::map<std::string, std::string> data; + }; + + std::list<Section> load(const char *path); + bool save(const char *path, const std::list<Section> §ions); +} + +#endif /* INI_H */ diff --git a/bouncer/ircserver.cpp b/bouncer/ircserver.cpp index 8279484..c058f5c 100644 --- a/bouncer/ircserver.cpp +++ b/bouncer/ircserver.cpp @@ -635,3 +635,31 @@ char IRCServer::getEffectivePrefixChar(uint32_t modes) const { return 0; } + + + +void IRCServer::loadFromConfig(std::map<std::string, std::string> &data) { + config.hostname = data["hostname"]; + config.username = data["username"]; + config.realname = data["realname"]; + config.nickname = data["nickname"]; + config.altNick = data["altnick"]; + config.password = data["password"]; + config.useTls = (data["tls"] == "y"); + config.port = atoi(data["port"].c_str()); +} + +void IRCServer::saveToConfig(std::map<std::string, std::string> &data) { + data["type"] = "IRCServer"; + data["hostname"] = config.hostname; + data["username"] = config.username; + data["realname"] = config.realname; + data["nickname"] = config.nickname; + data["altnick"] = config.altNick; + data["password"] = config.password; + data["tls"] = config.useTls ? "y" : "n"; + + char portstr[50]; + snprintf(portstr, sizeof(portstr), "%d", config.port); + data["port"] = portstr; +} diff --git a/bouncer/main.cpp b/bouncer/main.cpp index 5330310..6c248c8 100644 --- a/bouncer/main.cpp +++ b/bouncer/main.cpp @@ -50,6 +50,7 @@ int main(int argc, char **argv) { DNS::start(); Bouncer bounce; + bounce.loadConfig(); int errcode = bounce.execute(); if (errcode < 0) { diff --git a/bouncer/mobileclient.cpp b/bouncer/mobileclient.cpp index 0dbc35a..fc1836d 100644 --- a/bouncer/mobileclient.cpp +++ b/bouncer/mobileclient.cpp @@ -70,6 +70,12 @@ void MobileClient::handleDebugCommand(char *line, int size) { } else if (strcmp(line, "addsrv") == 0) { IRCServer *srv = new IRCServer(bouncer); bouncer->registerServer(srv); + } else if (strcmp(line, "save") == 0) { + bouncer->saveConfig(); + + Buffer pkt; + pkt.writeStr("Bouncer configuration saved."); + sendPacket(Packet::B2C_STATUS, pkt); } } diff --git a/bouncer/netcore.cpp b/bouncer/netcore.cpp index dee6ef7..0dd929f 100644 --- a/bouncer/netcore.cpp +++ b/bouncer/netcore.cpp @@ -1,4 +1,5 @@ #include "core.h" +#include "ini.h" NetCore::NetCore() { @@ -321,10 +322,49 @@ void NetCore::sendToClients(Packet::Type type, const Buffer &data) { + +void NetCore::loadConfig() { + auto sections = INI::load("config.ini"); + + for (auto §ion : sections) { + if (section.title == "Server" && serverCount < SERVER_LIMIT) { + Server *s = constructServer(section.data["type"].c_str()); + if (s) { + s->loadFromConfig(section.data); + registerServer(s); + } + } + } +} + +void NetCore::saveConfig() { + std::list<INI::Section> sections; + + for (int i = 0; i < serverCount; i++) { + INI::Section section; + section.title = "Server"; + + servers[i]->saveToConfig(section.data); + + sections.push_back(section); + } + + INI::save("config.ini", sections); +} + + + + Client *Bouncer::constructClient() { return new MobileClient(this); } +Server *Bouncer::constructServer(const char *type) { + if (strcmp(type, "IRCServer") == 0) + return new IRCServer(this); + + return 0; +} |