- Improved code safety

- Fixed bug in /ipscan command
- Restored icons_STAR.bni
This commit is contained in:
RElesgoe 2017-03-21 03:20:06 -07:00
parent 38c78a5a1c
commit 3b46205114
23 changed files with 173 additions and 180 deletions

View file

@ -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"
# #
##############################################################################

View file

@ -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"
# #
##############################################################################

View file

@ -10,4 +10,5 @@ bnserver-D2XP.ini
bnserver-WAR3.ini
bnserver.ini
icons-WAR3.bni
icons_STAR.bni
icons.bni

View file

@ -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)

BIN
files/icons_STAR.bni Normal file

Binary file not shown.

View file

@ -4550,7 +4550,6 @@ namespace pvpgn
t_account * account;
t_connection * conn;
char const * ip;
std::vector<std::string> 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;
}

View file

@ -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;
}

View file

@ -21,6 +21,7 @@
#include <cstring>
#include <cerrno>
#include <string>
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
@ -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)

View file

@ -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';

View file

@ -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;

View file

@ -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;
}

View file

@ -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);

View file

@ -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());

View file

@ -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();

View file

@ -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;
}

View file

@ -20,6 +20,7 @@
#include <cstdio>
#include <cerrno>
#include <cstring>
#include <string>
#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;
}
}

View file

@ -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();
}

View file

@ -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;

View file

@ -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);

View file

@ -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;
}

View file

@ -37,7 +37,7 @@ namespace pvpgn
extern void userlog_append(t_account * account, const char * text);
extern std::map<long, char*> userlog_read(const char* username, long startline, const char* search_substr = nullptr);
extern std::map<long, char*> 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);

View file

@ -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

View file

@ -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)