diff options
author | Andrei Karas <akaras@inbox.ru> | 2016-08-20 16:27:11 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-08-20 16:27:11 +0300 |
commit | af77eec4f736f989703f81df903a1a7c971fa659 (patch) | |
tree | ecadc9763347f1c6a04507f714e58f37f778533a /src/common | |
parent | 68947c86d5fe3eb2686c9b3393e3db0df083bb11 (diff) | |
parent | 9e02b4ed69ce857e3bda57c7f1d3b2457559c534 (diff) | |
download | hercules-af77eec4f736f989703f81df903a1a7c971fa659.tar.gz hercules-af77eec4f736f989703f81df903a1a7c971fa659.tar.bz2 hercules-af77eec4f736f989703f81df903a1a7c971fa659.tar.xz hercules-af77eec4f736f989703f81df903a1a7c971fa659.zip |
Merge pull request #1399 from HerculesWS/settings_libconfig
Ported the configuration to libconfig format
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/HPM.c | 52 | ||||
-rw-r--r-- | src/common/HPM.h | 6 | ||||
-rw-r--r-- | src/common/HPMi.h | 16 | ||||
-rw-r--r-- | src/common/mmo.h | 6 | ||||
-rw-r--r-- | src/common/socket.c | 314 | ||||
-rw-r--r-- | src/common/sql.c | 96 | ||||
-rw-r--r-- | src/common/sql.h | 2 |
7 files changed, 345 insertions, 147 deletions
diff --git a/src/common/HPM.c b/src/common/HPM.c index 8e0bbe992..a134a4822 100644 --- a/src/common/HPM.c +++ b/src/common/HPM.c @@ -2,7 +2,7 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2013-2015 Hercules Dev Team + * Copyright (C) 2013-2016 Hercules Dev Team * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -407,7 +407,7 @@ bool hpm_add_arg(unsigned int pluginID, char *name, bool has_param, CmdlineExecF * @retval true if the listener was added successfully. * @retval false in case of error. */ -bool hplugins_addconf(unsigned int pluginID, enum HPluginConfType type, char *name, void (*parse_func) (const char *key, const char *val), int (*return_func) (const char *key)) +bool hplugins_addconf(unsigned int pluginID, enum HPluginConfType type, char *name, void (*parse_func) (const char *key, const char *val), int (*return_func) (const char *key), bool required) { struct HPConfListenStorage *conf; int i; @@ -442,6 +442,7 @@ bool hplugins_addconf(unsigned int pluginID, enum HPluginConfType type, char *na safestrncpy(conf->key, name, HPM_ADDCONF_LENGTH); conf->parse_func = parse_func; conf->return_func = return_func; + conf->required = required; return true; } @@ -859,6 +860,52 @@ bool hplugins_get_battle_conf(const char *w1, int *value) } /** + * Parses battle config entries registered by plugins. + * + * @param config The configuration file to parse. + * @param filename Path to configuration file. + * @param imported Whether the current config is imported from another file. + * @retval false in case of error. + */ +bool hplugins_parse_battle_conf(const struct config_t *config, const char *filename, bool imported) +{ + const struct config_setting_t *setting = NULL; + int i, val, type; + char str[1024]; + bool retval = true; + + nullpo_retr(false, config); + + for (i = 0; i < VECTOR_LENGTH(HPM->config_listeners[HPCT_BATTLE]); i++) { + const struct HPConfListenStorage *entry = &VECTOR_INDEX(HPM->config_listeners[HPCT_BATTLE], i); + const char *config_name = entry->key; + if ((setting = libconfig->lookup(config, config_name)) == NULL) { + if (!imported && entry->required) { + ShowWarning("Missing configuration '%s' in file %s!\n", config_name, filename); + retval = false; + } + continue; + } + + switch ((type = config_setting_type(setting))) { + case CONFIG_TYPE_INT: + val = libconfig->setting_get_int(setting); + break; + case CONFIG_TYPE_BOOL: + val = libconfig->setting_get_bool(setting); + break; + default: // Unsupported type + ShowWarning("Setting %s has unsupported type %d, ignoring...\n", config_name, type); + retval = false; + continue; + } + sprintf(str, "%d", val); // FIXME: Remove this when support to int's as value is added + entry->parse_func(config_name, str); + } + return retval; +} + +/** * Helper to destroy an interface's hplugin_data store and release any owned memory. * * The pointer will be cleared. @@ -1074,6 +1121,7 @@ void hpm_defaults(void) HPM->parse_packets = hplugins_parse_packets; HPM->load_sub = NULL; HPM->parseConf = hplugins_parse_conf; + HPM->parse_battle_conf = hplugins_parse_battle_conf; HPM->getBattleConf = hplugins_get_battle_conf; HPM->DataCheck = HPM_DataCheck; HPM->datacheck_init = HPM_datacheck_init; diff --git a/src/common/HPM.h b/src/common/HPM.h index 0b1275fde..43f610a6a 100644 --- a/src/common/HPM.h +++ b/src/common/HPM.h @@ -2,7 +2,7 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2013-2015 Hercules Dev Team + * Copyright (C) 2013-2016 Hercules Dev Team * * Hercules is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -65,7 +65,9 @@ #endif // WIN32 +/* Forward Declarations */ struct HPMHooking_core_interface; +struct config_t; struct hplugin { DLL dll; @@ -121,6 +123,7 @@ struct HPConfListenStorage { char key[HPM_ADDCONF_LENGTH]; void (*parse_func) (const char *key, const char *val); int (*return_func) (const char *key); + bool required; }; /* Hercules Plugin Manager Interface */ @@ -155,6 +158,7 @@ struct HPM_interface { void *(*import_symbol) (char *name, unsigned int pID); void (*share) (void *value, const char *name); void (*config_read) (void); + bool (*parse_battle_conf) (const struct config_t *config, const char *filename, bool imported); char *(*pid2name) (unsigned int pid); unsigned char (*parse_packets) (int fd, int packet_id, enum HPluginPacketHookingPoints point); void (*load_sub) (struct hplugin *plugin); diff --git a/src/common/HPMi.h b/src/common/HPMi.h index e16eb1d75..19b9b20a5 100644 --- a/src/common/HPMi.h +++ b/src/common/HPMi.h @@ -188,19 +188,19 @@ enum HPluginConfType { /* HPMi->addPacket */ #define addPacket(cmd,len,receive,point) HPMi->addPacket(cmd,len,receive,point,HPMi->pid) /* HPMi->addBattleConf */ -#define addBattleConf(bcname,funcname,returnfunc) HPMi->addConf(HPMi->pid,HPCT_BATTLE,bcname,funcname,returnfunc) +#define addBattleConf(bcname, funcname, returnfunc, required) HPMi->addConf(HPMi->pid, HPCT_BATTLE, bcname, funcname, returnfunc, required) /* HPMi->addLogin */ -#define addLoginConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_LOGIN,bcname,funcname,NULL) +#define addLoginConf(bcname, funcname) HPMi->addConf(HPMi->pid, HPCT_LOGIN, bcname, funcname, NULL, false) /* HPMi->addChar */ -#define addCharConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_CHAR,bcname,funcname,NULL) +#define addCharConf(bcname, funcname) HPMi->addConf(HPMi->pid, HPCT_CHAR, bcname, funcname, NULL, false) /* HPMi->addCharInter */ -#define addCharInterConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_CHAR_INTER,bcname,funcname,NULL) +#define addCharInterConf(bcname, funcname) HPMi->addConf(HPMi->pid, HPCT_CHAR_INTER, bcname, funcname, NULL, false) /* HPMi->addMapInter */ -#define addMapInterConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_MAP_INTER,bcname,funcname,NULL) +#define addMapInterConf(bcname, funcname) HPMi->addConf(HPMi->pid, HPCT_MAP_INTER, bcname, funcname, NULL, false) /* HPMi->addLog */ -#define addLogConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_LOG,bcname,funcname,NULL) +#define addLogConf(bcname, funcname) HPMi->addConf(HPMi->pid, HPCT_LOG, bcname, funcname, NULL, false) /* HPMi->addScript */ -#define addScriptConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_SCRIPT,bcname,funcname,NULL) +#define addScriptConf(bcname, funcname) HPMi->addConf(HPMi->pid, HPCT_SCRIPT, bcname, funcname, NULL, false) /* HPMi->addPCGPermission */ #define addGroupPermission(pcgname,maskptr) HPMi->addPCGPermission(HPMi->pid,pcgname,&maskptr) @@ -223,7 +223,7 @@ struct HPMi_interface { /* program --arg/-a */ bool (*addArg) (unsigned int pluginID, char *name, bool has_param, CmdlineExecFunc func, const char *help); /* battle-config recv param */ - bool (*addConf) (unsigned int pluginID, enum HPluginConfType type, char *name, void (*parse_func) (const char *key, const char *val), int (*return_func) (const char *key)); + bool (*addConf) (unsigned int pluginID, enum HPluginConfType type, char *name, void (*parse_func) (const char *key, const char *val), int (*return_func) (const char *key), bool required); /* pc group permission */ void (*addPCGPermission) (unsigned int pluginID, char *name, unsigned int *mask); diff --git a/src/common/mmo.h b/src/common/mmo.h index 0a5d9d053..77f706f0d 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -185,9 +185,6 @@ #ifndef MAX_QUEST_OBJECTIVES #define MAX_QUEST_OBJECTIVES 3 // Max quest objectives for a quest #endif -#ifndef MAX_START_ITEMS -#define MAX_START_ITEMS 32 // Max number of items allowed to be given to a char whenever it's created. [mkbu95] -#endif // for produce #define MIN_ATTRIBUTE 0 @@ -360,7 +357,7 @@ enum equip_pos { struct point { unsigned short map; - short x,y; + int16 x, y; }; enum e_skill_flag @@ -1068,6 +1065,7 @@ enum e_char_server_type { CST_OVER18 = 2, CST_PAYING = 3, CST_F2P = 4, + CST_MAX, }; enum e_pc_reg_loading { diff --git a/src/common/socket.c b/src/common/socket.c index af5e8aa73..cee2875d5 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -2,7 +2,7 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2012-2015 Hercules Dev Team + * Copyright (C) 2012-2016 Hercules Dev Team * Copyright (C) Athena Dev Teams * * Hercules is free software: you can redistribute it and/or modify @@ -80,6 +80,8 @@ struct socket_interface *sockt; struct socket_data **session; +const char *SOCKET_CONF_FILENAME = "conf/common/socket.conf"; + #ifdef SEND_SHORTLIST // Add a fd to the shortlist so that it'll be recognized as a fd that needs // sending done on it. @@ -1059,17 +1061,19 @@ int do_sockets(int next) ////////////////////////////// // IP rules and DDoS protection -typedef struct connect_history { +struct connect_history { uint32 ip; int64 tick; int count; unsigned ddos : 1; -} ConnectHistory; +}; -typedef struct access_control { +struct access_control { uint32 ip; uint32 mask; -} AccessControl; +}; + +VECTOR_STRUCT_DECL(access_control_list, struct access_control); enum aco { ACO_DENY_ALLOW, @@ -1077,11 +1081,9 @@ enum aco { ACO_MUTUAL_FAILURE }; -static AccessControl* access_allow = NULL; -static AccessControl* access_deny = NULL; +static struct access_control_list access_allow; +static struct access_control_list access_deny; static int access_order = ACO_DENY_ALLOW; -static int access_allownum = 0; -static int access_denynum = 0; static int access_debug = 0; static int ddos_count = 10; static int ddos_interval = 3*1000; @@ -1106,33 +1108,35 @@ static int connect_check(uint32 ip) /// 1 or 2 : Connection Accepted static int connect_check_(uint32 ip) { - ConnectHistory* hist = NULL; + struct connect_history *hist = NULL; int i; int is_allowip = 0; int is_denyip = 0; int connect_ok = 0; // Search the allow list - for( i=0; i < access_allownum; ++i ){ - if (SUBNET_MATCH(ip, access_allow[i].ip, access_allow[i].mask)) { - if( access_debug ){ + for (i = 0; i < VECTOR_LENGTH(access_allow); ++i) { + struct access_control *entry = &VECTOR_INDEX(access_allow, i); + if (SUBNET_MATCH(ip, entry->ip, entry->mask)) { + if (access_debug) { ShowInfo("connect_check: Found match from allow list:%u.%u.%u.%u IP:%u.%u.%u.%u Mask:%u.%u.%u.%u\n", CONVIP(ip), - CONVIP(access_allow[i].ip), - CONVIP(access_allow[i].mask)); + CONVIP(entry->ip), + CONVIP(entry->mask)); } is_allowip = 1; break; } } // Search the deny list - for( i=0; i < access_denynum; ++i ){ - if (SUBNET_MATCH(ip, access_deny[i].ip, access_deny[i].mask)) { - if( access_debug ){ + for (i = 0; i < VECTOR_LENGTH(access_deny); ++i) { + struct access_control *entry = &VECTOR_INDEX(access_deny, i); + if (SUBNET_MATCH(ip, entry->ip, entry->mask)) { + if (access_debug) { ShowInfo("connect_check: Found match from deny list:%u.%u.%u.%u IP:%u.%u.%u.%u Mask:%u.%u.%u.%u\n", CONVIP(ip), - CONVIP(access_deny[i].ip), - CONVIP(access_deny[i].mask)); + CONVIP(entry->ip), + CONVIP(entry->mask)); } is_denyip = 1; break; @@ -1187,7 +1191,7 @@ static int connect_check_(uint32 ip) } } // IP not found, add to history - CREATE(hist, ConnectHistory, 1); + CREATE(hist, struct connect_history, 1); hist->ip = ip; hist->tick = timer->gettick(); uidb_put(connect_history, ip, hist); @@ -1199,7 +1203,7 @@ static int connect_check_(uint32 ip) static int connect_check_clear(int tid, int64 tick, int id, intptr_t data) { int clear = 0; int list = 0; - ConnectHistory *hist = NULL; + struct connect_history *hist = NULL; struct DBIterator *iter; if( !db_size(connect_history) ) @@ -1227,7 +1231,7 @@ static int connect_check_clear(int tid, int64 tick, int id, intptr_t data) { /// Parses the ip address and mask and puts it into acc. /// Returns 1 is successful, 0 otherwise. -int access_ipmask(const char* str, AccessControl* acc) +int access_ipmask(const char *str, struct access_control *acc) { uint32 ip; uint32 mask; @@ -1270,82 +1274,210 @@ int access_ipmask(const char* str, AccessControl* acc) acc->mask = mask; return 1; } + +/** + * Adds an entry to the access list. + * + * @param setting The setting to read from. + * @param list_name The list name (used in error messages). + * @param access_list The access list to edit. + * + * @retval false in case of failure + */ +bool access_list_add(struct config_setting_t *setting, const char *list_name, struct access_control_list *access_list) +{ + const char *temp = NULL; + int i, setting_length; + + nullpo_retr(false, setting); + nullpo_retr(false, list_name); + nullpo_retr(false, access_list); + + if ((setting_length = libconfig->setting_length(setting)) <= 0) + return false; + + VECTOR_ENSURE(*access_list, setting_length, 1); + for (i = 0; i < setting_length; i++) { + struct access_control acc; + if ((temp = libconfig->setting_get_string_elem(setting, i)) == NULL) { + continue; + } + + if (!access_ipmask(temp, &acc)) { + ShowError("access_list_add: Invalid ip or ip range %s '%d'!\n", list_name, i); + continue; + } + VECTOR_PUSH(*access_list, acc); + } + + return true; +} + ////////////////////////////// #endif // MINICORE ////////////////////////////// -int socket_config_read(const char* cfgName) +/** + * Reads 'socket_configuration/ip_rules' and initializes required variables. + * + * @param filename Path to configuration file (used in error and warning messages). + * @param config The current config being parsed. + * @param imported Whether the current config is imported from another file. + * + * @retval false in case of error. + */ +bool socket_config_read_iprules(const char *filename, struct config_t *config, bool imported) { - char line[1024],w1[1024],w2[1024]; - FILE *fp; +#ifndef MINICORE + struct config_setting_t *setting = NULL; + const char *temp = NULL; - fp = fopen(cfgName, "r"); - if(fp == NULL) { - ShowError("File not found: %s\n", cfgName); - return 1; + nullpo_retr(false, filename); + nullpo_retr(false, config); + + if ((setting = libconfig->lookup(config, "socket_configuration/ip_rules")) == NULL) { + if (imported) + return true; + ShowError("socket_config_read: socket_configuration/ip_rules was not found in %s!\n", filename); + return false; } + libconfig->setting_lookup_bool(setting, "enable", &ip_rules); - while (fgets(line, sizeof(line), fp)) { - if(line[0] == '/' && line[1] == '/') - continue; - if (sscanf(line, "%1023[^:]: %1023[^\r\n]", w1, w2) != 2) - continue; + if (!ip_rules) + return true; - if (!strcmpi(w1, "stall_time")) { - sockt->stall_time = atoi(w2); - if( sockt->stall_time < 3 ) - sockt->stall_time = 3;/* a minimum is required to refrain it from killing itself */ - } -#ifdef SOCKET_EPOLL - else if(!strcmpi(w1, "epoll_maxevents")) { - epoll_maxevents = atoi(w2); - if(epoll_maxevents < 16){ - epoll_maxevents = 16; // minimum that seems to be useful - } + if (libconfig->setting_lookup_string(setting, "order", &temp) == CONFIG_TRUE) { + if (strcmpi(temp, "deny,allow" ) == 0) { + access_order = ACO_DENY_ALLOW; + } else if (strcmpi(temp, "allow, deny") == 0) { + access_order = ACO_ALLOW_DENY; + } else if (strcmpi(temp, "mutual-failure") == 0) { + access_order = ACO_MUTUAL_FAILURE; + } else { + ShowWarning("socket_config_read: invalid value '%s' for socket_configuration/ip_rules/order.\n", temp); } + } + + if ((setting = libconfig->lookup(config, "socket_configuration/ip_rules/allow_list")) == NULL) { + if (!imported) + ShowError("socket_config_read: socket_configuration/ip_rules/allow_list was not found in %s!\n", filename); + } else { + access_list_add(setting, "allow_list", &access_allow); + } + + if ((setting = libconfig->lookup(config, "socket_configuration/ip_rules/deny_list")) == NULL) { + if (!imported) + ShowError("socket_config_read: socket_configuration/ip_rules/deny_list was not found in %s!\n", filename); + } else { + access_list_add(setting, "deny_list", &access_deny); + } +#endif // ! MINICORE + + return true; +} + +/** + * Reads 'socket_configuration/ddos' and initializes required variables. + * + * @param filename Path to configuration file (used in error and warning messages). + * @param config The current config being parsed. + * @param imported Whether the current config is imported from another file. + * + * @retval false in case of error. + */ +bool socket_config_read_ddos(const char *filename, struct config_t *config, bool imported) +{ +#ifndef MINICORE + struct config_setting_t *setting = NULL; + + nullpo_retr(false, filename); + nullpo_retr(false, config); + + if ((setting = libconfig->lookup(config, "socket_configuration/ddos")) == NULL) { + if (imported) + return true; + ShowError("socket_config_read: socket_configuration/ddos was not found in %s!\n", filename); + return false; + } + + libconfig->setting_lookup_int(setting, "interval", &ddos_interval); + libconfig->setting_lookup_int(setting, "count", &ddos_count); + libconfig->setting_lookup_int(setting, "autoreset", &ddos_autoreset); + +#endif // ! MINICORE + return true; +} + +/** + * Reads 'socket_configuration' and initializes required variables. + * + * @param filename Path to configuration file. + * @param imported Whether the current config is imported from another file. + * + * @retval false in case of error. + */ +bool socket_config_read(const char *filename, bool imported) +{ + struct config_t config; + struct config_setting_t *setting = NULL; + const char *import; + int i32 = 0; + bool retval = true; + + nullpo_retr(false, filename); + + if (!libconfig->load_file(&config, filename)) + return false; + + if ((setting = libconfig->lookup(&config, "socket_configuration")) == NULL) { + libconfig->destroy(&config); + if (imported) + return true; + ShowError("socket_config_read: socket_configuration was not found in %s!\n", filename); + return false; + } + + if (libconfig->setting_lookup_int(setting, "stall_time", &i32) == CONFIG_TRUE) { + if (i32 < 3) + i32 = 3; /* a minimum is required in order to refrain from killing itself */ + sockt->stall_time = i32; + } + +#ifdef SOCKET_EPOLL + if (libconfig->setting_lookup_int(setting, "epoll_maxevents", &i32) == CONFIG_TRUE) { + if (i32 < 16) + i32 = 16; // minimum that seems to be useful + epoll_maxevents = i32; + } #endif // SOCKET_EPOLL + #ifndef MINICORE - else if (!strcmpi(w1, "enable_ip_rules")) { - ip_rules = config_switch(w2); - } else if (!strcmpi(w1, "order")) { - if (!strcmpi(w2, "deny,allow")) - access_order = ACO_DENY_ALLOW; - else if (!strcmpi(w2, "allow,deny")) - access_order = ACO_ALLOW_DENY; - else if (!strcmpi(w2, "mutual-failure")) - access_order = ACO_MUTUAL_FAILURE; - } else if (!strcmpi(w1, "allow")) { - RECREATE(access_allow, AccessControl, access_allownum+1); - if (access_ipmask(w2, &access_allow[access_allownum])) - ++access_allownum; - else - ShowError("socket_config_read: Invalid ip or ip range '%s'!\n", line); - } else if (!strcmpi(w1, "deny")) { - RECREATE(access_deny, AccessControl, access_denynum+1); - if (access_ipmask(w2, &access_deny[access_denynum])) - ++access_denynum; - else - ShowError("socket_config_read: Invalid ip or ip range '%s'!\n", line); + { + uint32 ui32 = 0; + libconfig->setting_lookup_bool(setting, "debug", &access_debug); + if (libconfig->setting_lookup_uint32(setting, "socket_max_client_packet", &ui32) == CONFIG_TRUE) { + socket_max_client_packet = ui32; } - else if (!strcmpi(w1,"ddos_interval")) - ddos_interval = atoi(w2); - else if (!strcmpi(w1,"ddos_count")) - ddos_count = atoi(w2); - else if (!strcmpi(w1,"ddos_autoreset")) - ddos_autoreset = atoi(w2); - else if (!strcmpi(w1,"debug")) - access_debug = config_switch(w2); - else if (!strcmpi(w1,"socket_max_client_packet")) - socket_max_client_packet = strtoul(w2, NULL, 0); -#endif // MINICORE - else if (!strcmpi(w1, "import")) - socket_config_read(w2); - else - ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName); } - fclose(fp); - return 0; + if (!socket_config_read_iprules(filename, &config, imported)) + retval = false; + if (!socket_config_read_ddos(filename, &config, imported)) + retval = false; +#endif // MINICORE + + // import should overwrite any previous configuration, so it should be called last + if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) { + if (strcmp(import, filename) == 0 || strcmp(import, SOCKET_CONF_FILENAME) == 0) { + ShowWarning("socket_config_read: Loop detected! Skipping 'import'...\n"); + } else { + if (!socket_config_read(import, true)) + retval = false; + } + } + + libconfig->destroy(&config); + return retval; } void socket_final(void) @@ -1354,10 +1486,8 @@ void socket_final(void) #ifndef MINICORE if( connect_history ) db_destroy(connect_history); - if( access_allow ) - aFree(access_allow); - if( access_deny ) - aFree(access_deny); + VECTOR_CLEAR(access_allow); + VECTOR_CLEAR(access_deny); #endif // MINICORE for( i = 1; i < sockt->fd_max; i++ ) @@ -1496,7 +1626,6 @@ int socket_getips(uint32* ips, int max) void socket_init(void) { - char *SOCKET_CONF_FILENAME = "conf/packet.conf"; uint64 rlim_cur = FD_SETSIZE; #ifdef WIN32 @@ -1544,10 +1673,15 @@ void socket_init(void) } #endif // defined(HAVE_SETRLIMIT) && !defined(CYGWIN) +#ifndef MINICORE + VECTOR_INIT(access_allow); + VECTOR_INIT(access_deny); +#endif // ! MINICORE + // Get initial local ips sockt->naddr_ = sockt->getips(sockt->addr_,16); - socket_config_read(SOCKET_CONF_FILENAME); + socket_config_read(SOCKET_CONF_FILENAME, false); #ifndef SOCKET_EPOLL // Select based Event Dispatcher: diff --git a/src/common/sql.c b/src/common/sql.c index 9a90f9807..be0bd43e3 100644 --- a/src/common/sql.c +++ b/src/common/sql.c @@ -2,7 +2,7 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2012-2015 Hercules Dev Team + * Copyright (C) 2012-2016 Hercules Dev Team * Copyright (C) Athena Dev Teams * * Hercules is free software: you can redistribute it and/or modify @@ -23,7 +23,9 @@ #include "sql.h" #include "common/cbasetypes.h" +#include "common/conf.h" #include "common/memmgr.h" +#include "common/nullpo.h" #include "common/showmsg.h" #include "common/strlib.h" #include "common/timer.h" @@ -37,8 +39,8 @@ void hercules_mysql_error_handler(unsigned int ecode); -int mysql_reconnect_type; -unsigned int mysql_reconnect_count; +int mysql_reconnect_type = 2; +int mysql_reconnect_count = 1; struct sql_interface sql_s; struct sql_interface *SQL; @@ -868,55 +870,67 @@ void hercules_mysql_error_handler(unsigned int ecode) { switch( ecode ) { case 2003:/* Can't connect to MySQL (this error only happens here when failing to reconnect) */ if( mysql_reconnect_type == 1 ) { - static unsigned int retry = 1; + static int retry = 1; if( ++retry > mysql_reconnect_count ) { - ShowFatalError("MySQL has been unreachable for too long, %u reconnects were attempted. Shutting Down\n", retry); + ShowFatalError("MySQL has been unreachable for too long, %d reconnects were attempted. Shutting Down\n", retry); exit(EXIT_FAILURE); } } break; } } -void Sql_inter_server_read(const char* cfgName, bool first) { - char line[1024], w1[1024], w2[1024]; - FILE* fp; - - fp = fopen(cfgName, "r"); - if(fp == NULL) { - if( first ) { - ShowFatalError("File not found: %s\n", cfgName); - exit(EXIT_FAILURE); - } else - ShowError("File not found: %s\n", cfgName); - return; + +/** + * Parses mysql_reconnect from inter_configuration. + * + * @param filename Path to configuration file. + * @param imported Whether the current config is imported from another file. + * + * @retval false in case of error. + */ +bool Sql_inter_server_read(const char *filename, bool imported) +{ + struct config_t config; + const struct config_setting_t *setting = NULL; + const char *import = NULL; + bool retval = true; + + nullpo_retr(false, filename); + + if (!libconfig->load_file(&config, filename)) + return false; + + if ((setting = libconfig->lookup(&config, "inter_configuration/mysql_reconnect")) == NULL) { + config_destroy(&config); + if (imported) + return true; + ShowError("Sql_inter_server_read: inter_configuration/mysql_reconnect was not found in %s!\n", filename); + return false; } - while (fgets(line, sizeof(line), fp)) { - int i = sscanf(line, "%1023[^:]: %1023[^\r\n]", w1, w2); - if (i != 2) - continue; + if (libconfig->setting_lookup_int(setting, "type", &mysql_reconnect_type) == CONFIG_TRUE) { + if (mysql_reconnect_type != 1 && mysql_reconnect_type != 2) { + ShowError("%s::inter_configuration/mysql_reconnect/type is set to %d which is not valid, defaulting to 1...\n", filename, mysql_reconnect_type); + mysql_reconnect_type = 1; + } + } + if (libconfig->setting_lookup_int(setting, "count", &mysql_reconnect_count) == CONFIG_TRUE) { + if (mysql_reconnect_count < 1) + mysql_reconnect_count = 1; + } - if(!strcmpi(w1,"mysql_reconnect_type")) { - mysql_reconnect_type = atoi(w2); - switch( mysql_reconnect_type ) { - case 1: - case 2: - break; - default: - ShowError("%s::mysql_reconnect_type is set to %d which is not valid, defaulting to 1...\n", cfgName, mysql_reconnect_type); - mysql_reconnect_type = 1; - break; - } - } else if(!strcmpi(w1,"mysql_reconnect_count")) { - mysql_reconnect_count = atoi(w2); - if( mysql_reconnect_count < 1 ) - mysql_reconnect_count = 1; - } else if(!strcmpi(w1,"import")) - Sql_inter_server_read(w2,false); + // import should overwrite any previous configuration, so it should be called last + if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) { + if (strcmp(import, filename) == 0 || strcmp(import, "conf/common/inter-server.conf") == 0) { // FIXME: Hardcoded path + ShowWarning("Sql_inter_server_read: Loop detected in %s! Skipping 'import'...\n", filename); + } else { + if (!Sql_inter_server_read(import, true)) + retval = false; + } } - fclose(fp); - return; + libconfig->destroy(&config); + return retval; } void Sql_HerculesUpdateCheck(struct Sql *self) @@ -1019,7 +1033,7 @@ void Sql_HerculesUpdateSkip(struct Sql *self, const char *filename) } void Sql_Init(void) { - Sql_inter_server_read("conf/inter-server.conf",true); + Sql_inter_server_read("conf/common/inter-server.conf", false); // FIXME: Hardcoded path } void sql_defaults(void) { SQL = &sql_s; diff --git a/src/common/sql.h b/src/common/sql.h index 07be829fc..4d9a12cc1 100644 --- a/src/common/sql.h +++ b/src/common/sql.h @@ -2,7 +2,7 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2012-2015 Hercules Dev Team + * Copyright (C) 2012-2016 Hercules Dev Team * Copyright (C) Athena Dev Teams * * Hercules is free software: you can redistribute it and/or modify |