diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/HPM.c | 5 | ||||
-rw-r--r-- | src/common/HPM.h | 2 | ||||
-rw-r--r-- | src/common/HPMDataCheck.h | 5 | ||||
-rw-r--r-- | src/common/HPMi.h | 16 | ||||
-rw-r--r-- | src/common/Makefile.in | 24 | ||||
-rw-r--r-- | src/common/console.c | 15 | ||||
-rw-r--r-- | src/common/console.h | 4 | ||||
-rw-r--r-- | src/common/core.c | 151 | ||||
-rw-r--r-- | src/common/core.h | 14 | ||||
-rw-r--r-- | src/common/des.h | 5 | ||||
-rw-r--r-- | src/common/grfio.h | 4 | ||||
-rw-r--r-- | src/common/malloc.c | 8 | ||||
-rw-r--r-- | src/common/mmo.h | 142 | ||||
-rw-r--r-- | src/common/socket.h | 2 | ||||
-rw-r--r-- | src/common/sysinfo.c | 1022 | ||||
-rw-r--r-- | src/common/sysinfo.h | 62 | ||||
-rw-r--r-- | src/common/timer.h | 4 |
17 files changed, 1248 insertions, 237 deletions
diff --git a/src/common/HPM.c b/src/common/HPM.c index 971eb83bd..9ffce87de 100644 --- a/src/common/HPM.c +++ b/src/common/HPM.c @@ -13,6 +13,7 @@ #include "../common/console.h" #include "../common/strlib.h" #include "../common/sql.h" +#include "../common/sysinfo.h" #include "HPM.h" #include <stdio.h> @@ -703,8 +704,6 @@ void hplugins_share_defaults(void) { HPM->share(&arg_c,"arg_c"); HPM->share(SERVER_NAME,"SERVER_NAME"); HPM->share(&SERVER_TYPE,"SERVER_TYPE"); - HPM->share((void*)get_svn_revision,"get_svn_revision"); - HPM->share((void*)get_git_hash,"get_git_hash"); HPM->share(DB, "DB"); HPM->share(HPMiMalloc, "iMalloc"); /* socket */ @@ -719,6 +718,8 @@ void hplugins_share_defaults(void) { HPM->share(timer,"timer"); /* libconfig */ HPM->share(libconfig,"libconfig"); + /* sysinfo */ + HPM->share(sysinfo,"sysinfo"); } void hpm_init(void) { diff --git a/src/common/HPM.h b/src/common/HPM.h index b466cb4f3..0f0df4cda 100644 --- a/src/common/HPM.h +++ b/src/common/HPM.h @@ -1,7 +1,7 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. // See the LICENSE file -#ifndef _COMMON_HPM_H_ +#ifndef _COMMON_HPM_H_ #define _COMMON_HPM_H_ #include "../common/cbasetypes.h" diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h index 6eef028b2..f202ac306 100644 --- a/src/common/HPMDataCheck.h +++ b/src/common/HPMDataCheck.h @@ -51,6 +51,11 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = { #else #define _COMMON_STRLIB_H_ #endif // _COMMON_STRLIB_H_ + #ifdef _COMMON_SYSINFO_H_ + { "sysinfo_interface", sizeof(struct sysinfo_interface) }, + #else + #define _COMMON_SYSINFO_H_ + #endif // _COMMON_SYSINFO_H_ #ifdef _MAP_ATCOMMAND_H_ { "AliasInfo", sizeof(struct AliasInfo) }, { "atcommand_interface", sizeof(struct atcommand_interface) }, diff --git a/src/common/HPMi.h b/src/common/HPMi.h index 95037fd14..19206aeca 100644 --- a/src/common/HPMi.h +++ b/src/common/HPMi.h @@ -1,7 +1,7 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. // See the LICENSE file -#ifndef _COMMON_HPMI_H_ +#ifndef _COMMON_HPMI_H_ #define _COMMON_HPMI_H_ #include "../common/cbasetypes.h" @@ -67,13 +67,13 @@ enum hp_event_types { }; enum HPluginPacketHookingPoints { - hpClif_Parse, /* map-server (client-map) */ - hpChrif_Parse, /* map-server (char-map) */ - hpParse_FromMap, /* char-server (map-char) */ - hpParse_FromLogin, /* char-server (login-char) */ - hpParse_Char, /* char-server (client-char) */ - hpParse_FromChar, /* login-server (char-login) */ - hpParse_Login, /* login-server (client-login) */ + hpClif_Parse, ///< map-server (client-map) + hpChrif_Parse, ///< map-server (char-map) + hpParse_FromMap, ///< char-server (map-char) + hpParse_FromLogin, ///< char-server (login-char) + hpParse_Char, ///< char-server (client-char) + hpParse_FromChar, ///< login-server (char-login) + hpParse_Login, ///< login-server (client-login) /* */ hpPHP_MAX, }; diff --git a/src/common/Makefile.in b/src/common/Makefile.in index 7bb9ae630..623c59c2e 100644 --- a/src/common/Makefile.in +++ b/src/common/Makefile.in @@ -1,3 +1,5 @@ +# Copyright (c) Hercules Dev Team, licensed under GNU GPL. +# See the LICENSE file CONFIG_D = ../config CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h) @@ -15,8 +17,8 @@ MT19937AR_H = $(MT19937AR_D)/mt19937ar.h MT19937AR_INCLUDE = -I$(MT19937AR_D) COMMON_SHARED_C = conf.c db.c des.c ers.c grfio.c HPM.c mapindex.c md5calc.c \ - mutex.c nullpo.c random.c showmsg.c strlib.c thread.c \ - timer.c utils.c + mutex.c nullpo.c random.c showmsg.c strlib.c sysinfo.c \ + thread.c timer.c utils.c COMMON_C = $(COMMON_SHARED_C) COMMON_SHARED_OBJ = $(patsubst %.c,%.o,$(COMMON_SHARED_C)) COMMON_OBJ = $(addprefix obj_all/, $(COMMON_SHARED_OBJ) \ @@ -27,11 +29,12 @@ COMMON_C += console.c core.c malloc.c socket.c COMMON_H = atomic.h cbasetypes.h conf.h console.h core.h db.h des.h ers.h \ grfio.h HPM.h HPMi.h malloc.h mapindex.h md5calc.h mmo.h mutex.h \ nullpo.h random.h showmsg.h socket.h spinlock.h sql.h strlib.h \ - thread.h timer.h utils.h winapi.h + sysinfo.h thread.h timer.h utils.h winapi.h COMMON_SQL_OBJ = obj_sql/sql.o COMMON_SQL_H = sql.h COMMON_C += sql.c +SYSINFO_INC = sysinfo.inc HAVE_MYSQL=@HAVE_MYSQL@ ifeq ($(HAVE_MYSQL),yes) @@ -54,7 +57,7 @@ sql: $(SQL_DEPENDS) buildclean: @echo " CLEAN common (build temp files)" - @rm -rf *.o obj_all obj_sql + @rm -rf *.o obj_all obj_sql sysinfo.inc clean: buildclean @echo " CLEAN common" @@ -71,6 +74,10 @@ help: Makefile: Makefile.in @$(MAKE) -C ../.. src/common/Makefile +$(SYSINFO_INC): $(COMMON_C) $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) + @echo " MAKE $@" + @$(MAKE) -C ../.. sysinfo + needs_mysql: @echo "MySQL not found or disabled by the configure script" @exit 1 @@ -103,19 +110,20 @@ common_mini: $(COMMON_MINI_OBJ) $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) obj_all/common common_sql: $(COMMON_SQL_OBJ) obj_sql/common_sql.a Makefile -obj_all/%.o: %.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | obj_all +obj_all/sysinfo.o: sysinfo.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) $(SYSINFO_INC) | obj_all + +obj_all/%.o: %.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | $(SYSINFO_INC) obj_all @echo " CC $<" @$(CC) @CFLAGS@ $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) @CPPFLAGS@ -c $(OUTPUT_OPTION) $< -obj_all/mini%.o: %.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | obj_all +obj_all/mini%.o: %.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | $(SYSINFO_INC) obj_all @echo " CC $<" @$(CC) @CFLAGS@ $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) -DMINICORE @CPPFLAGS@ -c $(OUTPUT_OPTION) $< -obj_sql/%.o: %.c $(COMMON_H) $(COMMON_SQL_H) $(CONFIG_H) $(LIBCONFIG_H) | obj_sql +obj_sql/%.o: %.c $(COMMON_H) $(COMMON_SQL_H) $(CONFIG_H) $(LIBCONFIG_H) | $(SYSINFO_INC) obj_sql @echo " CC $<" @$(CC) @CFLAGS@ $(LIBCONFIG_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $< - # missing object files $(MT19937AR_OBJ): @echo " MAKE $@" diff --git a/src/common/console.c b/src/common/console.c index ec228b563..d8f352c8a 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -5,6 +5,7 @@ #include "../common/cbasetypes.h" #include "../common/showmsg.h" #include "../common/core.h" +#include "../common/sysinfo.h" #include "../config/core.h" #include "console.h" @@ -41,8 +42,7 @@ struct console_interface console_s; * CORE : Display title *--------------------------------------*/ void display_title(void) { - const char* svn = get_svn_revision(); - const char* git = get_git_hash(); + const char *vcstype = sysinfo->vcstype(); ShowMessage("\n"); ShowMessage(""CL_BG_RED""CL_BT_WHITE" "CL_CLL""CL_NORMAL"\n"); @@ -57,10 +57,13 @@ void display_title(void) { ShowMessage(""CL_BG_RED""CL_BT_WHITE" http://hercules.ws/board/ "CL_CLL""CL_NORMAL"\n"); ShowMessage(""CL_BG_RED""CL_BT_WHITE" "CL_CLL""CL_NORMAL"\n"); - if( git[0] != HERC_UNKNOWN_VER ) - ShowInfo("Git Hash: '"CL_WHITE"%s"CL_RESET"'\n", git); - else if( svn[0] != HERC_UNKNOWN_VER ) - ShowInfo("SVN Revision: '"CL_WHITE"%s"CL_RESET"'\n", svn); + ShowInfo("Hercules %d-bit for %s\n", sysinfo->is64bit() ? 64 : 32, sysinfo->platform()); + ShowInfo("%s revision (src): '"CL_WHITE"%s"CL_RESET"'\n", vcstype, sysinfo->vcsrevision_src()); + ShowInfo("%s revision (scripts): '"CL_WHITE"%s"CL_RESET"'\n", vcstype, sysinfo->vcsrevision_scripts()); + ShowInfo("OS version: '"CL_WHITE"%s"CL_RESET" [%s]'\n", sysinfo->osversion(), sysinfo->arch()); + ShowInfo("CPU: '"CL_WHITE"%s [%d]"CL_RESET"'\n", sysinfo->cpu(), sysinfo->cpucores()); + ShowInfo("Compiled with %s\n", sysinfo->compiler()); + ShowInfo("Compile Flags: %s\n", sysinfo->cflags()); } #ifdef CONSOLE_INPUT #if defined(WIN32) diff --git a/src/common/console.h b/src/common/console.h index bd1de4cbf..3d19ddc9d 100644 --- a/src/common/console.h +++ b/src/common/console.h @@ -1,8 +1,8 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. // See the LICENSE file -#ifndef _COMMON_CONSOLE_H_ -#define _COMMON_CONSOLE_H_ +#ifndef _COMMON_CONSOLE_H_ +#define _COMMON_CONSOLE_H_ #include "../common/thread.h" #include "../common/mutex.h" diff --git a/src/common/core.c b/src/common/core.c index c6075da40..798c832f0 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -9,6 +9,7 @@ #include "core.h" #include "../common/console.h" #include "../common/random.h" +#include "../common/sysinfo.h" #ifndef MINICORE #include "../common/db.h" @@ -78,7 +79,7 @@ sigfunc *compat_signal(int signo, sigfunc *func) { *--------------------------------------*/ #ifdef _WIN32 static BOOL WINAPI console_handler(DWORD c_event) { - switch(c_event) { + switch(c_event) { case CTRL_CLOSE_EVENT: case CTRL_LOGOFF_EVENT: case CTRL_SHUTDOWN_EVENT: @@ -89,8 +90,8 @@ static BOOL WINAPI console_handler(DWORD c_event) { break; default: return FALSE; - } - return TRUE; + } + return TRUE; } static void cevents_init() { @@ -152,134 +153,21 @@ void signals_init (void) { } #endif -const char* get_svn_revision(void) { - static char svn_version_buffer[16] = ""; - FILE *fp; - - if( svn_version_buffer[0] != '\0' ) - return svn_version_buffer; - - // subversion 1.7 uses a sqlite3 database - // FIXME this is hackish at best... - // - ignores database file structure - // - assumes the data in NODES.dav_cache column ends with "!svn/ver/<revision>/<path>)" - // - since it's a cache column, the data might not even exist - if( (fp = fopen(".svn"PATHSEP_STR"wc.db", "rb")) != NULL || (fp = fopen(".."PATHSEP_STR".svn"PATHSEP_STR"wc.db", "rb")) != NULL ) - { - #ifndef SVNNODEPATH - //not sure how to handle branches, so i'll leave this overridable define until a better solution comes up - #define SVNNODEPATH trunk - #endif - const char* prefix = "!svn/ver/"; - const char* postfix = "/"EXPAND_AND_QUOTE(SVNNODEPATH)")"; // there should exist only 1 entry like this - size_t prefix_len = strlen(prefix); - size_t postfix_len = strlen(postfix); - size_t i,j,len; - char* buffer; - - // read file to buffer - fseek(fp, 0, SEEK_END); - len = ftell(fp); - buffer = (char*)aMalloc(len + 1); - fseek(fp, 0, SEEK_SET); - len = fread(buffer, 1, len, fp); - buffer[len] = '\0'; - fclose(fp); - - // parse buffer - for( i = prefix_len + 1; i + postfix_len <= len; ++i ) { - if( buffer[i] != postfix[0] || memcmp(buffer + i, postfix, postfix_len) != 0 ) - continue; // postfix missmatch - for( j = i; j > 0; --j ) {// skip digits - if( !ISDIGIT(buffer[j - 1]) ) - break; - } - if( memcmp(buffer + j - prefix_len, prefix, prefix_len) != 0 ) - continue; // prefix missmatch - // done - snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", atoi(buffer + j)); - break; - } - aFree(buffer); - - if( svn_version_buffer[0] != '\0' ) - return svn_version_buffer; - } - - // subversion 1.6 and older? - if ((fp = fopen(".svn/entries", "r")) != NULL) { - char line[1024]; - int rev; - // Check the version - if (fgets(line, sizeof(line), fp)) { - if(!ISDIGIT(line[0])) { - // XML File format - while (fgets(line,sizeof(line),fp)) - if (strstr(line,"revision=")) break; - if (sscanf(line," %*[^\"]\"%d%*[^\n]", &rev) == 1) { - snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", rev); - } - } else { - // Bin File format - if ( fgets(line, sizeof(line), fp) == NULL ) { printf("Can't get bin name\n"); } // Get the name - if ( fgets(line, sizeof(line), fp) == NULL ) { printf("Can't get entries kind\n"); } // Get the entries kind - if(fgets(line, sizeof(line), fp)) { // Get the rev numver - snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", atoi(line)); - } - } - } - fclose(fp); - - if( svn_version_buffer[0] != '\0' ) - return svn_version_buffer; - } - - // fallback - svn_version_buffer[0] = HERC_UNKNOWN_VER; - return svn_version_buffer; -} -/* whats our origin */ -#define GIT_ORIGIN "refs/remotes/origin/master" -/* Grabs the hash from the last time the user updated his working copy (last pull) */ -const char *get_git_hash (void) { - static char HerculesGitHash[41] = "";//Sha(40) + 1 - FILE *fp; - - if( HerculesGitHash[0] != '\0' ) - return HerculesGitHash; - - if ( (fp = fopen (".git/"GIT_ORIGIN, "r")) != NULL) { - char line[64]; - char *rev = malloc (sizeof (char) * 50); - - if (fgets (line, sizeof (line), fp) && sscanf (line, "%50s", rev)) - snprintf (HerculesGitHash, sizeof (HerculesGitHash), "%s", rev); - - free (rev); - fclose (fp); - } else { - HerculesGitHash[0] = HERC_UNKNOWN_VER; - } - - if (! (*HerculesGitHash)) { - HerculesGitHash[0] = HERC_UNKNOWN_VER; - } - - return HerculesGitHash; -} -// Warning if executed as superuser (root) +/** + * Warns the user if executed as superuser (root) + */ void usercheck(void) { -#ifndef _WIN32 - if (geteuid() == 0) { - ShowWarning ("You are running Hercules with root privileges, it is not necessary.\n"); - } -#endif + if (sysinfo->is_superuser()) { + ShowWarning("You are running Hercules with root privileges, it is not necessary.\n"); + } } + void core_defaults(void) { #ifndef MINICORE hpm_defaults(); HCache_defaults(); #endif + sysinfo_defaults(); console_defaults(); strlib_defaults(); malloc_defaults(); @@ -318,16 +206,18 @@ int main (int argc, char **argv) { iMalloc->init();// needed for Show* in display_title() [FlavioJS] + sysinfo->init(); + if (!(msg_silent&0x1)) console->display_title(); - -#ifdef MINICORE // minimalist Core + usercheck(); + +#ifdef MINICORE // minimalist Core do_init(argc,argv); do_final(); #else// not MINICORE set_server_type(); - usercheck(); Sql_Init(); rathread_init(); @@ -348,10 +238,8 @@ int main (int argc, char **argv) { HCache->init(); -#ifndef MINICORE HPM->init(); -#endif - + sockt->init(); do_init(argc,argv); @@ -366,15 +254,14 @@ int main (int argc, char **argv) { console->final(); do_final(); -#ifndef MINICORE HPM->final(); -#endif timer->final(); sockt->final(); DB->final(); rathread_final(); ers_final(); #endif + sysinfo->final(); iMalloc->final(); diff --git a/src/common/core.h b/src/common/core.h index 72f956e1d..5c2f2c9a5 100644 --- a/src/common/core.h +++ b/src/common/core.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _COMMON_CORE_H_ -#define _COMMON_CORE_H_ +#ifndef _COMMON_CORE_H_ +#define _COMMON_CORE_H_ #include "../common/db.h" #include "../common/mmo.h" @@ -24,16 +24,14 @@ extern int runflag; extern char *SERVER_NAME; enum server_types { - SERVER_TYPE_UNKNOWN = 0x0, - SERVER_TYPE_LOGIN = 0x1, - SERVER_TYPE_CHAR = 0x2, - SERVER_TYPE_MAP = 0x4, + SERVER_TYPE_UNKNOWN = 0x0, + SERVER_TYPE_LOGIN = 0x1, + SERVER_TYPE_CHAR = 0x2, + SERVER_TYPE_MAP = 0x4, }; enum server_types SERVER_TYPE; -const char *get_svn_revision(void); -const char *get_git_hash (void); extern int do_init(int,char**); extern void set_server_type(void); extern void do_abort(void); diff --git a/src/common/des.h b/src/common/des.h index 3f55448ba..0f908a15b 100644 --- a/src/common/des.h +++ b/src/common/des.h @@ -1,8 +1,9 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _COMMON_DES_H_ -#define _COMMON_DES_H_ +#ifndef _COMMON_DES_H_ +#define _COMMON_DES_H_ +#include "../common/cbasetypes.h" /// One 64-bit block. typedef struct BIT64 { uint8_t b[8]; } BIT64; diff --git a/src/common/grfio.h b/src/common/grfio.h index 4f5d0d6bc..930ed7e36 100644 --- a/src/common/grfio.h +++ b/src/common/grfio.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _COMMON_GRFIO_H_ -#define _COMMON_GRFIO_H_ +#ifndef _COMMON_GRFIO_H_ +#define _COMMON_GRFIO_H_ void grfio_init(const char* fname); void grfio_final(void); diff --git a/src/common/malloc.c b/src/common/malloc.c index f7f108304..5b39cbab6 100644 --- a/src/common/malloc.c +++ b/src/common/malloc.c @@ -5,6 +5,7 @@ #include "../common/malloc.h" #include "../common/core.h" #include "../common/showmsg.h" +#include "../common/sysinfo.h" #include <stdio.h> #include <stdlib.h> @@ -574,17 +575,14 @@ static void memmgr_log (char *buf) if( !log_fp ) { time_t raw; struct tm* t; - const char* svn = get_svn_revision(); - const char* git = get_git_hash(); log_fp = fopen(memmer_logfile,"at"); if (!log_fp) log_fp = stdout; time(&raw); t = localtime(&raw); - fprintf(log_fp, "\nMemory manager: Memory leaks found at %d/%02d/%02d %02dh%02dm%02ds (rev %s).\n", - (t->tm_year+1900), (t->tm_mon+1), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, - git[0] != HERC_UNKNOWN_VER ? git : svn[0] != HERC_UNKNOWN_VER ? svn : "Unknown"); + fprintf(log_fp, "\nMemory manager: Memory leaks found at %d/%02d/%02d %02dh%02dm%02ds (%s rev '%s').\n", + (t->tm_year+1900), (t->tm_mon+1), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, sysinfo->vcstype(), sysinfo->vcsrevision_src()); } fprintf(log_fp, "%s", buf); return; diff --git a/src/common/mmo.h b/src/common/mmo.h index 0dd8d0f09..07a05677f 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _COMMON_MMO_H_ -#define _COMMON_MMO_H_ +#ifndef _COMMON_MMO_H_ +#define _COMMON_MMO_H_ #include "cbasetypes.h" #include "../common/db.h" @@ -60,7 +60,7 @@ // Client support for experimental RagexeRE UI present in 2012-04-10 and 2012-04-18 #if defined(PACKETVER_RE) && ( PACKETVER == 20120410 || PACKETVER == 20120418 ) -#define PARTY_RECRUIT +#define PARTY_RECRUIT #endif // PACKETVER_RE && (PACKETVER == 20120410 || PACKETVER == 10120418) // Comment the following line to disable sc_data saving. [Skotlex] @@ -113,11 +113,11 @@ #define MAX_GUILDPOSITION 20 // Increased max guild positions to accomodate for all members [Valaris] (removed) [PoW] #define MAX_GUILDEXPULSION 32 #define MAX_GUILDALLIANCE 16 -#define MAX_GUILDSKILL 15 // Increased max guild skills because of new skills [Sara-chan] +#define MAX_GUILDSKILL 15 // Increased max guild skills because of new skills [Sara-chan] #define MAX_GUILDLEVEL 50 #define MAX_GUARDIANS 8 // Local max per castle. [Skotlex] #define MAX_QUEST_OBJECTIVES 3 // Max quest objectives for a quest -#define MAX_START_ITEMS 32 // Max number of items allowed to be given to a char whenever it's created. [mkbu95] +#define MAX_START_ITEMS 32 // Max number of items allowed to be given to a char whenever it's created. [mkbu95] // for produce #define MIN_ATTRIBUTE 0 @@ -158,7 +158,7 @@ // Base Homun skill. #define HM_SKILLBASE 8001 #define MAX_HOMUNSKILL 43 -#define MAX_HOMUNCULUS_CLASS 52 // [orn] Increased to 60 from 16 to allow new Homun-S. +#define MAX_HOMUNCULUS_CLASS 52 // [orn] Increased to 60 from 16 to allow new Homun-S. #define HM_CLASS_BASE 6001 #define HM_CLASS_MAX (HM_CLASS_BASE+MAX_HOMUNCULUS_CLASS-1) @@ -230,6 +230,32 @@ struct item { uint64 unique_id; }; +//Equip position constants +enum equip_pos { + EQP_HEAD_LOW = 0x000001, + EQP_HEAD_MID = 0x000200, //512 + EQP_HEAD_TOP = 0x000100, //256 + EQP_HAND_R = 0x000002, //2 + EQP_HAND_L = 0x000020, //32 + EQP_ARMOR = 0x000010, //16 + EQP_SHOES = 0x000040, //64 + EQP_GARMENT = 0x000004, //4 + EQP_ACC_L = 0x000008, //8 + EQP_ACC_R = 0x000080, //128 + EQP_COSTUME_HEAD_TOP = 0x000400, //1024 + EQP_COSTUME_HEAD_MID = 0x000800, //2048 + EQP_COSTUME_HEAD_LOW = 0x001000, //4096 + EQP_COSTUME_GARMENT = 0x002000, //8192 + //UNUSED_COSTUME_FLOOR = 0x004000, //16384 + EQP_AMMO = 0x008000, //32768 + EQP_SHADOW_ARMOR = 0x010000, //65536 + EQP_SHADOW_WEAPON = 0x020000, //131072 + EQP_SHADOW_SHIELD = 0x040000, //262144 + EQP_SHADOW_SHOES = 0x080000, //524288 + EQP_SHADOW_ACC_R = 0x100000, //1048576 + EQP_SHADOW_ACC_L = 0x200000, //2097152 +}; + struct point { unsigned short map; short x,y; @@ -240,17 +266,17 @@ enum e_skill_flag SKILL_FLAG_PERMANENT, SKILL_FLAG_TEMPORARY, SKILL_FLAG_PLAGIARIZED, - SKILL_FLAG_UNUSED, /* needed to maintain the order since the values are saved, can be renamed and used if a new flag is necessary */ - SKILL_FLAG_PERM_GRANTED, // Permanent, granted through someway (e.g. script). + SKILL_FLAG_UNUSED, ///< needed to maintain the order since the values are saved, can be renamed and used if a new flag is necessary + SKILL_FLAG_PERM_GRANTED, ///< Permanent, granted through someway (e.g. script). /* */ /* MUST be the last, because with it the flag value stores a dynamic value (flag+lv) */ SKILL_FLAG_REPLACED_LV_0, // Temporary skill overshadowing permanent skill of level 'N - SKILL_FLAG_REPLACED_LV_0', }; enum e_mmo_charstatus_opt { - OPT_NONE = 0x0, - OPT_SHOW_EQUIP = 0x1, - OPT_ALLOW_PARTY = 0x2, + OPT_NONE = 0x0, + OPT_SHOW_EQUIP = 0x1, + OPT_ALLOW_PARTY = 0x2, }; enum e_item_bound_type { @@ -319,14 +345,14 @@ struct s_pet { char incuvate; }; -struct s_homunculus { //[orn] +struct s_homunculus { //[orn] char name[NAME_LENGTH]; int hom_id; int char_id; short class_; short prev_class; int hp,max_hp,sp,max_sp; - unsigned int intimacy; //[orn] + unsigned int intimacy; short hunger; struct s_skill hskill[MAX_HOMUNSKILL]; //albator short skillpts; @@ -503,7 +529,7 @@ struct party { unsigned char count; //Count of online characters. unsigned exp : 1, item : 2; //&1: Party-Share (round-robin), &2: pickup style: shared. - struct party_member member[MAX_PARTY]; + struct party_member member[MAX_PARTY]; }; struct map_session_data; @@ -607,14 +633,14 @@ enum fame_list_type { }; enum { //Change Guild Infos - GBI_EXP =1, // Guild Experience (EXP) - GBI_GUILDLV, // Guild level - GBI_SKILLPOINT, // Guild skillpoints - GBI_SKILLLV, // Guild skill_lv ?? seem unused + GBI_EXP = 1, ///< Guild Experience (EXP) + GBI_GUILDLV, ///< Guild level + GBI_SKILLPOINT, ///< Guild skillpoints + GBI_SKILLLV, ///< Guild skill_lv ?? seem unused }; enum { //Change Member Infos - GMI_POSITION =0, + GMI_POSITION = 0, GMI_EXP, GMI_HAIR, GMI_HAIR_COLOR, @@ -811,50 +837,50 @@ enum { }; enum weapon_type { - W_FIST, //Bare hands - W_DAGGER, //1 - W_1HSWORD, //2 - W_2HSWORD, //3 - W_1HSPEAR, //4 - W_2HSPEAR, //5 - W_1HAXE, //6 - W_2HAXE, //7 - W_MACE, //8 - W_2HMACE, //9 (unused) - W_STAFF, //10 - W_BOW, //11 - W_KNUCKLE, //12 - W_MUSICAL, //13 - W_WHIP, //14 - W_BOOK, //15 - W_KATAR, //16 - W_REVOLVER, //17 - W_RIFLE, //18 - W_GATLING, //19 - W_SHOTGUN, //20 - W_GRENADE, //21 - W_HUUMA, //22 - W_2HSTAFF, //23 + W_FIST, ///< Bare hands + W_DAGGER, //1 + W_1HSWORD, //2 + W_2HSWORD, //3 + W_1HSPEAR, //4 + W_2HSPEAR, //5 + W_1HAXE, //6 + W_2HAXE, //7 + W_MACE, //8 + W_2HMACE, //9 (unused) + W_STAFF, //10 + W_BOW, //11 + W_KNUCKLE, //12 + W_MUSICAL, //13 + W_WHIP, //14 + W_BOOK, //15 + W_KATAR, //16 + W_REVOLVER, //17 + W_RIFLE, //18 + W_GATLING, //19 + W_SHOTGUN, //20 + W_GRENADE, //21 + W_HUUMA, //22 + W_2HSTAFF, //23 MAX_WEAPON_TYPE, // dual-wield constants - W_DOUBLE_DD, // 2 daggers - W_DOUBLE_SS, // 2 swords - W_DOUBLE_AA, // 2 axes - W_DOUBLE_DS, // dagger + sword - W_DOUBLE_DA, // dagger + axe - W_DOUBLE_SA, // sword + axe + W_DOUBLE_DD, ///< 2 daggers + W_DOUBLE_SS, ///< 2 swords + W_DOUBLE_AA, ///< 2 axes + W_DOUBLE_DS, ///< dagger + sword + W_DOUBLE_DA, ///< dagger + axe + W_DOUBLE_SA, ///< sword + axe }; enum ammo_type { - A_ARROW = 1, - A_DAGGER, //2 - A_BULLET, //3 - A_SHELL, //4 - A_GRENADE, //5 - A_SHURIKEN, //6 - A_KUNAI, //7 - A_CANNONBALL, //8 - A_THROWWEAPON //9 + A_ARROW = 1, + A_DAGGER, //2 + A_BULLET, //3 + A_SHELL, //4 + A_GRENADE, //5 + A_SHURIKEN, //6 + A_KUNAI, //7 + A_CANNONBALL, //8 + A_THROWWEAPON, //9 }; enum e_char_server_type { diff --git a/src/common/socket.h b/src/common/socket.h index ca9141716..75adde4cf 100644 --- a/src/common/socket.h +++ b/src/common/socket.h @@ -2,7 +2,7 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _COMMON_SOCKET_H_ +#ifndef _COMMON_SOCKET_H_ #define _COMMON_SOCKET_H_ #include "../common/cbasetypes.h" diff --git a/src/common/sysinfo.c b/src/common/sysinfo.c new file mode 100644 index 000000000..a56896458 --- /dev/null +++ b/src/common/sysinfo.c @@ -0,0 +1,1022 @@ +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Base Author: Haru @ http://hercules.ws + +/// See sysinfo.h for a description of this file + +#define _COMMON_SYSINFO_P_ +#include "sysinfo.h" +#undef _COMMON_SYSINFO_P_ + +#include "../common/cbasetypes.h" +#include "../common/core.h" +#include "../common/strlib.h" +#include "../common/malloc.h" + +#ifdef WIN32 +#include <windows.h> +#include <string.h> // strlen +#else +#include <unistd.h> +#endif +#include <stdio.h> // fopen +#include <stdlib.h> // atoi + +/// sysinfo.c interface source +struct sysinfo_interface sysinfo_s; +struct sysinfo_private sysinfo_p; + +#define VCSTYPE_UNKNOWN 0 +#define VCSTYPE_GIT 1 +#define VCSTYPE_SVN 2 +#define VCSTYPE_NONE -1 + +#ifdef WIN32 +/** + * Values to be used with GetProductInfo. + * + * These aren't defined in MSVC2008/WindowsXP, so we gotta define them here. + * Values from: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724358%28v=vs.85%29.aspx + */ +enum windows_product_type { + msPRODUCT_UNDEFINED = 0x00000000, ///< An unknown product + msPRODUCT_ULTIMATE = 0x00000001, ///< Ultimate + msPRODUCT_HOME_BASIC = 0x00000002, ///< Home Basic + msPRODUCT_HOME_PREMIUM = 0x00000003, ///< Home Premium + msPRODUCT_ENTERPRISE = 0x00000004, ///< Enterprise + msPRODUCT_HOME_BASIC_N = 0x00000005, ///< Home Basic N + msPRODUCT_BUSINESS = 0x00000006, ///< Business + msPRODUCT_STANDARD_SERVER = 0x00000007, ///< Server Standard + msPRODUCT_DATACENTER_SERVER = 0x00000008, ///< Server Datacenter (full installation) + msPRODUCT_SMALLBUSINESS_SERVER = 0x00000009, ///< Windows Small Business Server + msPRODUCT_ENTERPRISE_SERVER = 0x0000000A, ///< Server Enterprise (full installation) + msPRODUCT_STARTER = 0x0000000B, ///< Starter + msPRODUCT_DATACENTER_SERVER_CORE = 0x0000000C, ///< Server Datacenter (core installation) + msPRODUCT_ENTERPRISE_SERVER_CORE = 0x0000000E, ///< Server Enterprise (core installation) + msPRODUCT_STANDARD_SERVER_CORE = 0x0000000D, ///< Server Standard (core installation) + msPRODUCT_ENTERPRISE_SERVER_IA64 = 0x0000000F, ///< Server Enterprise for Itanium-based Systems + msPRODUCT_BUSINESS_N = 0x00000010, ///< Business N + msPRODUCT_WEB_SERVER = 0x00000011, ///< Web Server (full installation) + msPRODUCT_CLUSTER_SERVER = 0x00000012, ///< HPC Edition + msPRODUCT_HOME_SERVER = 0x00000013, ///< Windows Storage Server 2008 R2 Essentials + msPRODUCT_STORAGE_EXPRESS_SERVER = 0x00000014, ///< Storage Server Express + msPRODUCT_STORAGE_STANDARD_SERVER = 0x00000015, ///< Storage Server Standard + msPRODUCT_STORAGE_WORKGROUP_SERVER = 0x00000016, ///< Storage Server Workgroup + msPRODUCT_STORAGE_ENTERPRISE_SERVER = 0x00000017, ///< Storage Server Enterprise + msPRODUCT_SERVER_FOR_SMALLBUSINESS = 0x00000018, ///< Windows Server 2008 for Windows Essential Server Solutions + msPRODUCT_SMALLBUSINESS_SERVER_PREMIUM = 0x00000019, ///< Small Business Server Premium + msPRODUCT_HOME_PREMIUM_N = 0x0000001A, ///< Home Premium N + msPRODUCT_ENTERPRISE_N = 0x0000001B, ///< Enterprise N + msPRODUCT_ULTIMATE_N = 0x0000001C, ///< Ultimate N + msPRODUCT_WEB_SERVER_CORE = 0x0000001D, ///< Web Server (core installation) + msPRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT = 0x0000001E, ///< Windows Essential Business Server Management Server + msPRODUCT_MEDIUMBUSINESS_SERVER_SECURITY = 0x0000001F, ///< Windows Essential Business Server Security Server + msPRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING = 0x00000020, ///< Windows Essential Business Server Messaging Server + msPRODUCT_SERVER_FOUNDATION = 0x00000021, ///< Server Foundation + msPRODUCT_HOME_PREMIUM_SERVER = 0x00000022, ///< Windows Home Server 2011 + msPRODUCT_SERVER_FOR_SMALLBUSINESS_V = 0x00000023, ///< Windows Server 2008 without Hyper-V for Windows Essential Server Solutions + msPRODUCT_STANDARD_SERVER_V = 0x00000024, ///< Server Standard without Hyper-V + msPRODUCT_DATACENTER_SERVER_V = 0x00000025, ///< Server Datacenter without Hyper-V (full installation) + msPRODUCT_ENTERPRISE_SERVER_V = 0x00000026, ///< Server Enterprise without Hyper-V (full installation) + msPRODUCT_DATACENTER_SERVER_CORE_V = 0x00000027, ///< Server Datacenter without Hyper-V (core installation) + msPRODUCT_STANDARD_SERVER_CORE_V = 0x00000028, ///< Server Standard without Hyper-V (core installation) + msPRODUCT_ENTERPRISE_SERVER_CORE_V = 0x00000029, ///< Server Enterprise without Hyper-V (core installation) + msPRODUCT_HYPERV = 0x0000002A, ///< Microsoft Hyper-V Server + msPRODUCT_STORAGE_EXPRESS_SERVER_CORE = 0x0000002B, ///< Storage Server Express (core installation) + msPRODUCT_STORAGE_STANDARD_SERVER_CORE = 0x0000002C, ///< Storage Server Standard (core installation) + msPRODUCT_STORAGE_WORKGROUP_SERVER_CORE = 0x0000002D, ///< Storage Server Workgroup (core installation) + msPRODUCT_STORAGE_ENTERPRISE_SERVER_CORE = 0x0000002E, ///< Storage Server Enterprise (core installation) + msPRODUCT_STARTER_N = 0x0000002F, ///< Starter N + msPRODUCT_PROFESSIONAL = 0x00000030, ///< Professional + msPRODUCT_PROFESSIONAL_N = 0x00000031, ///< Professional N + msPRODUCT_SB_SOLUTION_SERVER = 0x00000032, ///< Windows Small Business Server 2011 Essentials + msPRODUCT_SERVER_FOR_SB_SOLUTIONS = 0x00000033, ///< Server For SB Solutions + msPRODUCT_STANDARD_SERVER_SOLUTIONS = 0x00000034, ///< Server Solutions Premium + msPRODUCT_STANDARD_SERVER_SOLUTIONS_CORE = 0x00000035, ///< Server Solutions Premium (core installation) + msPRODUCT_SB_SOLUTION_SERVER_EM = 0x00000036, ///< Server For SB Solutions EM + msPRODUCT_SERVER_FOR_SB_SOLUTIONS_EM = 0x00000037, ///< Server For SB Solutions EM + msPRODUCT_SOLUTION_EMBEDDEDSERVER = 0x00000038, ///< Windows MultiPoint Server + msPRODUCT_ESSENTIALBUSINESS_SERVER_MGMT = 0x0000003B, ///< Windows Essential Server Solution Management + msPRODUCT_ESSENTIALBUSINESS_SERVER_ADDL = 0x0000003C, ///< Windows Essential Server Solution Additional + msPRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC = 0x0000003D, ///< Windows Essential Server Solution Management SVC + msPRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC = 0x0000003E, ///< Windows Essential Server Solution Additional SVC + msPRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE = 0x0000003F, ///< Small Business Server Premium (core installation) + msPRODUCT_CLUSTER_SERVER_V = 0x00000040, ///< Server Hyper Core V + msPRODUCT_STARTER_E = 0x00000042, ///< Not supported + msPRODUCT_HOME_BASIC_E = 0x00000043, ///< Not supported + msPRODUCT_HOME_PREMIUM_E = 0x00000044, ///< Not supported + msPRODUCT_PROFESSIONAL_E = 0x00000045, ///< Not supported + msPRODUCT_ENTERPRISE_E = 0x00000046, ///< Not supported + msPRODUCT_ULTIMATE_E = 0x00000047, ///< Not supported + msPRODUCT_ENTERPRISE_EVALUATION = 0x00000048, ///< Server Enterprise (evaluation installation) + msPRODUCT_MULTIPOINT_STANDARD_SERVER = 0x0000004C, ///< Windows MultiPoint Server Standard (full installation) + msPRODUCT_MULTIPOINT_PREMIUM_SERVER = 0x0000004D, ///< Windows MultiPoint Server Premium (full installation) + msPRODUCT_STANDARD_EVALUATION_SERVER = 0x0000004F, ///< Server Standard (evaluation installation) + msPRODUCT_DATACENTER_EVALUATION_SERVER = 0x00000050, ///< Server Datacenter (evaluation installation) + msPRODUCT_ENTERPRISE_N_EVALUATION = 0x00000054, ///< Enterprise N (evaluation installation) + msPRODUCT_STORAGE_WORKGROUP_EVALUATION_SERVER = 0x0000005F, ///< Storage Server Workgroup (evaluation installation) + msPRODUCT_STORAGE_STANDARD_EVALUATION_SERVER = 0x00000060, ///< Storage Server Standard (evaluation installation) + msPRODUCT_CORE_N = 0x00000062, ///< Windows 8 N + msPRODUCT_CORE_COUNTRYSPECIFIC = 0x00000063, ///< Windows 8 China + msPRODUCT_CORE_SINGLELANGUAGE = 0x00000064, ///< Windows 8 Single Language + msPRODUCT_CORE = 0x00000065, ///< Windows 8 + msPRODUCT_PROFESSIONAL_WMC = 0x00000067, ///< Professional with Media Center +}; + +/** + * Values to be used with GetSystemMetrics. + * + * Values from http://msdn.microsoft.com/en-us/library/windows/desktop/ms724385%28v=vs.85%29.aspx + */ +enum windows_metrics { + msSM_SERVERR2 = 89, ///< Obtains the build number if the system is Windows Server 2003 R2; otherwise, 0. +}; + +/** + * Values to be used with OSVERSIONINFOEX.wSuiteMask. + * + * Values from http://msdn.microsoft.com/en-us/library/windows/desktop/ms724833%28v=vs.85%29.aspx + */ +enum windows_ver_suite { + msVER_SUITE_BLADE = 0x00000400, ///< Windows Server 2003, Web Edition is installed. + msVER_SUITE_STORAGE_SERVER = 0x00002000, ///< Windows Storage Server 2003 R2 or Windows Storage Server 2003 is installed. + msVER_SUITE_COMPUTE_SERVER = 0x00004000, ///< Windows Server 2003, Compute Cluster Edition is installed. + msVER_SUITE_WH_SERVER = 0x00008000, ///< Windows Home Server is installed. +}; + +#else // not WIN32 +// UNIX. Use build-time cached values +#include "sysinfo.inc" +#endif // WIN32 + +// Compiler detection <http://sourceforge.net/p/predef/wiki/Compilers/> +#if defined(__BORLANDC__) +#define SYSINFO_COMPILER "Borland C++" +#elif defined(__clang__) +#define SYSINFO_COMPILER "Clang v" EXPAND_AND_QUOTE(__clang_major__) "." EXPAND_AND_QUOTE(__clang_minor__) "." EXPAND_AND_QUOTE(__clang_patchlevel__) +#elif defined(__INTEL_COMPILER) +#define SYSINFO_COMPILER "Intel CC v" EXPAND_AND_QUOTE(__INTEL_COMPILER) +#elif defined(__MINGW32__) +#if defined(__MINGW64__) +#define SYSINFO_COMPILER "MinGW-w64 64 Bit v" EXPAND_AND_QUOTE(__MINGW64_VERSION_MAJOR) "." EXPAND_AND_QUOTE(__MINGW64_VERSION_MINOR) \ + " (MinGW " EXPAND_AND_QUOTE(__MINGW32_MAJOR_VERSION) "." EXPAND_AND_QUOTE(__MINGW32_MINOR_VERSION) ")" +#elif defined(__MINGW64_VERSION_MAJOR) +#define SYSINFO_COMPILER "MinGW-w64 32 Bit v" EXPAND_AND_QUOTE(__MINGW64_VERSION_MAJOR) "." EXPAND_AND_QUOTE(__MINGW64_VERSION_MINOR) \ + " (MinGW " EXPAND_AND_QUOTE(__MINGW32_MAJOR_VERSION) "." EXPAND_AND_QUOTE(__MINGW32_MINOR_VERSION) ")" +#else +#define SYSINFO_COMPILER "MinGW32 v" EXPAND_AND_QUOTE(__MINGW32_MAJOR_VERSION) "." EXPAND_AND_QUOTE(__MINGW32_MINOR_VERSION) +#endif +#elif defined(__GNUC__) +#define SYSINFO_COMPILER "GCC v" EXPAND_AND_QUOTE(__GNUC__) "." EXPAND_AND_QUOTE(__GNUC_MINOR__) "." EXPAND_AND_QUOTE(__GNUC_PATCHLEVEL__) +#elif defined(_MSC_VER) +#if _MSC_VER >= 1300 && _MSC_VER < 1310 +#define SYSINFO_COMPILER "Microsoft Visual C++ 7.0 (v" EXPAND_AND_QUOTE(_MSC_VER) ")" +#elif _MSC_VER >= 1310 && _MSC_VER < 1400 +#define SYSINFO_COMPILER "Microsoft Visual C++ 2003 (v" EXPAND_AND_QUOTE(_MSC_VER) ")" +#elif _MSC_VER >= 1400 && _MSC_VER < 1500 +#define SYSINFO_COMPILER "Microsoft Visual C++ 2005 (v" EXPAND_AND_QUOTE(_MSC_VER) ")" +#elif _MSC_VER >= 1500 && _MSC_VER < 1600 +#define SYSINFO_COMPILER "Microsoft Visual C++ 2008 (v" EXPAND_AND_QUOTE(_MSC_VER) ")" +#elif _MSC_VER >= 1600 && _MSC_VER < 1700 +#define SYSINFO_COMPILER "Microsoft Visual C++ 2010 (v" EXPAND_AND_QUOTE(_MSC_VER) ")" +#elif _MSC_VER >= 1700 && _MSC_VER < 1800 +#define SYSINFO_COMPILER "Microsoft Visual C++ 2012 (v" EXPAND_AND_QUOTE(_MSC_VER) ")" +#elif _MSC_VER >= 1800 && _MSC_VER < 1900 +#define SYSINFO_COMPILER "Microsoft Visual C++ 2013 (v" EXPAND_AND_QUOTE(_MSC_VER) ")" +#else // < 1300 || >= 1900 +#define SYSINFO_COMPILER "Microsoft Visual C++ v" EXPAND_AND_QUOTE(_MSC_VER) +#endif +#else +#define SYSINFO_COMPILER "Unknown" +#endif +// end compiler detection + +/** + * Retrieves the current SVN revision. + * + * @param out[out] a string pointer to return the value (to be aFree()'d.) + * @retval true if a revision was correctly detected. + * @retval false if no revision was detected. out is set to NULL in this case. + */ +bool sysinfo_svn_get_revision(char **out) { + // Only include SVN support if detected it, or we're on MSVC +#if !defined(SYSINFO_VCSTYPE) || SYSINFO_VCSTYPE == VCSTYPE_SVN || SYSINFO_VCSTYPE == VCSTYPE_UNKNOWN + FILE *fp; + + // subversion 1.7 uses a sqlite3 database + // FIXME this is hackish at best... + // - ignores database file structure + // - assumes the data in NODES.dav_cache column ends with "!svn/ver/<revision>/<path>)" + // - since it's a cache column, the data might not even exist + if ((fp = fopen(".svn"PATHSEP_STR"wc.db", "rb")) != NULL || (fp = fopen(".."PATHSEP_STR".svn"PATHSEP_STR"wc.db", "rb")) != NULL) { + +#ifndef SVNNODEPATH //not sure how to handle branches, so i'll leave this overridable define until a better solution comes up +#define SVNNODEPATH trunk +#endif // SVNNODEPATH + + const char* prefix = "!svn/ver/"; + const char* postfix = "/"EXPAND_AND_QUOTE(SVNNODEPATH)")"; // there should exist only 1 entry like this + size_t prefix_len = strlen(prefix); + size_t postfix_len = strlen(postfix); + size_t i,j,flen; + char* buffer; + + // read file to buffer + fseek(fp, 0, SEEK_END); + flen = ftell(fp); + buffer = (char*)aMalloc(flen + 1); + fseek(fp, 0, SEEK_SET); + flen = fread(buffer, 1, flen, fp); + buffer[flen] = '\0'; + fclose(fp); + + // parse buffer + for (i = prefix_len + 1; i + postfix_len <= flen; ++i) { + if (buffer[i] != postfix[0] || memcmp(buffer + i, postfix, postfix_len) != 0) + continue; // postfix mismatch + for (j = i; j > 0; --j) { // skip digits + if (!ISDIGIT(buffer[j - 1])) + break; + } + if (memcmp(buffer + j - prefix_len, prefix, prefix_len) != 0) + continue; // prefix mismatch + // done + if (*out != NULL) + aFree(*out); + *out = aCalloc(1, 8); + snprintf(*out, 8, "%d", atoi(buffer + j)); + break; + } + aFree(buffer); + + if (*out != NULL) + return true; + } + + // subversion 1.6 and older? + if ((fp = fopen(".svn/entries", "r")) != NULL) { + char line[1024]; + int rev; + // Check the version + if (fgets(line, sizeof(line), fp)) { + if (!ISDIGIT(line[0])) { + // XML File format + while (fgets(line,sizeof(line),fp)) + if (strstr(line,"revision=")) break; + if (sscanf(line," %*[^\"]\"%d%*[^\n]", &rev) == 1) { + if (*out != NULL) + aFree(*out); + *out = aCalloc(1, 8); + snprintf(*out, 8, "%d", rev); + } + } else { + // Bin File format + if (fgets(line, sizeof(line), fp) == NULL) { printf("Can't get bin name\n"); } // Get the name + if (fgets(line, sizeof(line), fp) == NULL) { printf("Can't get entries kind\n"); } // Get the entries kind + if (fgets(line, sizeof(line), fp)) { // Get the rev numver + if (*out != NULL) + aFree(*out); + *out = aCalloc(1, 8); + snprintf(*out, 8, "%d", atoi(line)); + } + } + } + fclose(fp); + + if (*out != NULL) + return true; + } +#endif + if (*out != NULL) + aFree(*out); + *out = NULL; + return false; +} + +/** + * Retrieves the current Git revision. + * + * @param out[out] a string pointer to return the value (to be aFree()'d.) + * @retval true if a revision was correctly detected. + * @retval false if no revision was detected. out is set to NULL in this case. + */ +bool sysinfo_git_get_revision(char **out) { + // Only include Git support if we detected it, or we're on MSVC +#if !defined(SYSINFO_VCSTYPE) || SYSINFO_VCSTYPE == VCSTYPE_GIT || SYSINFO_VCSTYPE == VCSTYPE_UNKNOWN + FILE *fp; + char ref[128], filepath[128], line[128]; + + strcpy(ref, "HEAD"); + + while (*ref) { + snprintf(filepath, sizeof(filepath), ".git/%s", ref); + if ((fp = fopen(filepath, "r")) != NULL) { + if (fgets(line, sizeof(line)-1, fp) == NULL) { + fclose(fp); + break; + } + fclose(fp); + if (sscanf(line, "ref: %127[^\n]", ref) == 1) { + continue; + } else if (sscanf(line, "%127[a-f0-9]", ref) == 1 && strlen(ref) == 40) { + if (*out != NULL) + aFree(*out); + *out = aStrdup(ref); + } + } + break; + } + if (*out != NULL) + return true; +#else + if (*out != NULL) + aFree(*out); + *out = NULL; +#endif + return false; +} + +#ifdef WIN32 + +/// Windows-specific runtime detection functions. + +typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD); +/** + * Retrieves the Operating System version (Windows only). + * + * Once retrieved, the version string is stored into sysinfo->p->osversion. + */ +void sysinfo_osversion_retrieve(void) { + OSVERSIONINFOEX osvi; + StringBuf buf; + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + StrBuf->Init(&buf); + + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + + if (sysinfo->p->osversion != NULL) { + aFree(sysinfo->p->osversion); + sysinfo->p->osversion = NULL; + } + + /* + * #pragma rantmode (on) + * Some engineer at Microsoft moronically decided that, since some applications use this information to do version checks and refuse to + * run if they detect a new, unknown version of Windows, now nobody will be able to rely on this information anymore, not even those who + * need it for reporting or logging. + * The correct fix was to let those applications break, and their developer fix them (and in the meanwhile let the users use the + * Compatibility settings to run them) but no, they decided they'd deprecate the API, and make it lie for those who use it, reporting + * windows 8 even if they're running on 8.1 or newer. + * The API wasn't broken, applications were. Now we have broken applications, and a broken API. Great move, Microsoft. Oh right, + * there's the Version API helper functions. Or maybe not, since you can only do 'are we running on at least version X?' checks with + * those, it's not what we need. + * You know what? I'll just silence your deprecation warning for the time being. Maybe by the time you release the next version of + * Windows, you'll have provided a less crippled API or something. + * #pragma rantmode (off) + */ +#pragma warning (push) +#pragma warning (disable : 4996) + if (!GetVersionEx((OSVERSIONINFO*) &osvi)) { + sysinfo->p->osversion = aStrdup("Unknown Version"); + return; + } +#pragma warning (pop) + + if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId // Windows NT Family + && ((osvi.dwMajorVersion > 4 && osvi.dwMajorVersion < 6) || (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion <= 3)) // Between XP and 8.1 + ) { + if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion <= 3) { // Between Vista and 8.1 + PGPI pGPI; + DWORD dwType; + if (osvi.dwMinorVersion == 0) { + StrBuf->AppendStr(&buf, osvi.wProductType == VER_NT_WORKSTATION ? "Windows Vista" : "Windows Server 2008"); + } else if (osvi.dwMinorVersion == 1) { + StrBuf->AppendStr(&buf, osvi.wProductType == VER_NT_WORKSTATION ? "Windows 7" : "Windows Server 2008 R2"); + } else { + // If it's 2, it can be Windows 8, or any newer version (8.1 at the time of writing this) -- see above for the reason. + switch (osvi.dwMinorVersion) { + case 2: + { + ULONGLONG mask = 0; + OSVERSIONINFOEX osvi2; + ZeroMemory(&osvi2, sizeof(OSVERSIONINFOEX)); + osvi2.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + osvi2.dwMajorVersion = 6; + osvi2.dwMinorVersion = 2; + VER_SET_CONDITION(mask, VER_MAJORVERSION, VER_LESS_EQUAL); + VER_SET_CONDITION(mask, VER_MINORVERSION, VER_LESS_EQUAL); + if (VerifyVersionInfo(&osvi2, VER_MAJORVERSION | VER_MINORVERSION, mask)) { + StrBuf->AppendStr(&buf, osvi.wProductType == VER_NT_WORKSTATION ? "Windows 8" : "Windows Server 2012"); + break; + } + } + case 3: + StrBuf->AppendStr(&buf, osvi.wProductType == VER_NT_WORKSTATION ? "Windows 8.1" : "Windows Server 2012 R2"); + } + } + + pGPI = (PGPI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo"); + + pGPI(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType); + + switch (dwType) { + case msPRODUCT_ULTIMATE: + case msPRODUCT_ULTIMATE_N: + StrBuf->AppendStr(&buf, " Ultimate"); + break; + case msPRODUCT_PROFESSIONAL: + case msPRODUCT_PROFESSIONAL_N: + case msPRODUCT_PROFESSIONAL_WMC: + StrBuf->AppendStr(&buf, " Professional"); + break; + case msPRODUCT_HOME_PREMIUM: + case msPRODUCT_HOME_PREMIUM_N: + StrBuf->AppendStr(&buf, " Home Premium"); + break; + case msPRODUCT_HOME_BASIC: + case msPRODUCT_HOME_BASIC_N: + StrBuf->AppendStr(&buf, " Home Basic"); + break; + case msPRODUCT_ENTERPRISE: + case msPRODUCT_ENTERPRISE_N: + case msPRODUCT_ENTERPRISE_SERVER: + case msPRODUCT_ENTERPRISE_SERVER_CORE: + case msPRODUCT_ENTERPRISE_SERVER_IA64: + case msPRODUCT_ENTERPRISE_SERVER_V: + case msPRODUCT_ENTERPRISE_SERVER_CORE_V: + case msPRODUCT_ENTERPRISE_EVALUATION: + case msPRODUCT_ENTERPRISE_N_EVALUATION: + StrBuf->AppendStr(&buf, " Enterprise"); + break; + case msPRODUCT_BUSINESS: + case msPRODUCT_BUSINESS_N: + StrBuf->AppendStr(&buf, " Business"); + break; + case msPRODUCT_STARTER: + case msPRODUCT_STARTER_N: + StrBuf->AppendStr(&buf, " Starter"); + break; + case msPRODUCT_CLUSTER_SERVER: + case msPRODUCT_CLUSTER_SERVER_V: + StrBuf->AppendStr(&buf, " Cluster Server"); + break; + case msPRODUCT_DATACENTER_SERVER: + case msPRODUCT_DATACENTER_SERVER_CORE: + case msPRODUCT_DATACENTER_SERVER_V: + case msPRODUCT_DATACENTER_SERVER_CORE_V: + case msPRODUCT_DATACENTER_EVALUATION_SERVER: + StrBuf->AppendStr(&buf, " Datacenter"); + break; + case msPRODUCT_SMALLBUSINESS_SERVER: + case msPRODUCT_SMALLBUSINESS_SERVER_PREMIUM: + case msPRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE: + StrBuf->AppendStr(&buf, " Small Business Server"); + break; + case PRODUCT_STANDARD_SERVER: + case PRODUCT_STANDARD_SERVER_CORE: + case msPRODUCT_STANDARD_SERVER_V: + case msPRODUCT_STANDARD_SERVER_CORE_V: + case msPRODUCT_STANDARD_EVALUATION_SERVER: + StrBuf->AppendStr(&buf, " Standard"); + break; + case msPRODUCT_WEB_SERVER: + case msPRODUCT_WEB_SERVER_CORE: + StrBuf->AppendStr(&buf, " Web Server"); + break; + case msPRODUCT_STORAGE_EXPRESS_SERVER: + case msPRODUCT_STORAGE_STANDARD_SERVER: + case msPRODUCT_STORAGE_WORKGROUP_SERVER: + case msPRODUCT_STORAGE_ENTERPRISE_SERVER: + case msPRODUCT_STORAGE_EXPRESS_SERVER_CORE: + case msPRODUCT_STORAGE_STANDARD_SERVER_CORE: + case msPRODUCT_STORAGE_WORKGROUP_SERVER_CORE: + case msPRODUCT_STORAGE_ENTERPRISE_SERVER_CORE: + case msPRODUCT_STORAGE_WORKGROUP_EVALUATION_SERVER: + case msPRODUCT_STORAGE_STANDARD_EVALUATION_SERVER: + StrBuf->AppendStr(&buf, " Storage Server"); + break; + case msPRODUCT_HOME_SERVER: + case msPRODUCT_SERVER_FOR_SMALLBUSINESS: + case msPRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT: + case msPRODUCT_MEDIUMBUSINESS_SERVER_SECURITY: + case msPRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING: + case msPRODUCT_SERVER_FOR_SMALLBUSINESS_V: + case msPRODUCT_SERVER_FOUNDATION: + case msPRODUCT_HOME_PREMIUM_SERVER: + case msPRODUCT_HYPERV: + case msPRODUCT_SB_SOLUTION_SERVER: + case msPRODUCT_SERVER_FOR_SB_SOLUTIONS: + case msPRODUCT_STANDARD_SERVER_SOLUTIONS: + case msPRODUCT_STANDARD_SERVER_SOLUTIONS_CORE: + case msPRODUCT_SB_SOLUTION_SERVER_EM: + case msPRODUCT_SERVER_FOR_SB_SOLUTIONS_EM: + case msPRODUCT_SOLUTION_EMBEDDEDSERVER: + case msPRODUCT_ESSENTIALBUSINESS_SERVER_MGMT: + case msPRODUCT_ESSENTIALBUSINESS_SERVER_ADDL: + case msPRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC: + case msPRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC: + case msPRODUCT_MULTIPOINT_STANDARD_SERVER: + case msPRODUCT_MULTIPOINT_PREMIUM_SERVER: + StrBuf->AppendStr(&buf, " Server (other)"); + break; + case msPRODUCT_CORE_N: + case msPRODUCT_CORE_COUNTRYSPECIFIC: + case msPRODUCT_CORE_SINGLELANGUAGE: + case msPRODUCT_CORE: + StrBuf->AppendStr(&buf, " Workstation (other)"); + break; + } + + } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) { // XP x64 and Server 2003 + if (osvi.wProductType == VER_NT_WORKSTATION) { + StrBuf->AppendStr(&buf, "Windows XP Professional"); + } else { + if (GetSystemMetrics(msSM_SERVERR2)) + StrBuf->AppendStr(&buf, "Windows Server 2003 R2"); + else if (osvi.wSuiteMask & msVER_SUITE_STORAGE_SERVER) + StrBuf->AppendStr(&buf, "Windows Storage Server 2003"); + else if (osvi.wSuiteMask & msVER_SUITE_WH_SERVER) + StrBuf->AppendStr(&buf, "Windows Home Server"); + else + StrBuf->AppendStr(&buf, "Windows Server 2003"); + + // Test for the server type. + if (osvi.wSuiteMask & msVER_SUITE_COMPUTE_SERVER) + StrBuf->AppendStr(&buf, " Compute Cluster"); + else if (osvi.wSuiteMask & VER_SUITE_DATACENTER) + StrBuf->AppendStr(&buf, " Datacenter"); + else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) + StrBuf->AppendStr(&buf, " Enterprise"); + else if (osvi.wSuiteMask & msVER_SUITE_BLADE) + StrBuf->AppendStr(&buf, " Web"); + else + StrBuf->AppendStr(&buf, " Standard"); + } + } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) { // XP + StrBuf->AppendStr(&buf, "Windows XP"); + if (osvi.wSuiteMask & VER_SUITE_EMBEDDEDNT) + StrBuf->AppendStr(&buf, " Embedded"); + else if (osvi.wSuiteMask & VER_SUITE_PERSONAL) + StrBuf->AppendStr(&buf, " Home"); + else + StrBuf->AppendStr(&buf, " Professional"); + } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) { // 2000 + StrBuf->AppendStr(&buf, "Windows 2000"); + + if (osvi.wProductType == VER_NT_WORKSTATION) + StrBuf->AppendStr(&buf, " Professional"); + else if (osvi.wSuiteMask & VER_SUITE_DATACENTER) + StrBuf->AppendStr(&buf, " Datacenter Server"); + else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) + StrBuf->AppendStr(&buf, " Advanced Server"); + else + StrBuf->AppendStr(&buf, " Server"); + } else { + StrBuf->Printf(&buf, "Unknown Windows version %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); + } + } + + // Include service pack (if any) and build number. + + if (strlen(osvi.szCSDVersion) > 0) { + StrBuf->Printf(&buf, " %s", osvi.szCSDVersion); + } + + StrBuf->Printf(&buf, " (build %d)", osvi.dwBuildNumber); + + sysinfo->p->osversion = aStrdup(StrBuf->Value(&buf)); + + StrBuf->Destroy(&buf); + return; +} + +typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); +/** + * Retrieves the CPU type (Windows only). + * + * Once retrieved, the name is stored into sysinfo->p->cpu and the + * number of cores in sysinfo->p->cpucores. + */ +void sysinfo_cpu_retrieve(void) { + StringBuf buf; + PGNSI pGNSI; + SYSTEM_INFO si; + ZeroMemory(&si, sizeof(SYSTEM_INFO)); + StrBuf->Init(&buf); + + if (sysinfo->p->cpu != NULL) { + aFree(sysinfo->p->cpu); + sysinfo->p->cpu = NULL; + } + + // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise. + pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); + if (NULL != pGNSI) + pGNSI(&si); + else + GetSystemInfo(&si); + + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL + || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 + ) { + StrBuf->Printf(&buf, "%s CPU, Family %d, Model %d, Stepping %d", + si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL ? "x86" : "x86_64", + si.wProcessorLevel, + (si.wProcessorRevision&0xff00)>>8, + (si.wProcessorRevision&0xff)); + } else { + StrBuf->AppendStr(&buf, "Unknown"); + } + + sysinfo->p->cpu = aStrdup(StrBuf->Value(&buf)); + sysinfo->p->cpucores = si.dwNumberOfProcessors; + + StrBuf->Destroy(&buf); +} + +/** + * Retrieves the OS architecture (Windows only). + * + * Once retrieved, the name is stored into sysinfo->p->arch. + */ +void sysinfo_arch_retrieve(void) { + PGNSI pGNSI; + SYSTEM_INFO si; + ZeroMemory(&si, sizeof(SYSTEM_INFO)); + + if (sysinfo->p->arch != NULL) { + aFree(sysinfo->p->arch); + sysinfo->p->arch = NULL; + } + + // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise. + pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); + if (NULL != pGNSI) + pGNSI(&si); + else + GetSystemInfo(&si); + + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) // x64 + sysinfo->p->arch = aStrdup("x86_64"); + else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) // x32 + sysinfo->p->arch = aStrdup("x86"); + else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM) // ARM + sysinfo->p->arch = aStrdup("ARM"); + else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) // Itanium + sysinfo->p->arch = aStrdup("IA-64"); + else + sysinfo->p->arch = aStrdup("Unknown"); +} + +/** + * Retrieves the startup-time VCS revision information. + * + * Once retrieved, the value is stored in sysinfo->p->vcsrevision_src. + */ +void sysinfo_vcsrevision_src_retrieve(void) { + if (sysinfo->p->vcsrevision_src != NULL) { + aFree(sysinfo->p->vcsrevision_src); + sysinfo->p->vcsrevision_src = NULL; + } + // Try Git, then SVN + if (sysinfo_git_get_revision(&sysinfo->p->vcsrevision_src)) { + sysinfo->p->vcstype = VCSTYPE_GIT; + return; + } + if (sysinfo_svn_get_revision(&sysinfo->p->vcsrevision_src)) { + sysinfo->p->vcstype = VCSTYPE_SVN; + return; + } + sysinfo->p->vcstype = VCSTYPE_NONE; + sysinfo->p->vcsrevision_src = aStrdup("Unknown"); +} +#endif // WIN32 + +/** + * Retrieevs the VCS type name. + * + * Once retrieved, the value is stored in sysinfo->p->vcstype_name. + */ +void sysinfo_vcstype_name_retrieve(void) { + if (sysinfo->p->vcstype_name != NULL) { + aFree(sysinfo->p->vcstype_name); + sysinfo->p->vcstype_name = NULL; + } + switch (sysinfo->p->vcstype) { + case VCSTYPE_GIT: + sysinfo->p->vcstype_name = aStrdup("Git"); + break; + case VCSTYPE_SVN: + sysinfo->p->vcstype_name = aStrdup("SVN"); + break; + default: + sysinfo->p->vcstype_name = aStrdup("Exported"); + break; + } +} + +/** + * Returns the platform (OS type) this application is running on. + * + * This information is cached at compile time, since it's unlikely to change. + * + * @return the OS platform name. + * + * Note: Ownership is NOT transferred, the value should not be freed. + * + * Output example: "Linux", "Darwin", "Windows", etc. + */ +const char *sysinfo_platform(void) { + return sysinfo->p->platform; +} + +/** + * Returns the Operating System version the application is running on. + * + * On platforms other than Windows (MSVC), this information is cached at + * compile time, since it is uncommon that an application is compiled and runs + * on different machines. + * + * @return the OS name. + * + * Note: Ownership is NOT transferred, the value should not be freed. + * + * Output example: "Windows 2008 Small Business Server", "OS X 10.8 Mountain Lion", + * "Gentoo Base System Release 2.2", "Debian GNU/Linux 6.0.6 (squeeze)", etc. + */ +const char *sysinfo_osversion(void) { + return sysinfo->p->osversion; +} + +/** + * Returns the CPU model the application is running on. + * + * On platforms other than Windows (MSVC), this information is cached at + * compile time, since it is uncommon that an application is compiled and runs + * on different machines. + * + * @return the CPU model name. + * + * Note: Ownership is NOT transferred, the value should not be freed. + * + * Output example: "Intel(R) Atom(TM) CPU D2500 @ 1.86GHz", + * "Intel(R) Xeon(R) CPU E5-1650 0 @ 3.20GHz", "Intel Core i7", + * "x86 CPU, Family 6, Model 54, Stepping 1", etc. + */ +const char *sysinfo_cpu(void) { + return sysinfo->p->cpu; +} + +/** + * Returns the number of CPU cores available. + * + * On platforms other than Windows (MSVC), this information is cached at + * compile time, since it is uncommon that an application is compiled and runs + * on different machines. + * + * @return the number of CPU cores. + */ +int sysinfo_cpucores(void) { + return sysinfo->p->cpucores; +} + +/** + * Returns the CPU architecture the application was compiled for. + * + * On platforms other than Windows (MSVC), this information is cached at + * compile time, since it is uncommon that an application is compiled and runs + * on different machines. + * + * @return the CPU architecture name. + * + * Note: Ownership is NOT transferred, the value should not be freed. + * + * Output example: "x86", "x86_64", "IA-64", "ARM", etc. + */ +const char *sysinfo_arch(void) { + return sysinfo->p->arch; +} + +/** + * Returns info about the 32 or 64 bit build of Hercules. + * + * @retval true if this is a 64 bit build. + * @retval false if this isn't a 64 bit build (i.e. it is a 32 bit build). + */ +bool sysinfo_is64bit(void) { +#ifdef _LP64 + return true; +#else + return false; +#endif +} + +/** + * Returns the compiler the application was compiled with. + * + * @return the compiler name. + * + * Note: Ownership is NOT transferred, the value should not be freed. + * + * Output example: "Microsoft Visual C++ 2012 (v170050727)", + * "Clang v5.0.0", "MinGW32 v3.20", "GCC v4.7.3", etc. + */ +const char *sysinfo_compiler(void) { + return sysinfo->p->compiler; +} + +/** + * Returns the compiler flags the application was compiled with. + * + * On Windows (MSVC), an empty string is returned instead. + * + * @return the compiler flags. + * + * Note: Ownership is NOT transferred, the value should not be freed. + * + * Output example: "-ggdb -O2 -flto -pipe -ffast-math ..." + */ +const char *sysinfo_cflags(void) { + return sysinfo->p->cflags; +} + +/** + * Returns the Version Control System the application was downloaded with. + * + * On platforms other than Windows (MSVC), this information is cached at + * compile time. On Windows (MSVC), it is cached when the function is first + * called (most likely on server startup). + * + * @return the VCS type (numerical). + * + * @see VCSTYPE_NONE, VCSTYPE_GIT, VCSTYPE_SVN, VCSTYPE_UNKNOWN + */ +int sysinfo_vcstypeid(void) { + return sysinfo->p->vcstype; +} + +/** + * Returns the Version Control System the application was downloaded with. + * + * On platforms other than Windows (MSVC), this information is cached at + * compile time. On Windows (MSVC), it is cached when the function is first + * called (most likely on server startup). + * + * @return the VCS type. + * + * Note: Ownership is NOT transferred, the value should not be freed. + * + * Output example: "Git", "SVN", "Exported" + */ +const char *sysinfo_vcstype(void) { + return sysinfo->p->vcstype_name; +} + +/** + * Returns the Version Control System revision. + * + * On platforms other than Windows (MSVC), this information is cached at + * compile time for better reliability. On Windows (MSVC), it is cached when + * the function is first called (most likely on server startup), so it may + * diverge from the actual revision that was compiled. + * + * @return the VCS revision. + * + * Note: Ownership is NOT transferred, the value should not be freed. + * + * Output example: Git: "9128feccf3bddda94a7f8a170305565416815b40", SVN: "17546" + */ +const char *sysinfo_vcsrevision_src(void) { + return sysinfo->p->vcsrevision_src; +} + +/** + * Returns the Version Control System revision. + * + * This information is cached during a script reload, so that it matches the + * version of the loaded scripts. + * + * @return the VCS revision. + * + * Note: Ownership is NOT transferred, the value should not be freed. + * + * Output example: Git: "9128feccf3bddda94a7f8a170305565416815b40", SVN: "17546" + */ +const char *sysinfo_vcsrevision_scripts(void) { + return sysinfo->p->vcsrevision_scripts; +} + +/** + * Reloads the run-time (scripts) VCS revision information. To be used during + * script reloads to refresh the cached version. + */ +void sysinfo_vcsrevision_reload(void) { + if (sysinfo->p->vcsrevision_scripts != NULL) { + aFree(sysinfo->p->vcsrevision_scripts); + sysinfo->p->vcsrevision_scripts = NULL; + } + // Try Git, then SVN + if (sysinfo_git_get_revision(&sysinfo->p->vcsrevision_scripts)) { + return; + } + if (sysinfo_svn_get_revision(&sysinfo->p->vcsrevision_scripts)) { + return; + } + sysinfo->p->vcsrevision_scripts = aStrdup("Unknown"); +} + +/** + * Checks if we're running (unnecessarily) as superuser. + * + * @retval true if the current process is running as UNIX super-user. + * @retval false if the current process is running as regular user, or + * in any case under Windows. + */ +bool sysinfo_is_superuser(void) { +#ifndef _WIN32 + if (geteuid() == 0) + return true; +#endif + return false; +} + +/** + * Interface runtime initialization. + */ +void sysinfo_init(void) { + sysinfo->p->compiler = SYSINFO_COMPILER; +#ifdef WIN32 + sysinfo->p->platform = "Windows"; + sysinfo->p->cflags = "N/A"; + sysinfo_osversion_retrieve(); + sysinfo_cpu_retrieve(); + sysinfo_arch_retrieve(); + sysinfo_vcsrevision_src_retrieve(); +#else + sysinfo->p->platform = SYSINFO_PLATFORM; + sysinfo->p->osversion = SYSINFO_OSVERSION; + sysinfo->p->cpucores = SYSINFO_CPUCORES; + sysinfo->p->cpu = SYSINFO_CPU; + sysinfo->p->arch = SYSINFO_ARCH; + sysinfo->p->cflags = SYSINFO_CFLAGS; + sysinfo->p->vcstype = SYSINFO_VCSTYPE; + sysinfo->p->vcsrevision_src = SYSINFO_VCSREV; +#endif + sysinfo->vcsrevision_reload(); + sysinfo_vcstype_name_retrieve(); // Must be called after setting vcstype +} + +/** + * Interface shutdown cleanup. + */ +void sysinfo_final(void) { +#ifdef WIN32 + // Only need to be free'd in win32, they're #defined elsewhere + if (sysinfo->p->osversion) + aFree(sysinfo->p->osversion); + if (sysinfo->p->cpu) + aFree(sysinfo->p->cpu); + if (sysinfo->p->arch) + aFree(sysinfo->p->arch); + if (sysinfo->p->vcsrevision_src) + aFree(sysinfo->p->vcsrevision_src); +#endif + sysinfo->p->platform = NULL; + sysinfo->p->osversion = NULL; + sysinfo->p->cpu = NULL; + sysinfo->p->arch = NULL; + sysinfo->p->vcsrevision_src = NULL; + sysinfo->p->cflags = NULL; + if (sysinfo->p->vcsrevision_scripts) + aFree(sysinfo->p->vcsrevision_scripts); + sysinfo->p->vcsrevision_scripts = NULL; + if (sysinfo->p->vcstype_name) + aFree(sysinfo->p->vcstype_name); + sysinfo->p->vcstype_name = NULL; +} + +/** + * Interface default values initialization. + */ +void sysinfo_defaults(void) { + sysinfo = &sysinfo_s; + memset(&sysinfo_p, '\0', sizeof(sysinfo_p)); + sysinfo->p = &sysinfo_p; + + sysinfo->platform = sysinfo_platform; + sysinfo->osversion = sysinfo_osversion; + sysinfo->cpu = sysinfo_cpu; + sysinfo->cpucores = sysinfo_cpucores; + sysinfo->arch = sysinfo_arch; + sysinfo->is64bit = sysinfo_is64bit; + sysinfo->compiler = sysinfo_compiler; + sysinfo->cflags = sysinfo_cflags; + sysinfo->vcstype = sysinfo_vcstype; + sysinfo->vcstypeid = sysinfo_vcstypeid; + sysinfo->vcsrevision_src = sysinfo_vcsrevision_src; + sysinfo->vcsrevision_scripts = sysinfo_vcsrevision_scripts; + sysinfo->vcsrevision_reload = sysinfo_vcsrevision_reload; + sysinfo->is_superuser = sysinfo_is_superuser; + sysinfo->init = sysinfo_init; + sysinfo->final = sysinfo_final; +} diff --git a/src/common/sysinfo.h b/src/common/sysinfo.h new file mode 100644 index 000000000..17faac26b --- /dev/null +++ b/src/common/sysinfo.h @@ -0,0 +1,62 @@ +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Base Author: Haru @ http://hercules.ws + +#ifndef _COMMON_SYSINFO_H_ +#define _COMMON_SYSINFO_H_ + +/** + * Provides various bits of information about the system Hercules is running on + * (note: on unix systems, to avoid runtime detection, most of the data is + * cached at compile time) + */ + +#include "../common/cbasetypes.h" + +#ifdef _COMMON_SYSINFO_P_ +struct sysinfo_private { + char *platform; + char *osversion; + char *cpu; + int cpucores; + char *arch; + char *compiler; + char *cflags; + char *vcstype_name; + int vcstype; + char *vcsrevision_src; + char *vcsrevision_scripts; +}; +#else +struct sysinfo_private; +#endif + +/** + * sysinfo.c interface + **/ +struct sysinfo_interface { + struct sysinfo_private *p; + + const char *(*platform) (void); + const char *(*osversion) (void); + const char *(*cpu) (void); + int (*cpucores) (void); + const char *(*arch) (void); + bool (*is64bit) (void); + const char *(*compiler) (void); + const char *(*cflags) (void); + const char *(*vcstype) (void); + int (*vcstypeid) (void); + const char *(*vcsrevision_src) (void); + const char *(*vcsrevision_scripts) (void); + void (*vcsrevision_reload) (void); + bool (*is_superuser) (void); + void (*init) (void); + void (*final) (void); +}; + +struct sysinfo_interface *sysinfo; + +void sysinfo_defaults(void); + +#endif /* _COMMON_SYSINFO_H_ */ diff --git a/src/common/timer.h b/src/common/timer.h index ab3ffc21f..1ce8cf203 100644 --- a/src/common/timer.h +++ b/src/common/timer.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _COMMON_TIMER_H_ -#define _COMMON_TIMER_H_ +#ifndef _COMMON_TIMER_H_ +#define _COMMON_TIMER_H_ #include "../common/cbasetypes.h" |