git-svn-id: file:///var/lib/svn/clamav-devel/branches/clamd-proto@4626 77e5149b-7576-45b1-b177-96237e5ba77b
aCaB authored on 2009/01/21 02:46:47... | ... |
@@ -21,6 +21,7 @@ |
21 | 21 |
#endif |
22 | 22 |
|
23 | 23 |
#include <stdio.h> |
24 |
+#include <stdlib.h> |
|
24 | 25 |
#include <unistd.h> |
25 | 26 |
#include <string.h> |
26 | 27 |
#include <sys/types.h> |
... | ... |
@@ -35,6 +36,8 @@ |
35 | 35 |
#include <netdb.h> |
36 | 36 |
#include <utime.h> |
37 | 37 |
#include <errno.h> |
38 |
+#include <dirent.h> |
|
39 |
+ |
|
38 | 40 |
|
39 | 41 |
#ifdef HAVE_SYS_UIO_H |
40 | 42 |
#include <sys/uio.h> |
... | ... |
@@ -195,31 +198,18 @@ static int dsresult(int sockd, const char *scantype, const char *filename) |
195 | 195 |
|
196 | 196 |
static int dsstream(int sockd) |
197 | 197 |
{ |
198 |
- int wsockd, loopw = 60, bread, port, infected = 0; |
|
198 |
+ int wsockd, bread, port, infected = 0; |
|
199 | 199 |
struct sockaddr_in server; |
200 | 200 |
struct sockaddr_in peer; |
201 | 201 |
socklen_t peer_size; |
202 |
+ struct RCVLN rcv; |
|
202 | 203 |
char buff[4096], *pt; |
203 | 204 |
|
204 | 205 |
|
205 |
- if(write(sockd, "STREAM", 6) <= 0) { |
|
206 |
- logg("!Can't write to the socket.\n"); |
|
207 |
- return 2; |
|
208 |
- } |
|
209 |
- |
|
210 |
- while(loopw) { |
|
211 |
- memset(buff, 0, sizeof(buff)); |
|
212 |
- if(read(sockd, buff, sizeof(buff)) > 0) { |
|
213 |
- if((pt = strstr(buff, "PORT"))) { |
|
214 |
- pt += 5; |
|
215 |
- sscanf(pt, "%d", &port); |
|
216 |
- break; |
|
217 |
- } |
|
218 |
- } |
|
219 |
- loopw--; |
|
220 |
- } |
|
221 |
- |
|
222 |
- if(!loopw) { |
|
206 |
+ if(sendln(sockd, "zSTREAM", 8)) return 2; |
|
207 |
+ recvlninit(&rcv, sockd); |
|
208 |
+ bread = recvln(&rcv, &pt, NULL); |
|
209 |
+ if(bread < 7 || memcmp(pt, "PORT ", 5) || (port = atoi(&pt[5])) == 0) { |
|
223 | 210 |
logg("!Daemon not ready for stream scanning.\n"); |
224 | 211 |
return -1; |
225 | 212 |
} |
... | ... |
@@ -261,8 +251,9 @@ static int dsstream(int sockd) |
261 | 261 |
return -1; |
262 | 262 |
} |
263 | 263 |
|
264 |
- while((bread = read(0, buff, sizeof(buff))) > 0) { |
|
265 |
- if(write(wsockd, buff, bread) <= 0) { |
|
264 |
+ while((bread = read(0, buff, sizeof(buff))) > 0) { /* FIXME: this is stdin only, not nice */ |
|
265 |
+ if(sendln(wsockd, buff, bread)) { |
|
266 |
+ /* FIXME: we may just be overlimit here */ |
|
266 | 267 |
logg("!Can't write to the socket.\n"); |
267 | 268 |
close(wsockd); |
268 | 269 |
return -1; |
... | ... |
@@ -270,7 +261,13 @@ static int dsstream(int sockd) |
270 | 270 |
} |
271 | 271 |
close(wsockd); |
272 | 272 |
|
273 |
+ bread = recvln(&rcv, &pt, NULL); |
|
274 |
+ /* logg("~%s\n", bol); *//* FIXME: btw this is useless spam */ |
|
275 |
+ |
|
276 |
+ /* HERE */ |
|
277 |
+ |
|
273 | 278 |
memset(buff, 0, sizeof(buff)); |
279 |
+ |
|
274 | 280 |
while((bread = read(sockd, buff, sizeof(buff))) > 0) { |
275 | 281 |
logg("%s", buff); |
276 | 282 |
if(strstr(buff, "FOUND\n")) { |
... | ... |
@@ -449,6 +446,84 @@ int reload_clamd_database(const struct optstruct *opts) |
449 | 449 |
return 0; |
450 | 450 |
} |
451 | 451 |
|
452 |
+static int client_scan(const char *file, const char *scantype, int *infected, int *errors, const struct optstruct *opts) { |
|
453 |
+ struct stat sb; |
|
454 |
+ char *fullpath; |
|
455 |
+ DIR *dir; |
|
456 |
+ struct dirent *dent; |
|
457 |
+ int ret, sockd; |
|
458 |
+ |
|
459 |
+ /* BUF |
|
460 |
+ basename/thisname/child */ |
|
461 |
+ |
|
462 |
+ if(stat(file, &sb) == -1) { |
|
463 |
+ logg("^Can't access file %s\n", file); |
|
464 |
+ perror(file); |
|
465 |
+ (*errors)++; |
|
466 |
+ return 0; |
|
467 |
+ } |
|
468 |
+ if(!(fullpath = malloc(PATH_MAX + 1))) { |
|
469 |
+ logg("^Can't make room for fullpath.\n"); |
|
470 |
+ (*errors)++; |
|
471 |
+ return 0; |
|
472 |
+ } |
|
473 |
+ |
|
474 |
+ if(*file != '/') { /* FIXME: to be unified */ |
|
475 |
+ int namelen; |
|
476 |
+ if(!getcwd(fullpath, PATH_MAX)) { |
|
477 |
+ logg("^Can't get absolute pathname of current working directory.\n"); |
|
478 |
+ free(fullpath); |
|
479 |
+ (*errors)++; |
|
480 |
+ return 0; |
|
481 |
+ } |
|
482 |
+ namelen = strlen(fullpath); |
|
483 |
+ snprintf(&fullpath[namelen], PATH_MAX - namelen, "/%s", file); |
|
484 |
+ } else { |
|
485 |
+ strncpy(fullpath, file, PATH_MAX); |
|
486 |
+ } |
|
487 |
+ fullpath[PATH_MAX] = '\0'; |
|
488 |
+ |
|
489 |
+ /* FIXME: i should break out ASAP here for SCAN, continue for MULTISCAN, CONTSCAN */ |
|
490 |
+ switch(sb.st_mode & S_IFMT) { |
|
491 |
+ case S_IFDIR: |
|
492 |
+ /* FIXME: if (remote) { */ |
|
493 |
+ if(!(dir = opendir(file))) |
|
494 |
+ break; |
|
495 |
+ ret = strlen(fullpath); |
|
496 |
+ while((dent = readdir(dir))) { |
|
497 |
+ if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) continue; |
|
498 |
+ snprintf(&fullpath[ret], PATH_MAX - ret, "/%s", dent->d_name); |
|
499 |
+ fullpath[PATH_MAX] = '\0'; |
|
500 |
+ if(client_scan(fullpath, scantype, infected, errors, opts)) { |
|
501 |
+ closedir(dir); |
|
502 |
+ free(fullpath); |
|
503 |
+ return 1; |
|
504 |
+ } |
|
505 |
+ } |
|
506 |
+ closedir(dir); |
|
507 |
+ break; |
|
508 |
+ /* } else fallback to S_IFREG for external recursion */ |
|
509 |
+ |
|
510 |
+ case S_IFREG: |
|
511 |
+ if((sockd = dconnect(opts, NULL)) < 0) |
|
512 |
+ return 1; |
|
513 |
+ |
|
514 |
+ if((ret = dsresult(sockd, scantype, fullpath)) >= 0) |
|
515 |
+ *infected += ret; |
|
516 |
+ else |
|
517 |
+ (*errors)++; |
|
518 |
+ close(sockd); |
|
519 |
+ break; |
|
520 |
+ |
|
521 |
+ default: |
|
522 |
+ logg("^Not supported file type (%s)\n", fullpath); |
|
523 |
+ errors++; |
|
524 |
+ } |
|
525 |
+ |
|
526 |
+ free(fullpath); |
|
527 |
+ return 0; |
|
528 |
+} |
|
529 |
+ |
|
452 | 530 |
int client(const struct optstruct *opts, int *infected) |
453 | 531 |
{ |
454 | 532 |
char cwd[PATH_MAX+1], *fullpath; |
... | ... |
@@ -461,6 +536,9 @@ int client(const struct optstruct *opts, int *infected) |
461 | 461 |
|
462 | 462 |
if(optget(opts, "multiscan")->enabled) |
463 | 463 |
scantype = "MULTISCAN"; |
464 |
+ client_scan(opts->filename, scantype, infected, &errors, opts); |
|
465 |
+ return 0; /* FIXME */ |
|
466 |
+ |
|
464 | 467 |
|
465 | 468 |
/* parse argument list */ |
466 | 469 |
if(opts->filename == NULL || strlen(opts->filename) == 0) { |