From 11fc7760a05d1a48cc60b506960c429cd944e78e Mon Sep 17 00:00:00 2001
From: HarpyWar <harpywar@gmail.com>
Date: Tue, 27 May 2014 14:12:12 +0400
Subject: [PATCH] * send notification message to user after /rehash * move
 command_split() into command.cpp * fix compile errors on linux

---
 src/bnetd/command.cpp      | 73 ++++++++++++++++++++++++++++++++------
 src/bnetd/command.h        |  3 ++
 src/bnetd/helpfile.cpp     |  2 +-
 src/bnetd/icons.cpp        | 10 +++---
 src/bnetd/ipban.cpp        |  1 +
 src/bnetd/mail.cpp         |  1 +
 src/bnetd/sql_odbc.cpp     |  3 +-
 src/bnetd/topic.cpp        |  4 +--
 src/bnetd/versioncheck.cpp |  2 +-
 src/common/bnetsrp3.cpp    |  5 +--
 src/common/tag.cpp         |  6 ++--
 src/common/xstring.cpp     | 50 +-------------------------
 src/common/xstring.h       |  6 ++--
 13 files changed, 90 insertions(+), 76 deletions(-)

diff --git a/src/bnetd/command.cpp b/src/bnetd/command.cpp
index 77e28e3..3bffe54 100644
--- a/src/bnetd/command.cpp
+++ b/src/bnetd/command.cpp
@@ -117,6 +117,52 @@ namespace pvpgn
 			}
 		}
 
+		/*
+		* Split text by spaces and return array of arguments.
+		*   First text argument is a command name (index = 0)
+		*   Last text argument always reads to end
+		*/
+		extern std::vector<std::string> split_command(char const * text, int args_count)
+		{
+			std::vector<std::string> result(args_count + 1);
+
+			std::string s(text);
+			// remove slash from the command
+			if (!s.empty())
+				s.erase(0, 1);
+
+			std::istringstream iss(s);
+
+			int i = 0;
+			std::string tmp = std::string(); // to end
+			do
+			{
+				std::string sub;
+				iss >> sub;
+
+				if (sub.empty())
+					continue;
+
+				if (i < args_count)
+				{
+					result[i] = sub;
+					i++;
+				}
+				else
+				{
+					if (!tmp.empty())
+						tmp += " ";
+					tmp += sub;
+				}
+
+			} while (iss);
+
+			// push remaining text at the end
+			if (tmp.length() > 0)
+				result[args_count] = tmp;
+
+			return result;
+		}
 
 		static void do_whisper(t_connection * user_c, char const * dest, char const * text)
 		{
@@ -540,6 +586,10 @@ namespace pvpgn
 			return 0;
 		}
 
+
+
+
+
 		// +++++++++++++++++++++++++++++++++ command implementations +++++++++++++++++++++++++++++++++++++++
 
 		static int _handle_clan_command(t_connection * c, char const * text)
@@ -3755,6 +3805,8 @@ namespace pvpgn
 			}
 
 			server_restart_wraper(mode);
+			std::sprintf(msgtemp, "Rehash [%s] is complete!", mode_str.c_str());
+			message_send_text(c, message_type_info, c, msgtemp);
 			return 0;
 		}
 
@@ -4753,17 +4805,18 @@ namespace pvpgn
 				return 0;
 			}
 
