clamdscan: fix error logic once again

0.96
Tomasz Kojm 16 years ago
parent 0678c04bf5
commit dd5092ff73
  1. 4
      ChangeLog
  2. 8
      clamdscan/clamdscan.c
  3. 22
      clamdscan/client.c
  4. 2
      clamdscan/client.h
  5. 32
      clamdscan/proto.c
  6. 6
      clamdscan/proto.h

@ -1,3 +1,7 @@
Wed Feb 3 18:23:08 CET 2010 (tk)
---------------------------------
* clamdscan: fix error logic once again
Wed Feb 3 01:38:50 CET 2010 (acab)
-----------------------------------
* win32: workaround HUP reset in poll, set stdin to binary mode

@ -55,7 +55,7 @@ static void print_server_version(const struct optstruct *opt)
int main(int argc, char **argv)
{
int ds, dms, ret, infected = 0;
int ds, dms, ret, infected = 0, err = 0;
struct timeval t1, t2;
time_t starttime;
struct optstruct *opts;
@ -133,10 +133,10 @@ int main(int argc, char **argv)
gettimeofday(&t1, NULL);
ret = client(opts, &infected);
ret = client(opts, &infected, &err);
/* TODO: Implement STATUS in clamd */
if((infected || ret != 2) && !optget(opts, "no-summary")->enabled) {
if(!optget(opts, "no-summary")->enabled) {
gettimeofday(&t2, NULL);
ds = t2.tv_sec - t1.tv_sec;
dms = t2.tv_usec - t1.tv_usec;
@ -144,6 +144,8 @@ int main(int argc, char **argv)
dms += (dms < 0) ? (1000000):(0);
logg("\n----------- SCAN SUMMARY -----------\n");
logg("Infected files: %d\n", infected);
if(err)
logg("Errors: %d\n", err);
if(notremoved) {
logg("Not removed: %d\n", notremoved);
}

@ -151,16 +151,16 @@ static char *makeabs(const char *basepath) {
/* Recursively scans a path with the given scantype
* Returns non zero for serious errors, zero otherwise */
static int client_scan(const char *file, int scantype, int *infected, int maxlevel, int session, int flags) {
static int client_scan(const char *file, int scantype, int *infected, int *err, int maxlevel, int session, int flags) {
int ret;
char *fullpath = makeabs(file);
if(!fullpath)
return 0;
if (!session)
ret = serial_client_scan(fullpath, scantype, infected, maxlevel, flags);
ret = serial_client_scan(fullpath, scantype, infected, err, maxlevel, flags);
else
ret = parallel_client_scan(fullpath, scantype, infected, maxlevel, flags);
ret = parallel_client_scan(fullpath, scantype, infected, err, maxlevel, flags);
free(fullpath);
return ret;
}
@ -218,7 +218,7 @@ int reload_clamd_database(const struct optstruct *opts)
return 0;
}
int client(const struct optstruct *opts, int *infected)
int client(const struct optstruct *opts, int *infected, int *err)
{
const char *clamd_conf = optget(opts, "config-file")->strarg;
struct optstruct *clamdopts;
@ -265,7 +265,7 @@ int client(const struct optstruct *opts, int *infected)
struct stat sb;
fstat(0, &sb);
if((sb.st_mode & S_IFMT) != S_IFREG) scantype = STREAM;
if((sockd = dconnect()) >= 0 && (ret = dsresult(sockd, scantype, NULL, &ret, NULL, NULL)) >= 0)
if((sockd = dconnect()) >= 0 && (ret = dsresult(sockd, scantype, NULL, &ret, NULL)) >= 0)
*infected = ret;
else
errors = 1;
@ -274,15 +274,21 @@ int client(const struct optstruct *opts, int *infected)
if(opts->filename && optget(opts, "file-list")->enabled)
logg("^Only scanning files from --file-list (files passed at cmdline are ignored)\n");
while(!errors && (fname = filelist(opts, NULL))) {
while((fname = filelist(opts, NULL))) {
if(!strcmp(fname, "-")) {
logg("!Scanning from standard input requires \"-\" to be the only file argument\n");
continue;
}
errors = client_scan(fname, scantype, infected, maxrec, session, flags);
errors += client_scan(fname, scantype, infected, err, maxrec, session, flags);
/* this may be too strict
if(errors >= 10) {
logg("!Too many errors\n");
break;
}
*/
}
} else {
errors = client_scan("", scantype, infected, maxrec, session, flags);
errors = client_scan("", scantype, infected, err, maxrec, session, flags);
}
return *infected ? 1 : (errors ? 2 : 0);
}

@ -30,7 +30,7 @@ enum {
FILDES
};
int client(const struct optstruct *opts, int *infected);
int client(const struct optstruct *opts, int *infected, int *err);
int get_clamd_version(const struct optstruct *opts);
int reload_clamd_database(const struct optstruct *opts);

@ -247,7 +247,7 @@ static int send_fdpass(int sockd, const char *filename) {
/* Sends a proper scan request to clamd and parses its replies
* This is used only in non IDSESSION mode
* Returns the number of infected files or -1 on error */
int dsresult(int sockd, int scantype, const char *filename, int *printok, int *files, int *errors) {
int dsresult(int sockd, int scantype, const char *filename, int *printok, int *errors) {
int infected = 0, len, beenthere = 0;
char *bol, *eol;
struct RCVLN rcv;
@ -288,8 +288,6 @@ int dsresult(int sockd, int scantype, const char *filename, int *printok, int *f
while((len = recvln(&rcv, &bol, &eol))) {
if(len == -1) return -1;
beenthere = 1;
if(files)
(*files)++;
if(!filename) logg("~%s\n", bol);
if(len > 7) {
char *colon = strrchr(bol, ':');
@ -351,9 +349,11 @@ static int serial_callback(struct stat *sb, char *filename, const char *path, en
int sockd, ret;
const char *f = filename;
c->files++;
switch(reason) {
case error_stat:
logg("!Can't access file %s\n", path);
c->errors++;
return CL_SUCCESS;
case error_mem:
logg("!Memory allocation failed in ftw\n");
@ -378,12 +378,16 @@ static int serial_callback(struct stat *sb, char *filename, const char *path, en
if((sockd = dconnect()) < 0) {
if(filename) free(filename);
c->errors++;
return CL_EOPEN;
}
ret = dsresult(sockd, c->scantype, f, &c->printok, &c->files, &c->errors);
ret = dsresult(sockd, c->scantype, f, &c->printok, &c->errors);
if(filename) free(filename);
closesocket(sockd);
if(ret < 0) return CL_EOPEN;
if(ret < 0) {
c->errors++;
return CL_EOPEN;
}
c->infected += ret;
if(reason == visit_directory_toplev)
return CL_BREAK;
@ -392,7 +396,7 @@ static int serial_callback(struct stat *sb, char *filename, const char *path, en
/* Non-IDSESSION handler
* Returns non zero for serious errors, zero otherwise */
int serial_client_scan(char *file, int scantype, int *infected, int maxlevel, int flags) {
int serial_client_scan(char *file, int scantype, int *infected, int *err, int maxlevel, int flags) {
struct cli_ftw_cbdata data;
struct client_serial_data cdata;
int ftw;
@ -406,8 +410,9 @@ int serial_client_scan(char *file, int scantype, int *infected, int maxlevel, in
ftw = cli_ftw(file, flags, maxlevel ? maxlevel : INT_MAX, serial_callback, &data, NULL);
*infected += cdata.infected;
*err += cdata.errors;
if((cdata.errors < cdata.files) && (ftw == CL_SUCCESS || ftw == CL_BREAK)) {
if(!cdata.errors && (ftw == CL_SUCCESS || ftw == CL_BREAK)) {
if(cdata.printok)
logg("~%s: OK\n", file);
return 0;
@ -496,9 +501,11 @@ static int parallel_callback(struct stat *sb, char *filename, const char *path,
struct SCANID *cid;
int res;
c->files++;
switch(reason) {
case error_stat:
logg("!Can't access file %s\n", path);
c->errors++;
return CL_SUCCESS;
case error_mem:
logg("!Memory allocation failed in ftw\n");
@ -551,7 +558,6 @@ static int parallel_callback(struct stat *sb, char *filename, const char *path,
cid->file = filename;
cid->next = c->ids;
c->ids = cid;
c->files++;
switch(c->scantype) {
#ifdef HAVE_FD_PASSING
@ -577,7 +583,7 @@ static int parallel_callback(struct stat *sb, char *filename, const char *path,
/* IDSESSION handler
* Returns non zero for serious errors, zero otherwise */
int parallel_client_scan(char *file, int scantype, int *infected, int maxlevel, int flags) {
int parallel_client_scan(char *file, int scantype, int *infected, int *err, int maxlevel, int flags) {
struct cli_ftw_cbdata data;
struct client_parallel_data cdata;
int ftw;
@ -602,6 +608,7 @@ int parallel_client_scan(char *file, int scantype, int *infected, int maxlevel,
ftw = cli_ftw(file, flags, maxlevel ? maxlevel : INT_MAX, parallel_callback, &data, NULL);
if(ftw != CL_SUCCESS) {
*err += cdata.errors;
*infected += cdata.infected;
closesocket(cdata.sockd);
return 1;
@ -612,15 +619,18 @@ int parallel_client_scan(char *file, int scantype, int *infected, int maxlevel,
closesocket(cdata.sockd);
*infected += cdata.infected;
*err += cdata.errors;
if(cdata.ids) {
logg("!Clamd closed the connection before scanning all files.\n");
return 1;
}
if(cdata.errors)
return 1;
if(!cdata.files)
return 0;
if(cdata.errors == cdata.files)
return 1;
if(cdata.printok)
logg("~%s: OK\n", file);
return 0;

@ -34,7 +34,7 @@ int dconnect(void);
int sendln(int sockd, const char *line, unsigned int len);
void recvlninit(struct RCVLN *s, int sockd);
int recvln(struct RCVLN *s, char **rbol, char **reol);
int serial_client_scan(char *file, int scantype, int *infected, int maxlevel, int flags);
int parallel_client_scan(char *file, int scantype, int *infected, int maxlevel, int flags);
int dsresult(int sockd, int scantype, const char *filename, int *printok, int *files, int *errors);
int serial_client_scan(char *file, int scantype, int *infected, int *err, int maxlevel, int flags);
int parallel_client_scan(char *file, int scantype, int *infected, int *err, int maxlevel, int flags);
int dsresult(int sockd, int scantype, const char *filename, int *printok, int *errors);
#endif

Loading…
Cancel
Save