summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/char/geoip.c7
-rw-r--r--src/char/int_auction.c2
-rw-r--r--src/char/inter.c2
-rw-r--r--src/common/ers.c3
-rw-r--r--src/common/grfio.c151
-rw-r--r--src/common/md5calc.c4
-rw-r--r--src/common/socket.c29
-rw-r--r--src/common/sql.c10
-rw-r--r--src/common/utils.c57
9 files changed, 169 insertions, 96 deletions
diff --git a/src/char/geoip.c b/src/char/geoip.c
index 1268019e1..889958e16 100644
--- a/src/char/geoip.c
+++ b/src/char/geoip.c
@@ -136,7 +136,7 @@ void geoip_init(void)
geoip->final(false);
return;
}
- geoip->data->cache = aMalloc( (sizeof(geoip->data->cache) * bufa.st_size) );
+ geoip->data->cache = aMalloc(sizeof(unsigned char) * bufa.st_size);
if (fread(geoip->data->cache, sizeof(unsigned char), bufa.st_size, db) != bufa.st_size) {
ShowError("geoip_cache: Couldn't read all elements!\n");
fclose(db);
@@ -157,7 +157,10 @@ void geoip_init(void)
}
break;
} else {
- fseek(db, -4l, SEEK_CUR);
+ if (fseek(db, -4l, SEEK_CUR) != 0) {
+ db_type = 0;
+ break;
+ }
}
}
diff --git a/src/char/int_auction.c b/src/char/int_auction.c
index 164ca5360..57eae641d 100644
--- a/src/char/int_auction.c
+++ b/src/char/int_auction.c
@@ -105,7 +105,7 @@ unsigned int inter_auction_create(struct auction_data *auction)
else
{
struct auction_data *auction_;
- int64 tick = auction->hours * 3600000;
+ int64 tick = (int64)auction->hours * 3600000;
auction->item.amount = 1;
auction->item.identify = 1;
diff --git a/src/char/inter.c b/src/char/inter.c
index 5af9a6aab..eb14f1593 100644
--- a/src/char/inter.c
+++ b/src/char/inter.c
@@ -690,9 +690,11 @@ int inter_accreg_fromsql(int account_id,int char_id, int fd, int type)
if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", acc_reg_num_db, account_id) )
Sql_ShowDebug(inter->sql_handle);
break;
+#if 0 // This is already checked above.
case 1: //account2 reg
ShowError("inter->accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n");
return 0;
+#endif // 0
}
WFIFOHEAD(fd, 60000 + 300);
diff --git a/src/common/ers.c b/src/common/ers.c
index 489d8f7ae..52cba0fe5 100644
--- a/src/common/ers.c
+++ b/src/common/ers.c
@@ -308,8 +308,11 @@ ERS *ers_new(uint32 size, char *name, enum ERSOptions options)
CREATE(instance,struct ers_instance_t, 1);
size += sizeof(struct ers_list);
+
+#if ERS_ALIGNED > 1 // If it's aligned to 1-byte boundaries, no need to bother.
if (size % ERS_ALIGNED)
size += ERS_ALIGNED - size % ERS_ALIGNED;
+#endif
instance->VTable.alloc = ers_obj_alloc_entry;
instance->VTable.free = ers_obj_free_entry;
diff --git a/src/common/grfio.c b/src/common/grfio.c
index 28e6c87f4..d226fb158 100644
--- a/src/common/grfio.c
+++ b/src/common/grfio.c
@@ -402,51 +402,72 @@ static void grfio_localpath_create(char* buffer, size_t size, const char* filena
/// Reads a file into a newly allocated buffer (from grf or data directory).
-void* grfio_reads(const char* fname, int* size)
+void *grfio_reads(const char *fname, int *size)
{
- unsigned char* buf2 = NULL;
-
FILELIST* entry = filelist_find(fname);
- if( entry == NULL || entry->gentry <= 0 ) {// LocalFileCheck
+ if (entry == NULL || entry->gentry <= 0) {
+ // LocalFileCheck
char lfname[256];
- FILE* in;
- grfio_localpath_create(lfname, sizeof(lfname), ( entry && entry->fnd ) ? entry->fnd : fname);
+ FILE *in;
+ unsigned char *buf = NULL;
+ grfio_localpath_create(lfname, sizeof(lfname), (entry && entry->fnd) ? entry->fnd : fname);
in = fopen(lfname, "rb");
- if( in != NULL ) {
+ if (in != NULL) {
int declen;
fseek(in,0,SEEK_END);
declen = (int)ftell(in);
+ if (declen == -1) {
+ ShowError("An error occurred in fread grfio_reads, fname=%s \n",fname);
+ fclose(in);
+ return NULL;
+ }
fseek(in,0,SEEK_SET);
- buf2 = (unsigned char *)aMalloc(declen+1); // +1 for resnametable zero-termination
- if(fread(buf2, 1, declen, in) != (size_t)declen) ShowError("An error occurred in fread grfio_reads, fname=%s \n",fname);
+ buf = (unsigned char *)aMalloc(declen+1); // +1 for resnametable zero-termination
+ buf[declen] = '\0';
+ if (fread(buf, 1, declen, in) != (size_t)declen) {
+ ShowError("An error occurred in fread grfio_reads, fname=%s \n",fname);
+ aFree(buf);
+ fclose(in);
+ return NULL;
+ }
fclose(in);
- if( size )
+ if (size)
*size = declen;
- } else {
- if (entry != NULL && entry->gentry < 0) {
- entry->gentry = -entry->gentry; // local file checked
- } else {
- ShowError("grfio_reads: %s not found (local file: %s)\n", fname, lfname);
- return NULL;
- }
+ return buf;
}
+
+ if (entry == NULL || entry->gentry >= 0) {
+ ShowError("grfio_reads: %s not found (local file: %s)\n", fname, lfname);
+ return NULL;
+ }
+
+ entry->gentry = -entry->gentry; // local file checked
}
- if( entry != NULL && entry->gentry > 0 ) {// Archive[GRF] File Read
- char* grfname = gentry_table[entry->gentry - 1];
- FILE* in = fopen(grfname, "rb");
- if( in != NULL ) {
+ if (entry != NULL && entry->gentry > 0) {
+ // Archive[GRF] File Read
+ char *grfname = gentry_table[entry->gentry - 1];
+ FILE *in = fopen(grfname, "rb");
+
+ if (in != NULL) {
int fsize = entry->srclen_aligned;
unsigned char *buf = (unsigned char *)aMalloc(fsize);
- fseek(in, entry->srcpos, 0);
- if(fread(buf, 1, fsize, in) != (size_t)fsize) ShowError("An error occurred in fread in grfio_reads, grfname=%s\n",grfname);
+ unsigned char *buf2 = NULL;
+ if (fseek(in, entry->srcpos, SEEK_SET) != 0
+ || fread(buf, 1, fsize, in) != (size_t)fsize) {
+ ShowError("An error occurred in fread in grfio_reads, grfname=%s\n",grfname);
+ aFree(buf);
+ fclose(in);
+ return NULL;
+ }
fclose(in);
buf2 = (unsigned char *)aMalloc(entry->declen+1); // +1 for resnametable zero-termination
- if( entry->type & FILELIST_TYPE_FILE )
- {// file
+ buf2[entry->declen] = '\0';
+ if (entry->type & FILELIST_TYPE_FILE) {
+ // file
uLongf len;
grf_decode(buf, fsize, entry->type, entry->srclen);
len = entry->declen;
@@ -457,21 +478,23 @@ void* grfio_reads(const char* fname, int* size)
aFree(buf2);
return NULL;
}
- } else {// directory?
+ } else {
+ // directory?
memcpy(buf2, buf, entry->declen);
}
- if( size )
+ if (size)
*size = entry->declen;
aFree(buf);
+ return buf2;
} else {
ShowError("grfio_reads: %s not found (GRF file: %s)\n", fname, grfname);
return NULL;
}
}
- return buf2;
+ return NULL;
}
@@ -506,26 +529,31 @@ static bool isFullEncrypt(const char* fname)
/// Loads all entries in the specified grf file into the filelist.
/// @param gentry index of the grf file name in the gentry_table
-static int grfio_entryread(const char* grfname, int gentry)
+static int grfio_entryread(const char *grfname, int gentry)
{
long grf_size;
unsigned char grf_header[0x2e] = { 0 };
int entry,entrys,ofs,grf_version;
unsigned char *grf_filelist;
- FILE* fp = fopen(grfname, "rb");
+ FILE *fp = fopen(grfname, "rb");
if( fp == NULL ) {
ShowWarning("GRF data file not found: '%s'\n",grfname);
return 1; // 1:not found error
- } else
+ } else {
ShowInfo("GRF data file found: '%s'\n",grfname);
+ }
fseek(fp,0,SEEK_END);
grf_size = ftell(fp);
fseek(fp,0,SEEK_SET);
- if(fread(grf_header,1,0x2e,fp) != 0x2e) { ShowError("Couldn't read all grf_header element of %s \n", grfname); }
- if( strcmp((const char*)grf_header,"Master of Magic") != 0 || fseek(fp,getlong(grf_header+0x1e),SEEK_CUR) != 0 ) {
+ if (fread(grf_header,1,0x2e,fp) != 0x2e) {
+ ShowError("Couldn't read all grf_header element of %s \n", grfname);
+ fclose(fp);
+ return 2; // 2:file format error
+ }
+ if (strcmp((const char*)grf_header,"Master of Magic") != 0 || fseek(fp,getlong(grf_header+0x1e),SEEK_CUR) != 0) {
fclose(fp);
ShowError("GRF %s read error\n", grfname);
return 2; // 2:file format error
@@ -533,32 +561,37 @@ static int grfio_entryread(const char* grfname, int gentry)
grf_version = getlong(grf_header+0x2a) >> 8;
- if( grf_version == 0x01 ) {// ****** Grf version 01xx ******
+ if (grf_version == 0x01) {
+ // ****** Grf version 01xx ******
long list_size;
list_size = grf_size - ftell(fp);
- grf_filelist = (unsigned char *) aMalloc(list_size);
- if(fread(grf_filelist,1,list_size,fp) != (size_t)list_size) { ShowError("Couldn't read all grf_filelist element of %s \n", grfname); }
+ grf_filelist = (unsigned char *)aMalloc(list_size);
+ if (fread(grf_filelist,1,list_size,fp) != (size_t)list_size) {
+ ShowError("Couldn't read all grf_filelist element of %s \n", grfname);
+ aFree(grf_filelist);
+ fclose(fp);
+ return 2; // 2:file format error
+ }
fclose(fp);
entrys = getlong(grf_header+0x26) - getlong(grf_header+0x22) - 7;
// Get an entry
- for( entry = 0, ofs = 0; entry < entrys; ++entry ) {
+ for (entry = 0, ofs = 0; entry < entrys; ++entry) {
FILELIST aentry;
-
int ofs2 = ofs+getlong(grf_filelist+ofs)+4;
unsigned char type = grf_filelist[ofs2+12];
- if( type & FILELIST_TYPE_FILE ) {
- char* fname = decode_filename(grf_filelist+ofs+6, grf_filelist[ofs]-6);
+ if (type&FILELIST_TYPE_FILE) {
+ char *fname = decode_filename(grf_filelist+ofs+6, grf_filelist[ofs]-6);
int srclen = getlong(grf_filelist+ofs2+0) - getlong(grf_filelist+ofs2+8) - 715;
- if( strlen(fname) > sizeof(aentry.fn) - 1 ) {
+ if (strlen(fname) > sizeof(aentry.fn) - 1) {
ShowFatalError("GRF file name %s is too long\n", fname);
aFree(grf_filelist);
- exit(EXIT_FAILURE);
+ return 5; // 5: file name too long
}
- type |= ( isFullEncrypt(fname) ) ? FILELIST_TYPE_ENCRYPT_MIXED : FILELIST_TYPE_ENCRYPT_HEADER;
+ type |= isFullEncrypt(fname) ? FILELIST_TYPE_ENCRYPT_MIXED : FILELIST_TYPE_ENCRYPT_HEADER;
aentry.srclen = srclen;
aentry.srclen_aligned = getlong(grf_filelist+ofs2+4)-37579;
@@ -579,45 +612,55 @@ static int grfio_entryread(const char* grfname, int gentry)
}
aFree(grf_filelist);
- } else if( grf_version == 0x02 ) {// ****** Grf version 02xx ******
+ } else if (grf_version == 0x02) {
+ // ****** Grf version 02xx ******
unsigned char eheader[8];
unsigned char *rBuf;
uLongf rSize, eSize;
- if(fread(eheader,1,8,fp) != 8) ShowError("An error occurred in fread while reading header buffer\n");
+ if (fread(eheader,1,8,fp) != 8) {
+ ShowError("An error occurred in fread while reading header buffer\n");
+ fclose(fp);
+ return 4;
+ }
rSize = getlong(eheader); // Read Size
eSize = getlong(eheader+4); // Extend Size
- if( (long)rSize > grf_size-ftell(fp) ) {
+ if ((long)rSize > grf_size-ftell(fp)) {
fclose(fp);
ShowError("Illegal data format: GRF compress entry size\n");
return 4;
}
rBuf = (unsigned char *)aMalloc(rSize); // Get a Read Size
- grf_filelist = (unsigned char *)aMalloc(eSize); // Get a Extend Size
- if(fread(rBuf,1,rSize,fp) != rSize) ShowError("An error occurred in fread \n");
+ if (fread(rBuf,1,rSize,fp) != rSize) {
+ ShowError("An error occurred in fread \n");
+ fclose(fp);
+ aFree(rBuf);
+ return 4;
+ }
fclose(fp);
+ grf_filelist = (unsigned char *)aMalloc(eSize); // Get a Extend Size
decode_zip(grf_filelist, &eSize, rBuf, rSize); // Decode function
aFree(rBuf);
entrys = getlong(grf_header+0x26) - 7;
// Get an entry
- for( entry = 0, ofs = 0; entry < entrys; ++entry ) {
+ for (entry = 0, ofs = 0; entry < entrys; ++entry) {
FILELIST aentry;
-
- char* fname = (char*)(grf_filelist+ofs);
+ char *fname = (char*)(grf_filelist+ofs);
int ofs2 = ofs + (int)strlen(fname)+1;
int type = grf_filelist[ofs2+12];
- if( strlen(fname) > sizeof(aentry.fn)-1 ) {
+ if (strlen(fname) > sizeof(aentry.fn)-1) {
ShowFatalError("GRF file name %s is too long\n", fname);
aFree(grf_filelist);
- exit(EXIT_FAILURE);
+ return 5; // 5: file name too long
}
- if( type & FILELIST_TYPE_FILE ) {// file
+ if (type&FILELIST_TYPE_FILE) {
+ // file
aentry.srclen = getlong(grf_filelist+ofs2+0);
aentry.srclen_aligned = getlong(grf_filelist+ofs2+4);
aentry.declen = getlong(grf_filelist+ofs2+8);
diff --git a/src/common/md5calc.c b/src/common/md5calc.c
index 18e502da2..7b31a38d6 100644
--- a/src/common/md5calc.c
+++ b/src/common/md5calc.c
@@ -222,12 +222,12 @@ void MD5_Binary(const char * string, unsigned char * output)
}
/** output is the coded character sequence in the character sequence which wants to code string. */
-void MD5_String(const char * string, char * output)
+void MD5_String(const char *string, char *output)
{
unsigned char digest[16];
MD5_String2binary(string,digest);
- sprintf(output, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ snprintf(output, 33, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
digest[ 0], digest[ 1], digest[ 2], digest[ 3],
digest[ 4], digest[ 5], digest[ 6], digest[ 7],
digest[ 8], digest[ 9], digest[10], digest[11],
diff --git a/src/common/socket.c b/src/common/socket.c
index 9fe08e6f1..1b7f36f8b 100644
--- a/src/common/socket.c
+++ b/src/common/socket.c
@@ -311,15 +311,18 @@ void setsocketopts(int fd, struct hSockOpt *opt) {
// set SO_REAUSEADDR to true, unix only. on windows this option causes
// the previous owner of the socket to give up, which is not desirable
// in most cases, neither compatible with unix.
- sSetsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&yes,sizeof(yes));
+ if (sSetsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&yes,sizeof(yes)))
+ ShowWarning("setsocketopts: Unable to set SO_REUSEADDR mode for connection #%d!\n", fd);
#ifdef SO_REUSEPORT
- sSetsockopt(fd,SOL_SOCKET,SO_REUSEPORT,(char *)&yes,sizeof(yes));
-#endif
-#endif
+ if (sSetsockopt(fd,SOL_SOCKET,SO_REUSEPORT,(char *)&yes,sizeof(yes)))
+ ShowWarning("setsocketopts: Unable to set SO_REUSEPORT mode for connection #%d!\n", fd);
+#endif // SO_REUSEPORT
+#endif // WIN32
// Set the socket into no-delay mode; otherwise packets get delayed for up to 200ms, likely creating server-side lag.
// The RO protocol is mainly single-packet request/response, plus the FIFO model already does packet grouping anyway.
- sSetsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof(yes));
+ if (sSetsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof(yes)))
+ ShowWarning("setsocketopts: Unable to set TCP_NODELAY mode for connection #%d!\n", fd);
if( opt && opt->setTimeo ) {
struct timeval timeout;
@@ -327,8 +330,10 @@ void setsocketopts(int fd, struct hSockOpt *opt) {
timeout.tv_sec = 5;
timeout.tv_usec = 0;
- sSetsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout));
- sSetsockopt(fd,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout));
+ if (sSetsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout)))
+ ShowWarning("setsocketopts: Unable to set SO_RCVTIMEO for connection #%d!\n", fd);
+ if (sSetsockopt(fd,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout)))
+ ShowWarning("setsocketopts: Unable to set SO_SNDTIMEO for connection #%d!\n", fd);
}
// force the socket into no-wait, graceful-close mode (should be the default, but better make sure)
@@ -339,10 +344,12 @@ void setsocketopts(int fd, struct hSockOpt *opt) {
ShowWarning("setsocketopts: Unable to set SO_LINGER mode for connection #%d!\n", fd);
#ifdef TCP_THIN_LINEAR_TIMEOUTS
- setsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, &yes, sizeof yes);
+ if (sSetsockopt(fd, IPPROTO_TCP, TCP_THIN_LINEAR_TIMEOUTS, (char *)&yes, sizeof(yes)))
+ ShowWarning("setsocketopts: Unable to set TCP_THIN_LINEAR_TIMEOUTS mode for connection #%d!\n", fd);
#endif
#ifdef TCP_THIN_DUPACK
- setsockopt(fd, IPPROTO_TCP, TCP_THIN_DUPACK, &yes, sizeof yes);
+ if (sSetsockopt(fd, IPPROTO_TCP, TCP_THIN_DUPACK, (char *)&yes, sizeof(yes)))
+ ShowWarning("setsocketopts: Unable to set TCP_THIN_DUPACK mode for connection #%d!\n", fd);
#endif
}
@@ -1276,6 +1283,10 @@ int socket_getips(uint32* ips, int max)
u_long ad;
fd = sSocket(AF_INET, SOCK_STREAM, 0);
+ if (fd == -1) {
+ ShowError("socket_getips: Unable to create a socket!\n");
+ return 0;
+ }
memset(buf, 0x00, sizeof(buf));
diff --git a/src/common/sql.c b/src/common/sql.c
index aec2ae93d..4ca14d43b 100644
--- a/src/common/sql.c
+++ b/src/common/sql.c
@@ -1027,9 +1027,8 @@ void Sql_HerculesUpdateCheck(Sql* self) {
continue;
}
- fseek (ufp,1,SEEK_SET);/* woo. skip the # */
-
- if( fgets(timestamp,sizeof(timestamp),ufp) ) {
+ if (fseek(ufp,1,SEEK_SET) == 0 /* woo. skip the # */
+ && fgets(timestamp,sizeof(timestamp),ufp)) {
unsigned int timestampui = (unsigned int)atol(timestamp);
if( SQL_ERROR == SQL->Query(self, "SELECT 1 FROM `sql_updates` WHERE `timestamp` = '%u' LIMIT 1", timestampui) )
Sql_ShowDebug(self);
@@ -1070,9 +1069,8 @@ void Sql_HerculesUpdateSkip(Sql* self,const char *filename) {
return;
}
- fseek (ifp,1,SEEK_SET);/* woo. skip the # */
-
- if( fgets(timestamp,sizeof(timestamp),ifp) ) {
+ if (fseek (ifp,1,SEEK_SET) == 0 /* woo. skip the # */
+ && fgets(timestamp,sizeof(timestamp),ifp)) {
unsigned int timestampui = (unsigned int)atol(timestamp);
if( SQL_ERROR == SQL->Query(self, "SELECT 1 FROM `sql_updates` WHERE `timestamp` = '%u' LIMIT 1", timestampui) )
Sql_ShowDebug(self);
diff --git a/src/common/utils.c b/src/common/utils.c
index c168bd74e..ad68706ca 100644
--- a/src/common/utils.c
+++ b/src/common/utils.c
@@ -354,40 +354,51 @@ const char* timestamp2string(char* str, size_t size, time_t timestamp, const cha
/* [Ind/Hercules] Caching */
-bool HCache_check(const char *file) {
+bool HCache_check(const char *file)
+{
struct stat bufa, bufb;
FILE *first, *second;
char s_path[255], dT[1];
time_t rtime;
- if( !(first = fopen(file,"rb")) )
+ if (!(first = fopen(file,"rb")))
return false;
- if( file[0] == '.' && file[1] == '/' )
+ if (file[0] == '.' && file[1] == '/')
file += 2;
- else if( file[0] == '.' )
+ else if (file[0] == '.')
file++;
snprintf(s_path, 255, "./cache/%s", file);
- if( !(second = fopen(s_path,"rb")) ) {
+ if (!(second = fopen(s_path,"rb"))) {
fclose(first);
return false;
}
- if( fread(dT,sizeof(dT),1,second) != 1 || fread(&rtime,sizeof(rtime),1,second) != 1 || dT[0] != HCACHE_KEY || HCache->recompile_time > rtime ) {
+ if (fread(dT,sizeof(dT),1,second) != 1
+ || fread(&rtime,sizeof(rtime),1,second) != 1
+ || dT[0] != HCACHE_KEY
+ || HCache->recompile_time > rtime) {
fclose(first);
fclose(second);
return false;
}
- fstat(fileno(first), &bufa);
- fstat(fileno(second), &bufb);
-
+ if (fstat(fileno(first), &bufa) != 0) {
+ fclose(first);
+ fclose(second);
+ return false;
+ }
fclose(first);
+
+ if (fstat(fileno(second), &bufb) != 0) {
+ fclose(second);
+ return false;
+ }
fclose(second);
- if( bufa.st_mtime > bufb.st_mtime )
+ if (bufa.st_mtime > bufb.st_mtime)
return false;
return true;
@@ -414,24 +425,26 @@ FILE *HCache_open(const char *file, const char *opt) {
hwrite(dT,sizeof(dT),1,first);
hwrite(&HCache->recompile_time,sizeof(HCache->recompile_time),1,first);
}
- fseek(first, 20, SEEK_SET);/* skip first 20, might wanna store something else later */
+ if (fseek(first, 20, SEEK_SET) != 0) { // skip first 20, might wanna store something else later
+ fclose(first);
+ return NULL;
+ }
return first;
}
-void HCache_init(void) {
- FILE *server;
-
- if( (server = fopen(SERVER_NAME,"rb")) ) {
- struct stat buf;
-
- fstat(fileno(server), &buf);
- HCache->recompile_time = buf.st_mtime;
- fclose(server);
- HCache->enabled = true;
- } else
+void HCache_init(void)
+{
+ struct stat buf;
+ if (stat(SERVER_NAME, &buf) != 0) {
ShowWarning("Unable to open '%s', caching capabilities have been disabled!\n",SERVER_NAME);
+ return;
+ }
+
+ HCache->recompile_time = buf.st_mtime;
+ HCache->enabled = true;
}
+
/* transit to fread, shields vs warn_unused_result */
size_t hread(void * ptr, size_t size, size_t count, FILE * stream) {
return fread(ptr, size, count, stream);