Browse code

implement internal recursion, to be used when streaming or fdpassing

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
Showing 1 changed files
... ...
@@ -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) {