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
0.95
aCaB 17 years ago
parent dc3a1def55
commit 87066fbc5b
  1. 120
      clamdscan/client.c

@ -21,6 +21,7 @@
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
@ -35,6 +36,8 @@
#include <netdb.h>
#include <utime.h>
#include <errno.h>
#include <dirent.h>
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
@ -195,31 +198,18 @@ static int dsresult(int sockd, const char *scantype, const char *filename)
static int dsstream(int sockd)
{
int wsockd, loopw = 60, bread, port, infected = 0;
int wsockd, bread, port, infected = 0;
struct sockaddr_in server;
struct sockaddr_in peer;
socklen_t peer_size;
struct RCVLN rcv;
char buff[4096], *pt;
if(write(sockd, "STREAM", 6) <= 0) {
logg("!Can't write to the socket.\n");
return 2;
}
while(loopw) {
memset(buff, 0, sizeof(buff));
if(read(sockd, buff, sizeof(buff)) > 0) {
if((pt = strstr(buff, "PORT"))) {
pt += 5;
sscanf(pt, "%d", &port);
break;
}
}
loopw--;
}
if(!loopw) {
if(sendln(sockd, "zSTREAM", 8)) return 2;
recvlninit(&rcv, sockd);
bread = recvln(&rcv, &pt, NULL);
if(bread < 7 || memcmp(pt, "PORT ", 5) || (port = atoi(&pt[5])) == 0) {
logg("!Daemon not ready for stream scanning.\n");
return -1;
}
@ -261,8 +251,9 @@ static int dsstream(int sockd)
return -1;
}
while((bread = read(0, buff, sizeof(buff))) > 0) {
if(write(wsockd, buff, bread) <= 0) {
while((bread = read(0, buff, sizeof(buff))) > 0) { /* FIXME: this is stdin only, not nice */
if(sendln(wsockd, buff, bread)) {
/* FIXME: we may just be overlimit here */
logg("!Can't write to the socket.\n");
close(wsockd);
return -1;
@ -270,7 +261,13 @@ static int dsstream(int sockd)
}
close(wsockd);
bread = recvln(&rcv, &pt, NULL);
/* logg("~%s\n", bol); *//* FIXME: btw this is useless spam */
/* HERE */
memset(buff, 0, sizeof(buff));
while((bread = read(sockd, buff, sizeof(buff))) > 0) {
logg("%s", buff);
if(strstr(buff, "FOUND\n")) {
@ -449,6 +446,84 @@ int reload_clamd_database(const struct optstruct *opts)
return 0;
}
static int client_scan(const char *file, const char *scantype, int *infected, int *errors, const struct optstruct *opts) {
struct stat sb;
char *fullpath;
DIR *dir;
struct dirent *dent;
int ret, sockd;
/* BUF
basename/thisname/child */
if(stat(file, &sb) == -1) {
logg("^Can't access file %s\n", file);
perror(file);
(*errors)++;
return 0;
}
if(!(fullpath = malloc(PATH_MAX + 1))) {
logg("^Can't make room for fullpath.\n");
(*errors)++;
return 0;
}
if(*file != '/') { /* FIXME: to be unified */
int namelen;
if(!getcwd(fullpath, PATH_MAX)) {
logg("^Can't get absolute pathname of current working directory.\n");
free(fullpath);
(*errors)++;
return 0;
}
namelen = strlen(fullpath);
snprintf(&fullpath[namelen], PATH_MAX - namelen, "/%s", file);
} else {
strncpy(fullpath, file, PATH_MAX);
}
fullpath[PATH_MAX] = '\0';
/* FIXME: i should break out ASAP here for SCAN, continue for MULTISCAN, CONTSCAN */
switch(sb.st_mode & S_IFMT) {
case S_IFDIR:
/* FIXME: if (remote) { */
if(!(dir = opendir(file)))
break;
ret = strlen(fullpath);
while((dent = readdir(dir))) {
if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) continue;
snprintf(&fullpath[ret], PATH_MAX - ret, "/%s", dent->d_name);
fullpath[PATH_MAX] = '\0';
if(client_scan(fullpath, scantype, infected, errors, opts)) {
closedir(dir);
free(fullpath);
return 1;
}
}
closedir(dir);
break;
/* } else fallback to S_IFREG for external recursion */
case S_IFREG:
if((sockd = dconnect(opts, NULL)) < 0)
return 1;
if((ret = dsresult(sockd, scantype, fullpath)) >= 0)
*infected += ret;
else
(*errors)++;
close(sockd);
break;
default:
logg("^Not supported file type (%s)\n", fullpath);
errors++;
}
free(fullpath);
return 0;
}
int client(const struct optstruct *opts, int *infected)
{
char cwd[PATH_MAX+1], *fullpath;
@ -461,6 +536,9 @@ int client(const struct optstruct *opts, int *infected)
if(optget(opts, "multiscan")->enabled)
scantype = "MULTISCAN";
client_scan(opts->filename, scantype, infected, &errors, opts);
return 0; /* FIXME */
/* parse argument list */
if(opts->filename == NULL || strlen(opts->filename) == 0) {

Loading…
Cancel
Save