Browse code

restored non-scan commands

git-svn-id: file:///var/lib/svn/clamav-devel/branches/clamd-proto@4634 77e5149b-7576-45b1-b177-96237e5ba77b

aCaB authored on 2009/01/23 18:59:40
Showing 1 changed files
... ...
@@ -55,11 +55,11 @@
55 55
 int notremoved = 0, notmoved = 0;
56 56
 int printinfected = 0;
57 57
 
58
-struct sockaddr *mainsa = NULL;
59
-int mainsasz;
60
-struct sockaddr_un nixsock;
61
-struct sockaddr_in tcpsock;
62
-struct sockaddr_in strmsock;
58
+static struct sockaddr *mainsa = NULL;
59
+static int mainsasz;
60
+static struct sockaddr_un nixsock;
61
+static struct sockaddr_in tcpsock;
62
+static struct sockaddr_in strmsock;
63 63
 enum {
64 64
     CONT,
65 65
     MULTI,
... ...
@@ -170,11 +170,11 @@ static int recvln(struct RCVLN *s, char **rbol, char **reol) {
170 170
 
171 171
 static int dsresult(int sockd, int scantype, const char *filename)
172 172
 {
173
-    int infected = 0, waserror = 0, fd;
173
+	int infected = 0, waserror = 0, fd;
174 174
 	int len;
175 175
 	char *bol, *eol;
176
-	struct RCVLN rcv;
177 176
 	char buf[BUFSIZ];    
177
+	struct RCVLN rcv;
178 178
 
179 179
     recvlninit(&rcv, sockd);
180 180
 
... ...
@@ -197,7 +197,7 @@ static int dsresult(int sockd, int scantype, const char *filename)
197 197
 
198 198
 	    if(!(fd = open(filename, O_RDONLY))) {
199 199
 		logg("!Open failed on %s.\n", filename);
200
-		return -1; /* FIXME: grave ? */
200
+		return -1;
201 201
 	    }
202 202
 	    if(sendln(sockd, "zSTREAM", 8)) return -1;
203 203
 	    if(!(len = recvln(&rcv, &bol, &eol)) || len < 7 || memcmp(bol, "PORT ", 5) || !(len = atoi(bol + 5))) return -1;
... ...
@@ -240,10 +240,13 @@ static int dsresult(int sockd, int scantype, const char *filename)
240 240
 	    unsigned char fdbuf[CMSG_SPACE(sizeof(int))];
241 241
 	    char dummy[]="";
242 242
 
243
-	    if(!(fd = open(filename, O_RDONLY))) {
244
-		logg("!Open failed on %s.\n", filename);
245
-		return -1; /* FIXME: grave ? */
246
-
243
+	    if(filename) {
244
+		if(!(fd = open(filename, O_RDONLY))) {
245
+		    logg("!Open failed on %s.\n", filename);
246
+		    return -1;
247
+		}
248
+	    } else {
249
+		fd = 0;
247 250
 	    }
248 251
 	    if(sendln(sockd, "zFILDES", 8)) return -1;
249 252
 
... ...
@@ -321,56 +324,56 @@ static int dconnect()
321 321
     return sockd;
322 322
 }
323 323
 
324
-int get_clamd_version(const struct optstruct *opts)
325
-{
326
-	char buff[64];
327
-	int bread, sockd;
328
-
329
-
330
-    /* FIXME: call isremote */
331
-    if((sockd = dconnect()) < 0)
332
-	return 2;
324
+static int isremote(const struct optstruct *opts) {
325
+    int s, ret;
326
+    const struct optstruct *opt;
327
+    struct hostent *he;
328
+    struct optstruct *clamdopts;
329
+    const char *clamd_conf = optget(opts, "config-file")->strarg;
333 330
 
334
-    if(write(sockd, "VERSION", 7) <= 0) {
335
-	logg("!Can't write to the socket.\n");
336
-	close(sockd);
337
-	return 2;
331
+    if((clamdopts = optparse(clamd_conf, 0, NULL, 1, OPT_CLAMD, 0, NULL)) == NULL) {
332
+	logg("!Can't parse clamd configuration file %s\n", clamd_conf);
333
+	return 0;
338 334
     }
339
-
340
-    while((bread = read(sockd, buff, sizeof(buff)-1)) > 0) {
341
-	buff[bread] = '\0';
342
-	printf("%s\n", buff);
335
+    if(optget(clamdopts, "LocalSocket")->enabled) {
336
+	memset((void *)&nixsock, 0, sizeof(nixsock));
337
+	nixsock.sun_family = AF_UNIX;
338
+	strncpy(nixsock.sun_path, opt->strarg, sizeof(nixsock.sun_path));
339
+	nixsock.sun_path[sizeof(nixsock.sun_path)-1]='\0';
340
+	mainsa = (struct sockaddr *)&nixsock;
341
+	mainsasz = sizeof(nixsock);
342
+	optfree(clamdopts);
343
+	return 0;
343 344
     }
344
-
345
-    close(sockd);
346
-    return 0;
347
-}
348
-
349
-int reload_clamd_database(const struct optstruct *opts)
350
-{
351
-	char buff[64];
352
-	int bread, sockd;
353
-
354
-
355
-    /* FIXME: call isremote */
356
-    if((sockd = dconnect()) < 0)
357
-	return 2;
358
-
359
-    if(write(sockd, "RELOAD", 6) <= 0) {
360
-	logg("!Can't write to the socket.\n");
361
-	close(sockd);
362
-	return 2;
345
+    if(!(opt = optget(clamdopts, "TCPSocket"))->enabled) {
346
+	optfree(clamdopts);
347
+	return 0;
363 348
     }
364
-
365
-    bread = read(sockd, buff, sizeof(buff) - 1);
366
-    if(bread == -1 || strncmp(buff, "RELOADING", 9)) {
367
-	logg("!Incorrect reply from clamd\n");
368
-	close(sockd);
369
-	return 2;
349
+    mainsa = (struct sockaddr *)&tcpsock;
350
+    mainsasz = sizeof(tcpsock);
351
+    memset((void *)&tcpsock, 0, sizeof(tcpsock));
352
+    memset((void *)&strmsock, 0, sizeof(strmsock));
353
+    tcpsock.sin_family = strmsock.sin_family = AF_INET;
354
+    tcpsock.sin_port = htons(opt->numarg);
355
+    if(!(opt = optget(clamdopts, "TCPAddr"))->enabled) {
356
+	tcpsock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
357
+	optfree(clamdopts);
358
+	return 0;
370 359
     }
371
-
372
-    close(sockd);
373
-    return 0;
360
+    he = gethostbyname(opt->strarg);
361
+    optfree(clamdopts);
362
+    if(!he) {
363
+	perror("gethostbyname()");
364
+	logg("!Can't lookup clamd hostname.\n");
365
+	mainsa = NULL;
366
+	return 0;
367
+    }
368
+    strmsock.sin_port = htons(INADDR_ANY);
369
+    tcpsock.sin_addr = strmsock.sin_addr = *(struct in_addr *) he->h_addr_list[0];
370
+    if(!(s = socket(tcpsock.sin_family, SOCK_STREAM, 0))) return 0;
371
+    ret = (bind(s, (struct sockaddr *)&strmsock, sizeof(strmsock)) != 0);
372
+    close(s);
373
+    return ret;
374 374
 }
375 375
 
376 376
 static int client_scan(const char *file, int scantype, int *infected, int *errors) {
... ...
@@ -430,7 +433,6 @@ static int client_scan(const char *file, int scantype, int *infected, int *error
430 430
     case S_IFREG:
431 431
 	if((sockd = dconnect()) < 0)
432 432
 	    return 1;
433
-
434 433
 	if((ret = dsresult(sockd, scantype, fullpath)) >= 0)
435 434
 	    *infected += ret;
436 435
 	else
... ...
@@ -447,65 +449,82 @@ static int client_scan(const char *file, int scantype, int *infected, int *error
447 447
     return 0;
448 448
 }
449 449
 
450
-static int isremote(struct optstruct *clamdopts) {
451
-    int s, ret;
452
-    const struct optstruct *opt;
453
-    struct hostent *he;
450
+int get_clamd_version(const struct optstruct *opts)
451
+{
452
+	char *buff;
453
+	int len, sockd;
454
+	struct RCVLN rcv;
454 455
 
455
-    if(optget(clamdopts, "LocalSocket")->enabled) {
456
-	memset((void *)&nixsock, 0, sizeof(nixsock));
457
-	nixsock.sun_family = AF_UNIX;
458
-	strncpy(nixsock.sun_path, opt->strarg, sizeof(nixsock.sun_path));
459
-	nixsock.sun_path[sizeof(nixsock.sun_path)-1]='\0';
460
-	mainsa = (struct sockaddr *)&nixsock;
461
-	mainsasz = sizeof(nixsock);
462
-	return 0;
456
+    recvlninit(&rcv, sockd);
457
+    isremote(opts);
458
+    if(!mainsa) return 2;
459
+    if((sockd = dconnect()) < 0) return 2;
460
+
461
+    if(sendln(sockd, "zVERSION", 9)) {
462
+	logg("!Can't write to the socket.\n");
463
+	close(sockd);
464
+	return 2;
463 465
     }
464
-    if(!(opt = optget(clamdopts, "TCPSocket"))->enabled) return 0;
465
-    mainsa = (struct sockaddr *)&tcpsock;
466
-    mainsasz = sizeof(tcpsock);
467
-    memset((void *)&tcpsock, 0, sizeof(tcpsock));
468
-    memset((void *)&strmsock, 0, sizeof(strmsock));
469
-    tcpsock.sin_family = strmsock.sin_family = AF_INET;
470
-    tcpsock.sin_port = htons(opt->numarg);
471
-    if(!(opt = optget(clamdopts, "TCPAddr"))->enabled) {
472
-	tcpsock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
473
-	return 0;
466
+
467
+    while((len = recvln(&rcv, &buff, NULL))) {
468
+	if(len == -1) {
469
+	    logg("!Error occoured while receiving version information.\n");
470
+	    break;
471
+	}
472
+	printf("%s\n", buff);
474 473
     }
475
-    if(!(he = gethostbyname(opt->strarg))) {
476
-	perror("gethostbyname()");
477
-	logg("!Can't lookup clamd hostname.\n");
478
-	mainsa = NULL;
479
-	return 0;
474
+
475
+    close(sockd);
476
+    return 0;
477
+}
478
+
479
+int reload_clamd_database(const struct optstruct *opts)
480
+{
481
+	char *buff;
482
+	int len, sockd;
483
+	struct RCVLN rcv;
484
+
485
+    recvlninit(&rcv, sockd);
486
+    isremote(opts);
487
+    if(!mainsa) return 2;
488
+    if((sockd = dconnect()) < 0) return 2;
489
+
490
+    if(sendln(sockd, "zRELOAD", 8)) {
491
+	logg("!Can't write to the socket.\n");
492
+	close(sockd);
493
+	return 2;
480 494
     }
481
-    strmsock.sin_port = htons(INADDR_ANY);
482
-    tcpsock.sin_addr = strmsock.sin_addr = *(struct in_addr *) he->h_addr_list[0];
483
-    if(!(s = socket(tcpsock.sin_family, SOCK_STREAM, 0))) return 0;
484
-    ret = (bind(s, (struct sockaddr *)&strmsock, sizeof(strmsock)) != 0);
485
-    close(s);
486
-    return ret;
495
+
496
+    if(!(len = recvln(&rcv, &buff, NULL)) || len < 10 || memcmp(buff, "RELOADING", 9)) {
497
+	logg("!Incorrect reply from clamd\n");
498
+	close(sockd);
499
+	return 2;
500
+    }
501
+
502
+    close(sockd);
503
+    return 0;
487 504
 }
488 505
 
489 506
 int client(const struct optstruct *opts, int *infected)
490 507
 {
491
-	int errors = 0;
492 508
 	const char *clamd_conf = optget(opts, "config-file")->strarg;
493 509
 	struct optstruct *clamdopts;
494
-	int scantype, session = 0;
510
+	int scantype, session = 0, errors = 0, scandash = 0;
495 511
 
496 512
     if((clamdopts = optparse(clamd_conf, 0, NULL, 1, OPT_CLAMD, 0, NULL)) == NULL) {
497 513
 	logg("!Can't parse clamd configuration file %s\n", clamd_conf);
498 514
 	return 2;
499 515
     }
500 516
 
501
-    /* FIXME: save the connection method once for all */
502
-    if(isremote(clamdopts)) {
517
+    scandash = (opts->filename && opts->filename[0] && !strcmp(opts->filename[0], "-") && !opts->filename[1]);
518
+    if(isremote(opts)) {
503 519
 	scantype = STREAM;
504 520
 	session = optget(opts, "multiscan")->enabled;
505 521
 #ifdef HAVE_FD_PASSING
506
-    } else if(optget(clamdopts, "LocalSocket")->enabled && optget(opts, "fdpass")->enabled) {
522
+    } else if(optget(clamdopts, "LocalSocket")->enabled && (optget(opts, "fdpass")->enabled || scandash)) {
507 523
 	scantype = FILDES;
508 524
 	session = optget(opts, "multiscan")->enabled;
525
+	scandash <<= 1;
509 526
 #endif
510 527
     } else if(optget(opts, "multiscan")->enabled) scantype = MULTI;
511 528
     else scantype = CONT;
... ...
@@ -519,9 +538,20 @@ int client(const struct optstruct *opts, int *infected)
519 519
 
520 520
     *infected = 0;
521 521
 
522
-    if(opts->filename) {
522
+    if(scandash == 2) {
523
+	int sockd, ret;
524
+	if((sockd = dconnect()) >= 0 && (ret = dsresult(sockd, FILDES, NULL)) >= 0)
525
+	    *infected += ret;
526
+	else
527
+	    errors++;
528
+	close(sockd);
529
+    } else if(opts->filename) {
523 530
 	unsigned int i;
524 531
 	for (i = 0; opts->filename[i]; i++) {
532
+	    if(!strcmp(opts->filename[i], "-")) {
533
+		logg("!Standard input scan requires FD passing support and \"-\" must be the only file argument\n");
534
+		continue;
535
+	    }
525 536
 	    client_scan(opts->filename[i], scantype, infected, &errors);
526 537
 	}
527 538
     } else {