From 3b46205114ae6be51aeaaa80feb96ca0ebb4c197 Mon Sep 17 00:00:00 2001 From: RElesgoe Date: Tue, 21 Mar 2017 03:20:06 -0700 Subject: [PATCH] - Improved code safety - Fixed bug in /ipscan command - Restored icons_STAR.bni --- conf/bnetd.conf.in | 1 + conf/bnetd.conf.win32 | 1 + conf/supportfile.conf.in | 1 + files/CMakeLists.txt | 2 +- files/icons_STAR.bni | Bin 0 -> 24555 bytes src/bnetd/command.cpp | 45 +++++++------- src/bnetd/connection.cpp | 16 ++--- src/bnetd/file.cpp | 123 +++++++++++++++++++------------------ src/bnetd/handle_bnet.cpp | 9 +-- src/bnetd/helpfile.cpp | 11 ++-- src/bnetd/i18n.cpp | 17 ++--- src/bnetd/i18n.h | 2 +- src/bnetd/luainterface.cpp | 1 + src/bnetd/main.cpp | 1 - src/bnetd/news.cpp | 18 +++--- src/bnetd/output.cpp | 26 ++++---- src/bnetd/output.h | 5 +- src/bnetd/prefs.cpp | 27 ++++++++ src/bnetd/prefs.h | 1 + src/bnetd/userlog.cpp | 33 +++------- src/bnetd/userlog.h | 2 +- src/common/util.cpp | 10 --- src/common/util.h | 1 - 23 files changed, 173 insertions(+), 180 deletions(-) create mode 100644 files/icons_STAR.bni diff --git a/conf/bnetd.conf.in b/conf/bnetd.conf.in index c14c83d..0615ce5 100644 --- a/conf/bnetd.conf.in +++ b/conf/bnetd.conf.in @@ -169,6 +169,7 @@ allow_d2cs_setname = true # the "filedir" directory specified above. iconfile = "icons.bni" war3_iconfile = "icons-WAR3.bni" +star_iconfile = "icons_STAR.bni" # # ############################################################################## diff --git a/conf/bnetd.conf.win32 b/conf/bnetd.conf.win32 index bd3ca4a..a2a0cc0 100644 --- a/conf/bnetd.conf.win32 +++ b/conf/bnetd.conf.win32 @@ -150,6 +150,7 @@ allow_d2cs_setname = true # the "filedir" directory specified above. iconfile = "icons.bni" war3_iconfile = "icons-WAR3.bni" +star_iconfile = "icons_STAR.bni" # # ############################################################################## diff --git a/conf/supportfile.conf.in b/conf/supportfile.conf.in index 3c09e68..8551ffe 100644 --- a/conf/supportfile.conf.in +++ b/conf/supportfile.conf.in @@ -10,4 +10,5 @@ bnserver-D2XP.ini bnserver-WAR3.ini bnserver.ini icons-WAR3.bni +icons_STAR.bni icons.bni diff --git a/files/CMakeLists.txt b/files/CMakeLists.txt index 304b96d..bfe595a 100644 --- a/files/CMakeLists.txt +++ b/files/CMakeLists.txt @@ -20,5 +20,5 @@ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/var/ DESTINATION ${LOCALSTATEDIR}) install(FILES ad000001.png ad000001.smk ad000002.mng newbie.save bnserver.ini bnserver-D2DV.ini bnserver-D2XP.ini bnserver-WAR3.ini ver-IX86-1.mpq IX86ver1.mpq PMACver1.mpq XMACver1.mpq IX86ExtraWork.mpq - icons.bni icons-WAR3.bni + icons.bni icons-WAR3.bni icons_STAR.bni DESTINATION ${LOCALSTATEDIR}/files) diff --git a/files/icons_STAR.bni b/files/icons_STAR.bni new file mode 100644 index 0000000000000000000000000000000000000000..73c548a6937f8de4709cebba5f766398104889ff GIT binary patch literal 24555 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 S^Ebc#$=knpbN!8 args = split_command(text, 1); if (args[1].empty()) @@ -4560,27 +4559,32 @@ namespace pvpgn } text = args[1].c_str(); // ip or username - - if (account = accountlist_find_account(text)) { + std::string ip; + if (account = accountlist_find_account(text)) + { conn = account_get_conn(account); - if (conn) { + if (conn) + { // conn_get_addr returns int, so there can never be a NULL string construct ip = addr_num_to_ip_str(conn_get_addr(conn)); } - else { + else + { message_send_text(c, message_type_info, c, localize(c, "Warning: That user is not online, using last known address.")); - if (!(ip = account_get_ll_ip(account))) { + ip = account_get_ll_ip(account); + if (ip.empty()) + { message_send_text(c, message_type_error, c, localize(c, "Sorry, no IP address could be retrieved.")); return 0; } } } - else { + else + { ip = text; } - msgtemp = localize(c, "Scanning online users for IP {}...", ip); - message_send_text(c, message_type_error, c, msgtemp); + message_send_text(c, message_type_info, c, localize(c, "Scanning online users for IP {}...", ip)); t_elem const * curr; int count = 0; @@ -4591,7 +4595,8 @@ namespace pvpgn continue; } - if (std::strcmp(ip, addr_num_to_ip_str(conn_get_addr(conn))) == 0) { + if (ip.compare(addr_num_to_ip_str(conn_get_addr(conn))) == 0) + { std::snprintf(msgtemp0, sizeof(msgtemp0), " %s", conn_get_loggeduser(conn)); message_send_text(c, message_type_info, c, msgtemp0); count++; @@ -4670,11 +4675,10 @@ namespace pvpgn static int _handle_motd_command(t_connection * c, char const *text) { - std::FILE * fp; + std::string filename = i18n_filename(prefs_get_motdfile(), conn_get_gamelang_localized(c)); - const char* const filename = i18n_filename(prefs_get_motdfile(), conn_get_gamelang_localized(c)); - - if (fp = std::fopen(filename, "r")) + std::FILE* fp = std::fopen(filename.c_str(), "r"); + if (fp) { message_send_file(c, fp); if (std::fclose(fp) < 0) @@ -4686,8 +4690,6 @@ namespace pvpgn message_send_text(c, message_type_error, c, localize(c, "Unable to open motd.")); } - xfree((void*)filename); - return 0; } @@ -4695,15 +4697,12 @@ namespace pvpgn { /* handle /tos - shows terms of service by user request -raistlinthewiz */ - const char* const filename = i18n_filename(prefs_get_tosfile(), conn_get_gamelang_localized(c)); - std::FILE * fp; - + std::string filename = i18n_filename(prefs_get_tosfile(), conn_get_gamelang_localized(c)); /* FIXME: if user enters relative path to tos file in config, above routine will fail */ - - if ((fp = std::fopen(filename, "r"))) + std::FILE* fp = std::fopen(filename.c_str(), "r"); + if (fp) { - char * buff; unsigned len; @@ -4748,8 +4747,6 @@ namespace pvpgn message_send_text(c, message_type_error, c, localize(c, "Unable to send TOS (Terms of Service).")); } - xfree((void*)filename); - return 0; } diff --git a/src/bnetd/connection.cpp b/src/bnetd/connection.cpp index 8a5939b..f1fe95d 100644 --- a/src/bnetd/connection.cpp +++ b/src/bnetd/connection.cpp @@ -122,26 +122,28 @@ namespace pvpgn if (c->protocol.cflags & conn_flags_welcomed) return; + if ((conn_get_class(c) == conn_class_irc) || (conn_get_class(c) == conn_class_wol)) { c->protocol.cflags |= conn_flags_welcomed; return; } + if (filename = prefs_get_motdfile()) { - const char *lang_filename = i18n_filename(filename, conn_get_gamelang_localized(c)); - - if (fp = std::fopen(lang_filename, "r")) { + std::string lang_filename = i18n_filename(filename, conn_get_gamelang_localized(c)); + if (fp = std::fopen(lang_filename.c_str(), "r")) + { message_send_file(c, fp); - if (std::fclose(fp) < 0) { + if (std::fclose(fp) < 0) + { eventlog(eventlog_level_error, __FUNCTION__, "could not close MOTD file \"{}\" after reading (std::fopen: {})", lang_filename, std::strerror(errno)); } } - else { + else + { eventlog(eventlog_level_error, __FUNCTION__, "could not open MOTD file \"{}\" for reading (std::fopen: {})", filename, std::strerror(errno)); } - - xfree((void*)lang_filename); } c->protocol.cflags |= conn_flags_welcomed; } diff --git a/src/bnetd/file.cpp b/src/bnetd/file.cpp index 716dbfa..230acff 100644 --- a/src/bnetd/file.cpp +++ b/src/bnetd/file.cpp @@ -21,6 +21,7 @@ #include #include +#include #ifdef HAVE_SYS_TYPES_H # include @@ -51,7 +52,7 @@ namespace pvpgn namespace bnetd { - static char const * file_get_info(t_connection * c, char const * rawname, unsigned int * len, bn_long * modtime); + static std::string file_get_info(t_connection * c, char const * rawname, unsigned int * len, bn_long * modtime); /* Requested files aliases */ const char * requestfiles[] = { @@ -64,7 +65,7 @@ namespace pvpgn NULL, NULL }; - static const char * file_find_localized(t_connection * c, const char *rawname) + static std::string file_find_localized(t_connection * c, const char *rawname) { const char ** pattern, **alias; size_t rawnamelen = std::strlen(rawname); @@ -83,7 +84,7 @@ namespace pvpgn // if there is no country tag in the file (just in case to prevent crash from invalid filename) if ((strlen(*pattern) + 4) > rawnamelen) - return NULL; + return std::string(); // get language tag from the file name (like "termsofservice-ruRU.txt") // (it used in War3) @@ -105,54 +106,50 @@ namespace pvpgn return i18n_filename(*alias, gamelang); } } + // if not found return source file - return NULL; + return std::string(); } - static char const * file_get_info(t_connection * c, char const * rawname, unsigned int * len, bn_long * modtime) + static std::string file_get_info(t_connection * c, char const * rawname, unsigned int * len, bn_long * modtime) { - const char *filename = nullptr; - t_bnettime bt; - struct stat sfile; - - if (!rawname) { - eventlog(eventlog_level_error, __FUNCTION__, "got NULL rawname"); - return nullptr; - } - - if (!len) { - eventlog(eventlog_level_error, __FUNCTION__, "got NULL len"); - return nullptr; - } - - if (!modtime) { - eventlog(eventlog_level_error, __FUNCTION__, "got NULL modtime"); - return nullptr; - } - - if (std::strchr(rawname, '/') || std::strchr(rawname, '\\')) { - eventlog(eventlog_level_warn, __FUNCTION__, "got rawname containing '/' or '\\' \"{}\"", rawname); - return nullptr; - } - - - filename = file_find_localized(c, rawname); - // if localized file not found in "i18n" - if (!filename || stat(filename, &sfile) < 0) + if (!rawname) + { + throw std::runtime_error("NULL rawname"); + } + + if (!len) + { + throw std::runtime_error("NULL len"); + } + + if (!modtime) + { + throw std::runtime_error("NULL modtime"); + } + + if (std::strchr(rawname, '/') || std::strchr(rawname, '\\')) + { + throw std::runtime_error(fmt::format("got rawname containing '/' or '\\' \"{}\"", rawname)); + } + + struct stat sfile; + std::string filename = file_find_localized(c, rawname); + + // if localized file not found in "i18n" + if (filename.empty() || stat(filename.c_str(), &sfile) != 0) { - if (filename) - xfree((void*)filename); // try find it in "files" - filename = buildpath(prefs_get_filedir(), rawname); - if (stat(filename, &sfile) < 0) { /* try again */ + filename = fmt::format("{}/{}", prefs_get_filedir(), rawname).c_str(); + if (stat(filename.c_str(), &sfile) < 0) /* try again */ + { /* FIXME: check for lower-case version of filename */ - xfree((void*)filename); - return nullptr; + throw std::runtime_error(fmt::format("file {} not found", filename)); } } *len = (unsigned int)sfile.st_size; - bt = time_to_bnettime(sfile.st_mtime, 0); + t_bnettime bt = time_to_bnettime(sfile.st_mtime, 0); bnettime_to_bn_long(bt, modtime); return filename; @@ -161,24 +158,28 @@ namespace pvpgn extern int file_to_mod_time(t_connection * c, char const * rawname, bn_long * modtime) { - const char * filename = nullptr; - unsigned int len; - if (!rawname) { eventlog(eventlog_level_error, __FUNCTION__, "got NULL rawname"); return -1; } + if (!modtime) { eventlog(eventlog_level_error, __FUNCTION__, "got NULL modtime"); return -1; } - if (!(filename = file_get_info(c, rawname, &len, modtime))) + try + { + unsigned int len = 0; + file_get_info(c, rawname, &len, modtime); + } + catch (const std::runtime_error& e) + { + eventlog(eventlog_level_error, __FUNCTION__, "{}", e.what()); return -1; - - xfree((void *)filename); /* avoid warning */ + } return 0; } @@ -190,10 +191,9 @@ namespace pvpgn */ extern int file_send(t_connection * c, char const * rawname, unsigned int adid, unsigned int etag, unsigned int startoffset, int need_header) { - char filenamestk[FILENAME_MAX] = {}; t_packet * rpacket; std::FILE * fp; - unsigned int filelen; + int nbytes; if (!c) @@ -206,9 +206,6 @@ namespace pvpgn eventlog(eventlog_level_error, __FUNCTION__, "got NULL rawname"); return -1; } - // ignore request for icons_STAR.bni (deprecated https://github.com/pvpgn/pvpgn-server/issues/55) - if (strcmp(rawname, BNETD_STAR_ICON_FILE) == 0) - return -1; if (!(rpacket = packet_create(packet_class_file))) { @@ -218,16 +215,22 @@ namespace pvpgn packet_set_size(rpacket, sizeof(t_server_file_reply)); packet_set_type(rpacket, SERVER_FILE_REPLY); + unsigned int filelen = 0; + std::string filename; + try { - char const *filename = file_get_info(c, rawname, &filelen, &rpacket->u.server_file_reply.timestamp); - std::snprintf(filenamestk, sizeof filenamestk, "%s", filename); - xfree((void*)filename); - } //let filename go out of scope + filename = file_get_info(c, rawname, &filelen, &rpacket->u.server_file_reply.timestamp); + } + catch (const std::runtime_error& e) + { + eventlog(eventlog_level_error, __FUNCTION__, "{}", e.what()); + return -1; + } - if (!(fp = std::fopen(filenamestk, "rb"))) + if (!(fp = std::fopen(filename.c_str(), "rb"))) { /* FIXME: check for lower-case version of filename */ - eventlog(eventlog_level_error, __FUNCTION__, "stat() succeeded yet could not open file \"{}\" for reading (std::fopen: {})", filenamestk, std::strerror(errno)); + eventlog(eventlog_level_error, __FUNCTION__, "stat() succeeded yet could not open file \"{}\" for reading (std::fopen: {})", filename.c_str(), std::strerror(errno)); filelen = 0; } @@ -261,18 +264,18 @@ namespace pvpgn */ if (!fp) { - eventlog(eventlog_level_warn, __FUNCTION__, "[{}] sending no data for file \"{}\" (\"{}\")", conn_get_socket(c), rawname, filenamestk); + eventlog(eventlog_level_warn, __FUNCTION__, "[{}] sending no data for file \"{}\" (\"{}\")", conn_get_socket(c), rawname, filename.c_str()); return -1; } - eventlog(eventlog_level_info, __FUNCTION__, "[{}] sending file \"{}\" (\"{}\") of length {}", conn_get_socket(c), rawname, filenamestk, filelen); + eventlog(eventlog_level_info, __FUNCTION__, "[{}] sending file \"{}\" (\"{}\") of length {}", conn_get_socket(c), rawname, filename.c_str(), filelen); for (;;) { if (!(rpacket = packet_create(packet_class_raw))) { eventlog(eventlog_level_error, __FUNCTION__, "could not create raw packet"); if (std::fclose(fp) < 0) - eventlog(eventlog_level_error, __FUNCTION__, "could not close file \"{}\" after reading (std::fclose: {})", filenamestk, std::strerror(errno)); + eventlog(eventlog_level_error, __FUNCTION__, "could not close file \"{}\" after reading (std::fclose: {})", filename.c_str(), std::strerror(errno)); return -1; } if ((nbytes = std::fread(packet_get_raw_data_build(rpacket, 0), 1, MAX_PACKET_SIZE, fp))<(int)MAX_PACKET_SIZE) diff --git a/src/bnetd/handle_bnet.cpp b/src/bnetd/handle_bnet.cpp index 2f1fd90..3f5483b 100644 --- a/src/bnetd/handle_bnet.cpp +++ b/src/bnetd/handle_bnet.cpp @@ -2808,14 +2808,11 @@ namespace pvpgn { fmt::MemoryWriter serverinfo; - const char* const filename = i18n_filename(prefs_get_motdw3file(), conn_get_gamelang_localized(c)); - std::FILE* fp = std::fopen(filename, "r"); - xfree((void*)filename); - + std::string filename = i18n_filename(prefs_get_motdw3file(), conn_get_gamelang_localized(c)); + std::FILE* fp = std::fopen(filename.c_str(), "r"); if (fp) { - char* buff; - while (buff = file_get_line(fp)) + while (char* buff = file_get_line(fp)) { char* line = message_format_line(c, buff); serverinfo << (line + 1) << '\n'; diff --git a/src/bnetd/helpfile.cpp b/src/bnetd/helpfile.cpp index b5332e1..bad0012 100644 --- a/src/bnetd/helpfile.cpp +++ b/src/bnetd/helpfile.cpp @@ -67,20 +67,17 @@ namespace pvpgn eventlog(eventlog_level_error, __FUNCTION__, "got NULL filename"); return -1; } - const char * _filename = nullptr; // iterate language list - for (int i = 0; i < languages.size(); i++) + for (std::size_t i = 0; i < languages.size(); i++) { // get hfd of all localized help files - _filename = i18n_filename(filename, languages[i].gamelang); - if (!(hfd_list[languages[i].gamelang] = std::fopen(_filename, "r"))) + std::string helpfile = i18n_filename(filename, languages[i].gamelang); + if (!(hfd_list[languages[i].gamelang] = std::fopen(helpfile.c_str(), "r"))) { - eventlog(eventlog_level_error, __FUNCTION__, "could not open help file \"{}\" for reading (std::fopen: {})", _filename, std::strerror(errno)); - xfree((void*)_filename); + eventlog(eventlog_level_error, __FUNCTION__, "could not open help file \"{}\" for reading (std::fopen: {})", helpfile, std::strerror(errno)); return -1; } - xfree((void*)_filename); } return 0; diff --git a/src/bnetd/i18n.cpp b/src/bnetd/i18n.cpp index 4d6629d..f68fe7d 100644 --- a/src/bnetd/i18n.cpp +++ b/src/bnetd/i18n.cpp @@ -247,24 +247,19 @@ namespace pvpgn /* Add a locale tag into filename example: motd.txt -> motd-ruRU.txt */ - extern const char * i18n_filename(const char * filename, t_tag gamelang) + extern std::string i18n_filename(const char * filename, t_tag gamelang) { - struct stat sfile; - const char * tmpfilename = buildpath(prefs_get_i18ndir(), tag_uint_to_str2(gamelang).c_str()); - const char * _filename = buildpath(tmpfilename, filename); - xfree((void*)tmpfilename); + std::string path = fmt::format("{}/{}/{}", prefs_get_i18ndir(), tag_uint_to_str2(gamelang), filename); // if localized file not found - if (stat(_filename, &sfile) < 0) + struct stat sfile = {}; + if (stat(path.c_str(), &sfile) < 0) { - // free previously allocated memory first - xfree((void*)_filename); - // use default file - _filename = buildpath(prefs_get_i18ndir(), filename); + path = fmt::format("{}/{}", prefs_get_i18ndir(), filename); } - return _filename; + return path; } diff --git a/src/bnetd/i18n.h b/src/bnetd/i18n.h index 3f220e7..f5a651e 100644 --- a/src/bnetd/i18n.h +++ b/src/bnetd/i18n.h @@ -53,7 +53,7 @@ namespace pvpgn extern int i18n_load(void); extern int i18n_reload(void); - extern const char * i18n_filename(const char * filename, t_tag gamelang); + extern std::string i18n_filename(const char * filename, t_tag gamelang); extern t_language language_find_by_country(const char * code, bool &found); extern t_language language_find_by_tag(t_gamelang gamelang, bool &found); extern t_language language_get_by_country(const char * code); diff --git a/src/bnetd/luainterface.cpp b/src/bnetd/luainterface.cpp index 48b7d1f..7aac911 100644 --- a/src/bnetd/luainterface.cpp +++ b/src/bnetd/luainterface.cpp @@ -210,6 +210,7 @@ namespace pvpgn config.update("allow_d2cs_setname", prefs_allow_d2cs_setname()); config.update("iconfile", prefs_get_iconfile()); config.update("war3_iconfile", prefs_get_war3_iconfile()); + config.update("star_iconfile", prefs_get_star_iconfile()); config.update("tosfile", prefs_get_tosfile()); config.update("allowed_clients", prefs_get_allowed_clients()); config.update("skip_versioncheck", prefs_get_skip_versioncheck()); diff --git a/src/bnetd/main.cpp b/src/bnetd/main.cpp index 894b893..323226e 100644 --- a/src/bnetd/main.cpp +++ b/src/bnetd/main.cpp @@ -445,7 +445,6 @@ void post_server_shutdown(int status) case STATUS_LADDERLIST_FAILURE: ladders.save(); - output_dispose_filename(); accountlist_destroy(); attrlayer_cleanup(); watchlist.reset(); diff --git a/src/bnetd/news.cpp b/src/bnetd/news.cpp index 5d85d7e..ca172a2 100644 --- a/src/bnetd/news.cpp +++ b/src/bnetd/news.cpp @@ -146,15 +146,15 @@ namespace pvpgn } // FIXME: (HarpyWar) change news loading when user log on to send a localized version - const char *ENfilename = i18n_filename(filename, GAMELANG_ENGLISH_UINT); - if ((fp = std::fopen(ENfilename, "rt")) == NULL) { + if ((fp = std::fopen(i18n_filename(filename, GAMELANG_ENGLISH_UINT).c_str(), "rt")) == NULL) + { eventlog(eventlog_level_warn, __FUNCTION__, "can't open news file"); _news_insert_default(); - xfree((void*)ENfilename); return 0; } - for (line = 1; std::fgets(buff, sizeof(buff), fp); line++) { + for (line = 1; std::fgets(buff, sizeof(buff), fp); line++) + { len = std::strlen(buff); while (len && (buff[len - 1] == '\n' || buff[len - 1] == '\r')) len--; if (!len) continue; /* empty line */ @@ -165,7 +165,6 @@ namespace pvpgn if (_news_parsetime(buff + 1, &date, line)) { eventlog(eventlog_level_error, __FUNCTION__, "error parsing news date on line {}", line); - xfree((void*)ENfilename); std::fclose(fp); return -1; } @@ -175,8 +174,11 @@ namespace pvpgn { ni = (t_news_index*)xmalloc(sizeof(t_news_index)); if (date_set) + { ni->date = std::mktime(&date); - else { + } + else + { ni->date = std::time(NULL); eventlog(eventlog_level_warn, __FUNCTION__, "(first) news entry seems to be missing a timestamp, please check your news file on line {}", line); } @@ -186,12 +188,12 @@ namespace pvpgn } std::fclose(fp); - if (elist_empty(&news_head)) { + if (elist_empty(&news_head)) + { eventlog(eventlog_level_warn, __FUNCTION__, "no news configured"); _news_insert_default(); } - xfree((void*)ENfilename); return 0; } diff --git a/src/bnetd/output.cpp b/src/bnetd/output.cpp index e8b296c..a4e2cef 100644 --- a/src/bnetd/output.cpp +++ b/src/bnetd/output.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include "common/eventlog.h" #include "common/xalloc.h" @@ -41,7 +42,7 @@ namespace pvpgn namespace bnetd { - char * status_filename; + std::string status_filename; int output_standard_writer(std::FILE * fp); @@ -49,14 +50,14 @@ namespace pvpgn * Initialisation Output * */ - extern void output_init(void) + extern void output_init() { eventlog(eventlog_level_info, __FUNCTION__, "initializing output file"); if (prefs_get_XML_status_output()) - status_filename = buildpath(prefs_get_outputdir(), "server.xml"); + status_filename = fmt::format("{}/{}", prefs_get_outputdir(), "server.xml"); else - status_filename = buildpath(prefs_get_outputdir(), "server.dat"); + status_filename = fmt::format("{}/{}", prefs_get_outputdir(), "server.dat"); return; } @@ -205,17 +206,16 @@ namespace pvpgn } } - extern int output_write_to_file(void) + extern int output_write_to_file() { - std::FILE * fp; - - if (!status_filename) + if (status_filename.empty()) { - eventlog(eventlog_level_error, __FUNCTION__, "got NULL filename"); + eventlog(eventlog_level_error, __FUNCTION__, "got empty filename"); return -1; } - if (!(fp = std::fopen(status_filename, "w"))) + std::FILE* fp = std::fopen(status_filename.c_str(), "w"); + if (!fp) { eventlog(eventlog_level_error, __FUNCTION__, "could not open file \"{}\" for writing (std::fopen: {})", status_filename, std::strerror(errno)); return -1; @@ -223,12 +223,8 @@ namespace pvpgn output_standard_writer(fp); std::fclose(fp); - return 0; - } - extern void output_dispose_filename(void) - { - if (status_filename) xfree(status_filename); + return 0; } } diff --git a/src/bnetd/output.h b/src/bnetd/output.h index e2b0d38..50992dd 100644 --- a/src/bnetd/output.h +++ b/src/bnetd/output.h @@ -23,9 +23,8 @@ namespace pvpgn namespace bnetd { - extern void output_init(void); - extern void output_dispose_filename(void); - extern int output_write_to_file(void); + extern void output_init(); + extern int output_write_to_file(); } diff --git a/src/bnetd/prefs.cpp b/src/bnetd/prefs.cpp index 3a9b859..3f6fe86 100644 --- a/src/bnetd/prefs.cpp +++ b/src/bnetd/prefs.cpp @@ -85,6 +85,7 @@ namespace pvpgn unsigned int report_diablo_games; char const * iconfile; char const * war3_iconfile; + char const * star_iconfile; char const * tosfile; char const * mpqfile; char const * trackaddrs; @@ -361,6 +362,10 @@ namespace pvpgn static const char *conf_get_war3_iconfile(void); static int conf_setdef_war3_iconfile(void); + static int conf_set_star_iconfile(const char *valstr); + static const char *conf_get_star_iconfile(void); + static int conf_setdef_star_iconfile(void); + static int conf_set_tosfile(const char *valstr); static const char *conf_get_tosfile(void); static int conf_setdef_tosfile(void); @@ -778,6 +783,7 @@ namespace pvpgn { "report_diablo_games", conf_set_report_diablo_games, conf_get_report_diablo_games, conf_setdef_report_diablo_games }, { "iconfile", conf_set_iconfile, conf_get_iconfile, conf_setdef_iconfile }, { "war3_iconfile", conf_set_war3_iconfile, conf_get_war3_iconfile, conf_setdef_war3_iconfile }, + { "star_iconfile", conf_set_star_iconfile, conf_get_star_iconfile, conf_setdef_star_iconfile }, { "tosfile", conf_set_tosfile, conf_get_tosfile, conf_setdef_tosfile }, { "mpqfile", conf_set_mpqfile, conf_get_mpqfile, conf_setdef_mpqfile }, { "trackaddrs", conf_set_trackaddrs, conf_get_trackaddrs, conf_setdef_trackaddrs }, @@ -1835,6 +1841,27 @@ namespace pvpgn } + extern char const * prefs_get_star_iconfile(void) + { + return prefs_runtime_config.star_iconfile; + } + + static int conf_set_star_iconfile(const char *valstr) + { + return conf_set_str(&prefs_runtime_config.star_iconfile, valstr, NULL); + } + + static int conf_setdef_star_iconfile(void) + { + return conf_set_str(&prefs_runtime_config.star_iconfile, NULL, BNETD_STAR_ICON_FILE); + } + + static const char* conf_get_star_iconfile(void) + { + return prefs_runtime_config.star_iconfile; + } + + extern char const * prefs_get_tosfile(void) { return prefs_runtime_config.tosfile; diff --git a/src/bnetd/prefs.h b/src/bnetd/prefs.h index 914e6ae..3abe0f1 100644 --- a/src/bnetd/prefs.h +++ b/src/bnetd/prefs.h @@ -80,6 +80,7 @@ namespace pvpgn extern char const * prefs_get_pidfile(void); extern char const * prefs_get_iconfile(void); extern char const * prefs_get_war3_iconfile(void); + extern char const * prefs_get_star_iconfile(void); extern char const * prefs_get_tosfile(void); extern char const * prefs_get_mpqauthfile(void); extern char const * prefs_get_mpqfile(void); diff --git a/src/bnetd/userlog.cpp b/src/bnetd/userlog.cpp index 41f3a9d..6728025 100644 --- a/src/bnetd/userlog.cpp +++ b/src/bnetd/userlog.cpp @@ -140,9 +140,9 @@ namespace pvpgn std::strftime(time_string, USEREVENT_TIME_MAXLEN, USEREVENT_TIME_FORMAT, tmnow); - const char* const filename = userlog_filename(account_get_name(account), true); + std::string filename = userlog_filename(account_get_name(account), true); - if (FILE *fp = fopen(filename, "a")) + if (FILE *fp = fopen(filename.c_str(), "a")) { // append date and text std::fprintf(fp, "[%s] %s\n", time_string, text); @@ -152,8 +152,6 @@ namespace pvpgn { ERROR1("could not write into user log file \"{}\"", filename); } - - xfree((void*)filename); } // read "count" lines from the end starting from "startline" @@ -162,12 +160,7 @@ namespace pvpgn if (!username) throw std::runtime_error("username is a nullptr"); - FILE* fp = nullptr; - { - const char* const filename = userlog_filename(username); - fp = std::fopen(filename, "r"); - xfree((void*)filename); - } + FILE* fp = std::fopen(userlog_filename(username).c_str(), "r"); if (!fp) throw std::runtime_error("Could not open userlog"); @@ -248,10 +241,8 @@ namespace pvpgn // return full path for user log filename // if (force_create_path == true) then create dirs in path if not exist - extern char * userlog_filename(const char * username, bool force_create_path) + extern std::string userlog_filename(const char * username, bool force_create_path) { - char * filepath; - // lowercase username std::string lusername = std::string(username); std::transform(lusername.begin(), lusername.end(), lusername.begin(), ::tolower); @@ -259,26 +250,20 @@ namespace pvpgn // it will improve performance with large count of files std::string dir_prefix = lusername.substr(0, 3); - filepath = buildpath(prefs_get_userlogdir(), dir_prefix.c_str()); + std::string filepath = fmt::format("{}/{}", prefs_get_userlogdir(), dir_prefix); // create directories in path if (force_create_path) { struct stat statbuf; // create inside user dir - if (stat(filepath, &statbuf) == -1) { - p_mkdir(filepath, S_IRWXU | S_IRWXG | S_IRWXO); + if (stat(filepath.c_str(), &statbuf) == -1) + { + p_mkdir(filepath.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); eventlog(eventlog_level_info, __FUNCTION__, "created user directory: {}", filepath); } } - char *tmp = new char[std::strlen(filepath) + 1]; - strcpy(tmp, filepath); - xfree(filepath); - - filepath = buildpath(tmp, lusername.c_str()); - delete[] tmp; - - std::strcat(filepath, ".log"); + filepath += fmt::format("/{}.log", lusername.c_str()); return filepath; } diff --git a/src/bnetd/userlog.h b/src/bnetd/userlog.h index a35f5ea..42e4eb6 100644 --- a/src/bnetd/userlog.h +++ b/src/bnetd/userlog.h @@ -37,7 +37,7 @@ namespace pvpgn extern void userlog_append(t_account * account, const char * text); extern std::map userlog_read(const char* username, long startline, const char* search_substr = nullptr); extern std::map userlog_find_text(const char * username, const char * search_substr, long startline); - extern char * userlog_filename(const char * username, bool force_create_path = false); + extern std::string userlog_filename(const char * username, bool force_create_path = false); extern int handle_log_command(t_connection * c, char const *text); diff --git a/src/common/util.cpp b/src/common/util.cpp index a6079cc..354e542 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -562,16 +562,6 @@ namespace pvpgn return i; } - extern char * buildpath(char const *root, const char *suffix) - { - char *result; - - result = (char*)xmalloc(std::strlen(root) + 1 + std::strlen(suffix) + 1); - - std::strcpy(result, root); std::strcat(result, "/"); std::strcat(result, suffix); - return result; - } - /* convert a time string to time_t time string format is: yyyy/mm/dd or yyyy-mm-dd or yyyy.mm.dd diff --git a/src/common/util.h b/src/common/util.h index efe2e3b..e96d2d1 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -42,7 +42,6 @@ namespace pvpgn extern char * unescape_chars(char const * in); extern void str_to_hex(char * target, char const * data, int datalen); extern int hex_to_str(char const * source, char * data, int datalen); - extern char * buildpath(char const *root, const char *suffix); extern int timestr_to_time(char const * timestr, std::time_t* ptime); static inline char * str_skip_space(char *str)