diff options
Diffstat (limited to '')
| -rw-r--r-- | .gitignore | 1 | ||||
| -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 | 
10 files changed, 217 insertions, 2 deletions
@@ -1,3 +1,4 @@  binary  *.crt  *.key +*.ini 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; +}  | 