-			for (char& g : args[3]) {
-				if (g == '1') groups |= 1;
-				else if (g == '2') groups |= 2;
-				else if (g == '3') groups |= 4;
-				else if (g == '4') groups |= 8;
-				else if (g == '5') groups |= 16;
-				else if (g == '6') groups |= 32;
-				else if (g == '7') groups |= 64;
-				else if (g == '8') groups |= 128;
+			// iterate chars in string
+			for (std::string::iterator g = args[3].begin(); g != args[3].end(); ++g) {
+				if (*g == '1') groups |= 1;
+				else if (*g == '2') groups |= 2;
+				else if (*g == '3') groups |= 4;
+				else if (*g == '4') groups |= 8;
+				else if (*g == '5') groups |= 16;
+				else if (*g == '6') groups |= 32;
+				else if (*g == '7') groups |= 64;
+				else if (*g == '8') groups |= 128;
 				else {
-					snprintf(msgtemp, sizeof(msgtemp), "Got bad group: %c", g);
+					snprintf(msgtemp, sizeof(msgtemp), "Got bad group: %c", *g);
 					message_send_text(c, message_type_info, c, msgtemp);
 					return 0;
 				}
diff --git a/src/bnetd/command.h b/src/bnetd/command.h
index 31fa6ae..2ecf52e 100644
--- a/src/bnetd/command.h
+++ b/src/bnetd/command.h
@@ -21,6 +21,8 @@
 #define INCLUDED_COMMAND_PROTOS
 
 #define JUST_NEED_TYPES
+#include <string>
+#include <vector>
 #include "connection.h"
 #undef JUST_NEED_TYPES
 
@@ -31,6 +33,7 @@ namespace pvpgn
 	{
 
 		extern int handle_command(t_connection * c, char const * text);
+		extern std::vector<std::string> split_command(char const * text, int args_count);
 
 	}
 
diff --git a/src/bnetd/helpfile.cpp b/src/bnetd/helpfile.cpp
index 48de29c..81d77fc 100644
--- a/src/bnetd/helpfile.cpp
+++ b/src/bnetd/helpfile.cpp
@@ -199,7 +199,7 @@ namespace pvpgn
 									if (line[i] == '#') line[i] = '\0';
 
 									// replace tabs with 3 spaces
-									line = (char*)str_replace(line, "\t", "   ");
+									line = str_replace(line, "\t", "   ");
 									// if text starts with slash then make it colored
 									int j = 0; for (; line[j] == ' ' || line[j] == '\t'; j++);
 									if (line[j] == '/')
diff --git a/src/bnetd/icons.cpp b/src/bnetd/icons.cpp
index 4f6e42e..9b541c0 100644
--- a/src/bnetd/icons.cpp
+++ b/src/bnetd/icons.cpp
@@ -26,6 +26,7 @@
 #include <cstdlib>
 #include <sstream>
 #include <vector>
+#include <string.h>
 
 #include "compat/strcasecmp.h"
 #include "compat/snprintf.h"
@@ -47,6 +48,7 @@
 #include "message.h"
 #include "helpfile.h"
 #include "channel.h"
+#include "command.h"
 
 namespace pvpgn
 {
@@ -111,7 +113,7 @@ namespace pvpgn
 
 				// get current user icon
 				if (usericon = account_get_user_icon(account, clienttag))
-					usericon = strrev(xstrdup(usericon));
+					usericon = strreverse(xstrdup(usericon));
 
 				bool is_found = false;
 				// get user stash
@@ -170,7 +172,7 @@ namespace pvpgn
 						if (!(iconcode = customicons_stash_find(clienttag, iconname)))
 						{
 							// set icon code from args
-							std::transform(args[1].begin(), args[1].end(), args[1].begin(), std::toupper); // to upper
+							std::transform(args[1].begin(), args[1].end(), args[1].begin(), ::toupper); // to upper
 							iconcode = args[1].c_str();
 						}
 						if (!is_found || strlen(iconcode) != 4)
@@ -282,7 +284,7 @@ namespace pvpgn
 				case 'l':
 					// get current user icon
 					if (usericon = account_get_user_icon(account, clienttag))
-						usericon = strrev(xstrdup(usericon));
+						usericon = strreverse(xstrdup(usericon));
 
 					// get user stash
 					if (char const * iconstash = account_get_user_iconstash(account, clienttag))
@@ -393,7 +395,7 @@ namespace pvpgn
 					{
 						// get current user icon
 						if (usericon = account_get_user_icon(account, clienttag))
-							usericon = strrev(xstrdup(usericon));
+							usericon = strreverse(xstrdup(usericon));
 
 						std::string s(iconstash);
 						std::istringstream iss(s);
diff --git a/src/bnetd/ipban.cpp b/src/bnetd/ipban.cpp
index 80ef4b8..a626252 100644
--- a/src/bnetd/ipban.cpp
+++ b/src/bnetd/ipban.cpp
@@ -43,6 +43,7 @@
 #include "connection.h"
 #include "common/setup_after.h"
 #include "helpfile.h"
+#include "command.h"
 
 namespace pvpgn
 {
diff --git a/src/bnetd/mail.cpp b/src/bnetd/mail.cpp
index 9e2f700..58f8ef5 100644
--- a/src/bnetd/mail.cpp
+++ b/src/bnetd/mail.cpp
@@ -41,6 +41,7 @@
 #include "connection.h"
 #include "common/setup_after.h"
 #include "helpfile.h"
+#include "command.h"
 
 
 namespace pvpgn
diff --git a/src/bnetd/sql_odbc.cpp b/src/bnetd/sql_odbc.cpp
index 6566eb2..2e2e639 100644
--- a/src/bnetd/sql_odbc.cpp
+++ b/src/bnetd/sql_odbc.cpp
@@ -24,6 +24,7 @@
 #include <cctype>
 #include "common/eventlog.h"
 #include "common/xalloc.h"
+#include "common/xstring.h"
 #include "storage_sql.h"
 #include "sql_odbc.h"
 #include "common/setup_after.h"
@@ -397,7 +398,7 @@ namespace pvpgn
 				}
 				p_SQLColAttribute(res->stmt, i + 1, SQL_DESC_NAME, fName, fNameSz, &fNameSz, NULL);
 				tmp = fName;
-				for (; *tmp; ++tmp) *tmp = std::toupper(*tmp);
+				for (; *tmp; ++tmp) *tmp = safe_toupper(*tmp);
 				fields[i] = fName;
 			}
 			return fields;
diff --git a/src/bnetd/topic.cpp b/src/bnetd/topic.cpp
index 9dcc3dd..6f7a8b4 100644
--- a/src/bnetd/topic.cpp
+++ b/src/bnetd/topic.cpp
@@ -216,7 +216,7 @@ namespace pvpgn
 		{
 			char msgtemp[MAX_MESSAGE_LEN];
 			char *topic, *tmp, *token;
-			char * delim = "\\";
+			const char * delim = "\\";
 			if (!(topic = channel_get_topic(channel_name)))
 				return -1;
 
@@ -246,7 +246,7 @@ namespace pvpgn
 
 				message_send_text(c, message_type_info, c, msgtemp);
 
-				token = strtok(NULL, delim);
+				token = strtok(NULL, (const char*)delim);
 				first = false;
 			}
 			xfree((void *)tmp);
diff --git a/src/bnetd/versioncheck.cpp b/src/bnetd/versioncheck.cpp
index f377e0e..b2a3f5a 100644
--- a/src/bnetd/versioncheck.cpp
+++ b/src/bnetd/versioncheck.cpp
@@ -38,6 +38,7 @@
 #include "common/field_sizes.h"
 #include "common/token.h"
 #include "common/proginfo.h"
+#include "common/xstring.h"
 
 #include "prefs.h"
 #include "common/setup_after.h"
@@ -272,7 +273,6 @@ namespace pvpgn
 			return parsed_exeinfo;
 		}
 
-#define safe_toupper(X) (std::islower((int)X)?std::toupper((int)X):(X))
 
 		/* This implements some dumb kind of pattern matching. Any '?'
 		 * signs in the pattern are treated as "don't care" signs. This
diff --git a/src/common/bnetsrp3.cpp b/src/common/bnetsrp3.cpp
index aaf43b3..6d88f44 100644
--- a/src/common/bnetsrp3.cpp
+++ b/src/common/bnetsrp3.cpp
@@ -35,6 +35,7 @@
 #include "common/util.h"
 #include "common/xalloc.h"
 #include "compat/uint.h"
+#include "common/xstring.h"
 
 #include "common/setup_after.h"
 
@@ -78,7 +79,7 @@ namespace pvpgn
 			symbol = username;
 			for (i = 0; i < username_length; i++)
 			{
-				*(symbol++) = std::toupper(*(source++));
+				*(symbol++) = safe_toupper(*(source++));
 			}
 
 			if (!((password_ == NULL) ^ (salt_ == NULL))) {
@@ -93,7 +94,7 @@ namespace pvpgn
 				symbol = password;
 				for (i = 0; i < password_length; i++)
 				{
-					*(symbol++) = std::toupper(*(source++));
+					*(symbol++) = safe_toupper(*(source++));
 				}
 				a = BigInt::random(32) % N;
 				s = BigInt::random(32);
diff --git a/src/common/tag.cpp b/src/common/tag.cpp
index e32bed7..44f42e7 100644
--- a/src/common/tag.cpp
+++ b/src/common/tag.cpp
@@ -27,6 +27,7 @@
 
 #include "common/eventlog.h"
 #include "common/xalloc.h"
+#include "common/xstring.h"
 #include "common/setup_after.h"
 
 namespace pvpgn
@@ -122,10 +123,7 @@ namespace pvpgn
 			eventlog(eventlog_level_warn, __FUNCTION__, "got unusual sized clienttag '%s'", tag_str);
 
 		for (i = 0; i < len && i < 4; i++)
-		if (std::islower((int)tag_str[i]))
-			temp_str[i] = std::toupper((int)tag_str[i]);
-		else
-			temp_str[i] = tag_str[i];
+			temp_str[i] = safe_toupper(tag_str[i]);
 
 		temp_str[4] = '\0';
 
diff --git a/src/common/xstring.cpp b/src/common/xstring.cpp
index 992a7a8..1f1670d 100644
--- a/src/common/xstring.cpp
+++ b/src/common/xstring.cpp
@@ -273,7 +273,7 @@ namespace pvpgn
 
 
 	// You must free the result if result is non-NULL.
-	extern const char *str_replace(char *orig, char *rep, char *with)
+	extern char *str_replace(char *orig, char *rep, char *with)
 	{
 		char *result; // the return string
 		char *ins;    // the next insert point
@@ -319,54 +319,6 @@ namespace pvpgn
 	}
 
 
-	/*
-	* Split text by spaces and return array of arguments.
-	*   First text argument is a command name (index = 0)
-	*   Last text argument always reads to end
-	*/
-	extern std::vector<std::string> split_command(char const * text, int args_count)
-	{
-		int count = 1 + args_count;
-		std::vector<std::string> result(count);
-
-		std::string s(text);
-		std::istringstream iss(s);
-
-		int i = 0;
-		std::string tmp = std::string(); // to end
-		do
-		{
-			std::string sub;
-			iss >> sub;
-
-			if (sub.empty())
-				continue;
-
-			// remove slash from the command
-			if (i == 0)
-				sub.erase(0, 1);
-
-			if (i < args_count)
-			{
-				result[i] = sub;
-				i++;
-			}
-			else
-			{
-				if (!tmp.empty())
-					tmp += " ";
-				tmp += sub;
-			}
-
-		} while (iss);
-
-		// push remaining text at the end
-		if (tmp.length() > 0)
-			result[count - 1] = tmp;
-
-		return result;
-	}
-
 	/* Replace "\n" in string to a new line character '\n' */
 	extern std::string str_replace_nl(char const * text)
 	{
diff --git a/src/common/xstring.h b/src/common/xstring.h
index 6c78210..01c4d11 100644
--- a/src/common/xstring.h
+++ b/src/common/xstring.h
@@ -20,6 +20,7 @@
 
 
 #include <string>
+#include <sstream>
 #include <vector>
 
 namespace pvpgn
@@ -32,10 +33,11 @@ namespace pvpgn
 	extern char * *		strtoargv(char const * str, unsigned int * count);
 	extern char *		arraytostr(char * * array, char const * delim, int count);
 	extern char *		str_strip_affix(char * str, char const * affix);
-	extern const char *str_replace(char *orig, char *rep, char *with);
-	extern std::vector<std::string> split_command(char const * text, int args_count);
+	extern char *str_replace(char *orig, char *rep, char *with);
 	extern std::string str_replace_nl(char const * text);
 
+	#define safe_toupper(X) (std::islower((int)X)?std::toupper((int)X):(X))
+
 	/*
 	Fix for std::string for some unix compilers
 	http://stackoverflow.com/a/20861692/701779