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) Wed Feb 3 01:38:50 CET 2010 (acab)
----------------------------------- -----------------------------------
* win32: workaround HUP reset in poll, set stdin to binary mode * 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 main(int argc, char **argv)
{ {
int ds, dms, ret, infected = 0; int ds, dms, ret, infected = 0, err = 0;
struct timeval t1, t2; struct timeval t1, t2;
time_t starttime; time_t starttime;
struct optstruct *opts; struct optstruct *opts;
@ -133,10 +133,10 @@ int main(int argc, char **argv)
gettimeofday(&t1, NULL); gettimeofday(&t1, NULL);
ret = client(opts, &infected); ret = client(opts, &infected, &err);
/* TODO: Implement STATUS in clamd */ /* TODO: Implement STATUS in clamd */
if((infected || ret != 2) && !optget(opts, "no-summary")->enabled) { if(!optget(opts, "no-summary")->enabled) {
gettimeofday(&t2, NULL); gettimeofday(&t2, NULL);
ds = t2.tv_sec - t1.tv_sec; ds = t2.tv_sec - t1.tv_sec;
dms = t2.tv_usec - t1.tv_usec; dms = t2.tv_usec - t1.tv_usec;
@ -144,6 +144,8 @@ int main(int argc, char **argv)
dms += (dms < 0) ? (1000000):(0); dms += (dms < 0) ? (1000000):(0);
logg("\n----------- SCAN SUMMARY -----------\n"); logg("\n----------- SCAN SUMMARY -----------\n");
logg("Infected files: %d\n", infected); logg("Infected files: %d\n", infected);
if(err)
logg("Errors: %d\n", err);
if(notremoved) { if(notremoved) {
logg("Not removed: %d\n", 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 /* Recursively scans a path with the given scantype
* Returns non zero for serious errors, zero otherwise */ * 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; int ret;
char *fullpath = makeabs(file); char *fullpath = makeabs(file);
if(!fullpath) if(!fullpath)
return 0; return 0;
if (!session) if (!session)
ret = serial_client_scan(fullpath, scantype, infected, maxlevel, flags); ret = serial_client_scan(fullpath, scantype, infected, err, maxlevel, flags);
else else
ret = parallel_client_scan(fullpath, scantype, infected, maxlevel, flags); ret = parallel_client_scan(fullpath, scantype, infected, err, maxlevel, flags);
free(fullpath); free(fullpath);
return ret; return ret;
} }
@ -218,7 +218,7 @@ int reload_clamd_database(const struct optstruct *opts)
return 0; 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; const char *clamd_conf = optget(opts, "config-file")->strarg;
struct optstruct *clamdopts; struct optstruct *clamdopts;
@ -265,7 +265,7 @@ int client(const struct optstruct *opts, int *infected)
struct stat sb; struct stat sb;
fstat(0, &sb); fstat(0, &sb);
if((sb.st_mode & S_IFMT) != S_IFREG) scantype = STREAM; 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; *infected = ret;
else else
errors = 1; errors = 1;
@ -274,15 +274,21 @@ int client(const struct optstruct *opts, int *infected)
if(opts->filename && optget(opts, "file-list")->enabled) if(opts->filename && optget(opts, "file-list")->enabled)
logg("^Only scanning files from --file-list (files passed at cmdline are ignored)\n"); 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, "-")) { if(!strcmp(fname, "-")) {
logg("!Scanning from standard input requires \"-\" to be the only file argument\n"); logg("!Scanning from standard input requires \"-\" to be the only file argument\n");
continue; 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 { } else {
errors = client_scan("", scantype, infected, maxrec, session, flags); errors = client_scan("", scantype, infected, err, maxrec, session, flags);
} }
return *infected ? 1 : (errors ? 2 : 0); return *infected ? 1 : (errors ? 2 : 0);
} }

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

@ -34,7 +34,7 @@ int dconnect(void);
int sendln(int sockd, const char *line, unsigned int len); int sendln(int sockd, const char *line, unsigned int len);
void recvlninit(struct RCVLN *s, int sockd); void recvlninit(struct RCVLN *s, int sockd);
int recvln(struct RCVLN *s, char **rbol, char **reol); int recvln(struct RCVLN *s, char **rbol, char **reol);
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);
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);
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);
#endif #endif

Loading…
Cancel
Save