git-svn: trunk@3578
Török Edvin authored on 2008/02/04 04:23:20... | ... |
@@ -1,3 +1,11 @@ |
1 |
+Sun Feb 3 21:04:54 EET 2008 (edwin) |
|
2 |
+--------------------------------- |
|
3 |
+ * libclamav/others.[ch]: introduce cli_ctime() that uses ctime_r() when |
|
4 |
+ available, and falls back to locking with a mutex around |
|
5 |
+ ctime(). (ensures we are using the same mutex always). |
|
6 |
+ * clamd, shared: use cli_ctime() instead of the thread-unsafe ctime(). |
|
7 |
+ This fixes stability problems. |
|
8 |
+ |
|
1 | 9 |
Sun Feb 3 19:13:43 CET 2008 (tk) |
2 | 10 |
--------------------------------- |
3 | 11 |
* libclamav/filetypes.h: set MAGIC_BUFFER_SIZE to 512 |
... | ... |
@@ -216,6 +216,7 @@ int main(int argc, char **argv) |
216 | 216 |
cl_debug(); |
217 | 217 |
|
218 | 218 |
if((cpt = cfgopt(copt, "LogFile"))->enabled) { |
219 |
+ char timestr[32]; |
|
219 | 220 |
logg_file = cpt->strarg; |
220 | 221 |
if(strlen(logg_file) < 2 || (logg_file[0] != '/' && logg_file[0] != '\\' && logg_file[1] != ':')) { |
221 | 222 |
fprintf(stderr, "ERROR: LogFile requires full path.\n"); |
... | ... |
@@ -224,7 +225,7 @@ int main(int argc, char **argv) |
224 | 224 |
return 1; |
225 | 225 |
} |
226 | 226 |
time(&currtime); |
227 |
- if(logg("#+++ Started at %s", ctime(&currtime))) { |
|
227 |
+ if(logg("#+++ Started at %s", cli_ctime(&currtime, timestr, sizeof(timestr)))) { |
|
228 | 228 |
fprintf(stderr, "ERROR: Problem with internal logger. Please check the permissions on the %s file.\n", logg_file); |
229 | 229 |
logg_close(); |
230 | 230 |
freecfg(copt); |
... | ... |
@@ -50,6 +50,7 @@ |
50 | 50 |
#include "clamuko.h" |
51 | 51 |
#include "others.h" |
52 | 52 |
#include "shared.h" |
53 |
+#include "libclamav/others.h" |
|
53 | 54 |
|
54 | 55 |
#ifndef C_WINDOWS |
55 | 56 |
#define closesocket(s) close(s) |
... | ... |
@@ -260,6 +261,7 @@ int acceptloop_th(int *socketds, int nsockets, struct cl_engine *engine, unsigne |
260 | 260 |
int max_threads, i, ret = 0; |
261 | 261 |
unsigned int options = 0; |
262 | 262 |
threadpool_t *thr_pool; |
263 |
+ char timestr[32]; |
|
263 | 264 |
#ifndef C_WINDOWS |
264 | 265 |
struct sigaction sigact; |
265 | 266 |
#endif |
... | ... |
@@ -664,7 +666,7 @@ int acceptloop_th(int *socketds, int nsockets, struct cl_engine *engine, unsigne |
664 | 664 |
} |
665 | 665 |
|
666 | 666 |
time(¤t_time); |
667 |
- logg("--- Stopped at %s", ctime(¤t_time)); |
|
667 |
+ logg("--- Stopped at %s", cli_ctime(¤t_time, timestr, sizeof(timestr))); |
|
668 | 668 |
|
669 | 669 |
return ret; |
670 | 670 |
} |
... | ... |
@@ -43,6 +43,7 @@ |
43 | 43 |
|
44 | 44 |
#include "libclamav/clamav.h" |
45 | 45 |
#include "libclamav/str.h" |
46 |
+#include "libclamav/others.h" |
|
46 | 47 |
|
47 | 48 |
#include "shared/cfgparser.h" |
48 | 49 |
#include "shared/output.h" |
... | ... |
@@ -53,8 +54,6 @@ |
53 | 53 |
#include "server.h" |
54 | 54 |
#include "session.h" |
55 | 55 |
|
56 |
-static pthread_mutex_t ctime_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
57 |
- |
|
58 | 56 |
int command(int desc, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options, const struct cfgstruct *copt, int timeout) |
59 | 57 |
{ |
60 | 58 |
char buff[1025]; |
... | ... |
@@ -117,11 +116,10 @@ int command(int desc, const struct cl_engine *engine, const struct cl_limits *li |
117 | 117 |
sprintf(path, "%s/daily.cld", dbdir); |
118 | 118 |
|
119 | 119 |
if(!access(path, R_OK) && (daily = cl_cvdhead(path))) { |
120 |
+ char timestr[32]; |
|
120 | 121 |
time_t t = (time_t) daily->stime; |
121 | 122 |
|
122 |
- pthread_mutex_lock(&ctime_mutex); |
|
123 |
- mdprintf(desc, "ClamAV "VERSION"/%d/%s", daily->version, ctime(&t)); |
|
124 |
- pthread_mutex_unlock(&ctime_mutex); |
|
123 |
+ mdprintf(desc, "ClamAV "VERSION"/%d/%s", daily->version, cli_ctime(&t, timestr, sizeof(timestr))); |
|
125 | 124 |
cl_cvdfree(daily); |
126 | 125 |
} else { |
127 | 126 |
mdprintf(desc, "ClamAV "VERSION"\n"); |
... | ... |
@@ -59,6 +59,11 @@ |
59 | 59 |
#ifdef CL_THREAD_SAFE |
60 | 60 |
# include <pthread.h> |
61 | 61 |
static pthread_mutex_t cli_gentemp_mutex = PTHREAD_MUTEX_INITIALIZER; |
62 |
+ |
|
63 |
+# ifndef HAVE_CTIME_R |
|
64 |
+static pthread_mutex_t cli_ctime_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
65 |
+# endif |
|
66 |
+ |
|
62 | 67 |
#endif |
63 | 68 |
|
64 | 69 |
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2) |
... | ... |
@@ -853,3 +858,32 @@ int cli_bitset_test(bitset_t *bs, unsigned long bit_offset) |
853 | 853 |
} |
854 | 854 |
return (bs->bitset[char_offset] & ((unsigned char)1 << bit_offset)); |
855 | 855 |
} |
856 |
+ |
|
857 |
+const char* cli_ctime(const time_t *timep, char *buf, const size_t bufsize) |
|
858 |
+{ |
|
859 |
+ if(bufsize < 26) { |
|
860 |
+ /* standard says we must have at least 26 bytes buffer */ |
|
861 |
+ cli_warnmsg("buffer too small for ctime\n"); |
|
862 |
+ return NULL; |
|
863 |
+ } |
|
864 |
+#ifdef HAVE_CTIME_R |
|
865 |
+# ifdef HAVE_CTIME_R_2 |
|
866 |
+ char* y = ctime_r(timep, buf); |
|
867 |
+ return y; |
|
868 |
+# else |
|
869 |
+ return ctime_r(timep, buf, bufsize); |
|
870 |
+# endif |
|
871 |
+#else /* no ctime_r */ |
|
872 |
+ |
|
873 |
+# ifdef CL_THREAD_SAFE |
|
874 |
+ pthread_mutex_lock(&cli_ctime_mutex); |
|
875 |
+# endif |
|
876 |
+ strncpy(buf, ctime(timep), bufsize-1); |
|
877 |
+ buf[bufsize-1] = '\0'; |
|
878 |
+# ifdef CL_THREAD_SAFE |
|
879 |
+ pthread_mutex_unlock(&cli_ctime_mutex); |
|
880 |
+# endif |
|
881 |
+ return buf; |
|
882 |
+#endif |
|
883 |
+} |
|
884 |
+ |
... | ... |
@@ -230,5 +230,6 @@ bitset_t *cli_bitset_init(void); |
230 | 230 |
void cli_bitset_free(bitset_t *bs); |
231 | 231 |
int cli_bitset_set(bitset_t *bs, unsigned long bit_offset); |
232 | 232 |
int cli_bitset_test(bitset_t *bs, unsigned long bit_offset); |
233 |
+const char* cli_ctime(const time_t *timep, char *buf, const size_t bufsize); |
|
233 | 234 |
|
234 | 235 |
#endif |
... | ... |
@@ -334,6 +334,7 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
334 | 334 |
uint32_t valign, falign, hdr_size, j; |
335 | 335 |
struct cli_exe_section *exe_sections; |
336 | 336 |
struct cli_matcher *md5_sect; |
337 |
+ char timestr[32]; |
|
337 | 338 |
|
338 | 339 |
|
339 | 340 |
if(!ctx) { |
... | ... |
@@ -506,7 +507,7 @@ int cli_scanpe(int desc, cli_ctx *ctx) |
506 | 506 |
cli_dbgmsg("NumberOfSections: %d\n", nsections); |
507 | 507 |
|
508 | 508 |
timestamp = (time_t) EC32(file_hdr.TimeDateStamp); |
509 |
- cli_dbgmsg("TimeDateStamp: %s", ctime(×tamp)); |
|
509 |
+ cli_dbgmsg("TimeDateStamp: %s", cli_ctime(×tamp, timestr, sizeof(timestr))); |
|
510 | 510 |
|
511 | 511 |
cli_dbgmsg("SizeOfOptionalHeader: %x\n", EC16(file_hdr.SizeOfOptionalHeader)); |
512 | 512 |
|
... | ... |
@@ -50,6 +50,7 @@ |
50 | 50 |
#endif |
51 | 51 |
|
52 | 52 |
#include "output.h" |
53 |
+#include "libclamav/others.h" |
|
53 | 54 |
|
54 | 55 |
#ifdef CL_NOTHREADS |
55 | 56 |
#undef CL_THREAD_SAFE |
... | ... |
@@ -132,7 +133,7 @@ int logg(const char *str, ...) |
132 | 132 |
#ifdef F_WRLCK |
133 | 133 |
struct flock fl; |
134 | 134 |
#endif |
135 |
- char *pt, *timestr, vbuff[1025]; |
|
135 |
+ char vbuff[1025]; |
|
136 | 136 |
time_t currtime; |
137 | 137 |
struct stat sb; |
138 | 138 |
mode_t old_umask; |
... | ... |
@@ -189,12 +190,12 @@ int logg(const char *str, ...) |
189 | 189 |
is not set or we get a bunch of timestamps in the log without |
190 | 190 |
newlines... */ |
191 | 191 |
if(logg_time && ((*vbuff != '*') || logg_verbose)) { |
192 |
+ char timestr[32]; |
|
192 | 193 |
time(&currtime); |
193 |
- pt = ctime(&currtime); |
|
194 |
- timestr = calloc(strlen(pt), 1); |
|
195 |
- strncpy(timestr, pt, strlen(pt) - 1); |
|
194 |
+ cli_ctime(&currtime, timestr, sizeof(timestr)); |
|
195 |
+ /* cut trailing \n */ |
|
196 |
+ timestr[strlen(timestr)-1] = '\0'; |
|
196 | 197 |
fprintf(logg_fd, "%s -> ", timestr); |
197 |
- free(timestr); |
|
198 | 198 |
} |
199 | 199 |
|
200 | 200 |
if(*vbuff == '!') { |