git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@1410 77e5149b-7576-45b1-b177-96237e5ba77b
Tomasz Kojm authored on 2005/03/20 05:35:38... | ... |
@@ -1,3 +1,9 @@ |
1 |
+Sat Mar 19 21:30:33 CET 2005 (tk) |
|
2 |
+--------------------------------- |
|
3 |
+ * clamd: add support for environment variables CLAM_VIRUSEVENT_FILENAME and |
|
4 |
+ CLAM_VIRUSEVENT_VIRUSNAME in virusaction() (patch by |
|
5 |
+ Calin A. Culianu" <calin*ajvar.org>) |
|
6 |
+ |
|
1 | 7 |
Sat Mar 19 01:35:04 CET 2005 (tk) |
2 | 8 |
--------------------------------- |
3 | 9 |
* clamscan: fix detection logic in treewalk() to properly work with external |
... | ... |
@@ -173,7 +173,7 @@ void *clamukoth(void *arg) |
173 | 173 |
|
174 | 174 |
if(scan && cl_scanfile(acc->filename, &virname, NULL, tharg->root, tharg->limits, tharg->options) == CL_VIRUS) { |
175 | 175 |
logg("Clamuko: %s: %s FOUND\n", acc->filename, virname); |
176 |
- virusaction(virname, tharg->copt); |
|
176 |
+ virusaction(acc->filename, virname, tharg->copt); |
|
177 | 177 |
acc->deny = 1; |
178 | 178 |
} else |
179 | 179 |
acc->deny = 0; |
... | ... |
@@ -69,32 +69,61 @@ |
69 | 69 |
#include "cfgparser.h" |
70 | 70 |
#include "session.h" |
71 | 71 |
|
72 |
-void virusaction(const char *virname, const struct cfgstruct *copt) |
|
72 |
+#define ENV_FILE "CLAM_VIRUSEVENT_FILENAME" |
|
73 |
+#define ENV_VIRUS "CLAM_VIRUSEVENT_VIRUSNAME" |
|
74 |
+ |
|
75 |
+void virusaction(const char *filename, const char *virname, const struct cfgstruct *copt) |
|
73 | 76 |
{ |
74 |
- char *buffer, *pt, *cmd; |
|
77 |
+ pid_t pid; |
|
75 | 78 |
struct cfgstruct *cpt; |
76 | 79 |
|
77 |
- |
|
78 | 80 |
if(!(cpt = cfgopt(copt, "VirusEvent"))) |
79 | 81 |
return; |
80 | 82 |
|
81 |
- cmd = strdup(cpt->strarg); |
|
83 |
+ /* NB: we need to fork here since this function modifies the environment. |
|
84 |
+ (Modifications to the env. are not reentrant, but we need to be.) */ |
|
85 |
+ pid = fork(); |
|
86 |
+ |
|
87 |
+ if ( pid == 0 ) { |
|
88 |
+ /* child... */ |
|
89 |
+ char *buffer, *pt, *cmd; |
|
82 | 90 |
|
83 |
- if((pt = strstr(cmd, "%v"))) { |
|
84 |
- buffer = (char *) mcalloc(strlen(cmd) + strlen(virname) + 10, sizeof(char)); |
|
85 |
- *pt = 0; pt += 2; |
|
86 |
- strcpy(buffer, cmd); |
|
87 |
- strcat(buffer, virname); |
|
88 |
- strcat(buffer, pt); |
|
91 |
+ cmd = strdup(cpt->strarg); |
|
92 |
+ |
|
93 |
+ if((pt = strstr(cmd, "%v"))) { |
|
94 |
+ buffer = (char *) mcalloc(strlen(cmd) + strlen(virname) + 10, sizeof(char)); |
|
95 |
+ *pt = 0; pt += 2; |
|
96 |
+ strcpy(buffer, cmd); |
|
97 |
+ strcat(buffer, virname); |
|
98 |
+ strcat(buffer, pt); |
|
99 |
+ free(cmd); |
|
100 |
+ cmd = strdup(buffer); |
|
101 |
+ free(buffer); |
|
102 |
+ } |
|
103 |
+ |
|
104 |
+ /* Allocate env vars.. to be portable env vars should not be freed */ |
|
105 |
+ buffer = (char *) mcalloc(strlen(ENV_FILE) + strlen(filename) + 2, sizeof(char)); |
|
106 |
+ sprintf(buffer, "%s=%s", ENV_FILE, filename); |
|
107 |
+ putenv(buffer); |
|
108 |
+ |
|
109 |
+ buffer = (char *) mcalloc(strlen(ENV_VIRUS) + strlen(virname) + 2, sizeof(char)); |
|
110 |
+ sprintf(buffer, "%s=%s", ENV_VIRUS, virname); |
|
111 |
+ putenv(buffer); |
|
112 |
+ |
|
113 |
+ |
|
114 |
+ /* WARNING: this is uninterruptable ! */ |
|
115 |
+ exit(system(cmd)); |
|
116 |
+ |
|
117 |
+ /* The below is not reached but is here for completeness to remind |
|
118 |
+ maintainers that this buffer is still allocated.. */ |
|
89 | 119 |
free(cmd); |
90 |
- cmd = strdup(buffer); |
|
91 |
- free(buffer); |
|
120 |
+ } else if (pid > 0) { |
|
121 |
+ /* parent */ |
|
122 |
+ waitpid(pid, NULL, 0); |
|
123 |
+ } else { |
|
124 |
+ /* error.. */ |
|
125 |
+ logg("!VirusAction: fork failed.\n"); |
|
92 | 126 |
} |
93 |
- |
|
94 |
- /* WARNING: this is uninterruptable ! */ |
|
95 |
- system(cmd); |
|
96 |
- |
|
97 |
- free(cmd); |
|
98 | 127 |
} |
99 | 128 |
|
100 | 129 |
int poll_fd(int fd, int timeout_sec) |
... | ... |
@@ -28,7 +28,7 @@ |
28 | 28 |
|
29 | 29 |
int poll_fd(int fd, int timeout_sec); |
30 | 30 |
int is_fd_connected(int fd); |
31 |
-void virusaction(const char *virname, const struct cfgstruct *copt); |
|
31 |
+void virusaction(const char *filename, const char *virname, const struct cfgstruct *copt); |
|
32 | 32 |
int writen(int fd, void *buff, unsigned int count); |
33 | 33 |
|
34 | 34 |
#if defined(HAVE_RECVMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) && !defined(C_CYGWIN) && !defined(C_OS2) |
... | ... |
@@ -159,7 +159,7 @@ int dirscan(const char *dirname, const char **virname, unsigned long int *scanne |
159 | 159 |
|
160 | 160 |
mdprintf(odesc, "%s: %s FOUND\n", fname, *virname); |
161 | 161 |
logg("%s: %s FOUND\n", fname, *virname); |
162 |
- virusaction(*virname, copt); |
|
162 |
+ virusaction(fname, *virname, copt); |
|
163 | 163 |
if(!contscan) { |
164 | 164 |
closedir(dd); |
165 | 165 |
free(fname); |
... | ... |
@@ -237,7 +237,7 @@ int scan(const char *filename, unsigned long int *scanned, const struct cl_node |
237 | 237 |
if(ret == CL_VIRUS) { |
238 | 238 |
mdprintf(odesc, "%s: %s FOUND\n", filename, virname); |
239 | 239 |
logg("%s: %s FOUND\n", filename, virname); |
240 |
- virusaction(virname, copt); |
|
240 |
+ virusaction(filename, virname, copt); |
|
241 | 241 |
} else if(ret != CL_CLEAN) { |
242 | 242 |
mdprintf(odesc, "%s: %s ERROR\n", filename, cl_strerror(ret)); |
243 | 243 |
logg("%s: %s ERROR\n", filename, cl_strerror(ret)); |
... | ... |
@@ -266,6 +266,7 @@ int scanfd(const int fd, unsigned long int *scanned, const struct cl_node *root, |
266 | 266 |
int ret; |
267 | 267 |
const char *virname; |
268 | 268 |
struct stat statbuf; |
269 |
+ char fdstr[32]; |
|
269 | 270 |
|
270 | 271 |
|
271 | 272 |
if(fstat(fd, &statbuf) == -1) |
... | ... |
@@ -274,19 +275,21 @@ int scanfd(const int fd, unsigned long int *scanned, const struct cl_node *root, |
274 | 274 |
if(!S_ISREG(statbuf.st_mode)) |
275 | 275 |
return -1; |
276 | 276 |
|
277 |
+ snprintf(fdstr, sizeof(fdstr), "fd[%d]", fd); |
|
278 |
+ |
|
277 | 279 |
ret = cl_scandesc(fd, &virname, scanned, root, limits, options); |
278 | 280 |
|
279 | 281 |
if(ret == CL_VIRUS) { |
280 |
- mdprintf(odesc, "fd[%d]: %s FOUND\n", fd, virname); |
|
281 |
- logg("fd[%d]: %s FOUND\n", fd, virname); |
|
282 |
- virusaction(virname, copt); |
|
282 |
+ mdprintf(odesc, "%s: %s FOUND\n", fdstr, virname); |
|
283 |
+ logg("%s: %s FOUND\n", fdstr, virname); |
|
284 |
+ virusaction(fdstr, virname, copt); |
|
283 | 285 |
} else if(ret != CL_CLEAN) { |
284 |
- mdprintf(odesc, "fd[%d]: %s ERROR\n", fd, cl_strerror(ret)); |
|
285 |
- logg("fd[%d]: %s ERROR\n", fd, cl_strerror(ret)); |
|
286 |
+ mdprintf(odesc, "%s: %s ERROR\n", fdstr, cl_strerror(ret)); |
|
287 |
+ logg("%s: %s ERROR\n", fdstr, cl_strerror(ret)); |
|
286 | 288 |
} else { |
287 |
- mdprintf(odesc, "fd[%d]: OK\n", fd); |
|
289 |
+ mdprintf(odesc, "%s: OK\n", fdstr); |
|
288 | 290 |
if(logok) |
289 |
- logg("fd[%d]: OK\n", fd); |
|
291 |
+ logg("%s: OK\n", fdstr); |
|
290 | 292 |
} |
291 | 293 |
|
292 | 294 |
return ret; |
... | ... |
@@ -467,7 +470,7 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_node *root |
467 | 467 |
if(ret == CL_VIRUS) { |
468 | 468 |
mdprintf(odesc, "stream: %s FOUND\n", virname); |
469 | 469 |
logg("stream: %s FOUND\n", virname); |
470 |
- virusaction(virname, copt); |
|
470 |
+ virusaction("stream", virname, copt); |
|
471 | 471 |
} else if(ret != CL_CLEAN) { |
472 | 472 |
mdprintf(odesc, "stream: %s ERROR\n", cl_strerror(ret)); |
473 | 473 |
logg("stream: %s ERROR\n", cl_strerror(ret)); |