Convert two macros to functions

pull/6/head
Shawn Webb 11 years ago
parent ddc4afc858
commit ff2d5e61d8
  1. 211
      libclamav/scanners.c

@ -2449,97 +2449,73 @@ static void emax_reached(cli_ctx *ctx) {
return retcode; \
} while(0)
static int magic_scandesc_cleanup(cli_ctx *ctx, cli_file_t type, unsigned char *hash, size_t hashed_size, int cache_clean, int retcode, void *parent_property)
{
#if HAVE_JSON
#define ret_from_magicscan(retcode) \
do { \
cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__); \
ctx->wrkproperty = parent_property; \
if(ctx->engine->cb_post_scan) { \
perf_start(ctx, PERFT_POSTCB); \
switch(ctx->engine->cb_post_scan(fmap_fd(*ctx->fmap), retcode, retcode == CL_VIRUS ? cli_get_last_virus(ctx) : NULL, ctx->cb_ctx)) { \
case CL_BREAK: \
cli_dbgmsg("cli_magic_scandesc: file whitelisted by post_scan callback\n"); \
perf_stop(ctx, PERFT_POSTCB); \
return CL_CLEAN; \
case CL_VIRUS: \
cli_dbgmsg("cli_magic_scandesc: file blacklisted by post_scan callback\n"); \
cli_append_virus(ctx, "Detected.By.Callback"); \
perf_stop(ctx, PERFT_POSTCB); \
if (retcode != CL_VIRUS) \
return cli_checkfp(hash, hashed_size, ctx); \
return CL_VIRUS; \
case CL_CLEAN: \
break; \
default: \
cli_warnmsg("cli_magic_scandesc: ignoring bad return code from post_scan callback\n"); \
} \
perf_stop(ctx, PERFT_POSTCB); \
} \
if (retcode == CL_CLEAN && cache_clean) { \
perf_start(ctx, PERFT_CACHE); \
cache_add(hash, hashed_size, ctx); \
perf_stop(ctx, PERFT_CACHE); \
} \
return retcode; \
} while(0)
#else
#define ret_from_magicscan(retcode) \
do { \
cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__); \
if(ctx->engine->cb_post_scan) { \
perf_start(ctx, PERFT_POSTCB); \
switch(ctx->engine->cb_post_scan(fmap_fd(*ctx->fmap), retcode, retcode == CL_VIRUS ? cli_get_last_virus(ctx) : NULL, ctx->cb_ctx)) { \
case CL_BREAK: \
cli_dbgmsg("cli_magic_scandesc: file whitelisted by post_scan callback\n"); \
perf_stop(ctx, PERFT_POSTCB); \
return CL_CLEAN; \
case CL_VIRUS: \
cli_dbgmsg("cli_magic_scandesc: file blacklisted by post_scan callback\n"); \
cli_append_virus(ctx, "Detected.By.Callback"); \
perf_stop(ctx, PERFT_POSTCB); \
if (retcode != CL_VIRUS) \
return cli_checkfp(hash, hashed_size, ctx); \
return CL_VIRUS; \
case CL_CLEAN: \
break; \
default: \
cli_warnmsg("cli_magic_scandesc: ignoring bad return code from post_scan callback\n"); \
} \
perf_stop(ctx, PERFT_POSTCB); \
} \
if (retcode == CL_CLEAN && cache_clean) { \
perf_start(ctx, PERFT_CACHE); \
cache_add(hash, hashed_size, ctx); \
perf_stop(ctx, PERFT_CACHE); \
} \
return retcode; \
} while(0)
ctx->wrkproperty = (struct json_object *)(parent_property);
#endif
#define CALL_PRESCAN_CB(scanfn) \
if(ctx->engine->scanfn) { \
perf_start(ctx, PERFT_PRECB); \
switch(ctx->engine->scanfn(fmap_fd(*ctx->fmap), filetype, ctx->cb_ctx)) { \
case CL_BREAK: \
cli_dbgmsg("cli_magic_scandesc: file whitelisted by "#scanfn" callback\n"); \
perf_stop(ctx, PERFT_PRECB); \
ctx->hook_lsig_matches = old_hook_lsig_matches; \
ret_from_magicscan(CL_CLEAN); \
case CL_VIRUS: \
cli_dbgmsg("cli_magic_scandesc: file blacklisted by "#scanfn" callback\n"); \
cli_append_virus(ctx, "Detected.By.Callback"); \
perf_stop(ctx, PERFT_PRECB); \
ctx->hook_lsig_matches = old_hook_lsig_matches; \
ret_from_magicscan(cli_checkfp(hash, hashed_size, ctx)); \
case CL_CLEAN: \
break; \
default: \
cli_warnmsg("cli_magic_scandesc: ignoring bad return code from callback\n"); \
} \
perf_stop(ctx, PERFT_PRECB); \
cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__);
if(ctx->engine->cb_post_scan) {
perf_start(ctx, PERFT_POSTCB);
switch(ctx->engine->cb_post_scan(fmap_fd(*ctx->fmap), retcode, retcode == CL_VIRUS ? cli_get_last_virus(ctx) : NULL, ctx->cb_ctx)) {
case CL_BREAK:
cli_dbgmsg("cli_magic_scandesc: file whitelisted by post_scan callback\n");
perf_stop(ctx, PERFT_POSTCB);
return CL_CLEAN;
case CL_VIRUS:
cli_dbgmsg("cli_magic_scandesc: file blacklisted by post_scan callback\n");
cli_append_virus(ctx, "Detected.By.Callback");
perf_stop(ctx, PERFT_POSTCB);
if (retcode != CL_VIRUS)
return cli_checkfp(hash, hashed_size, ctx);
return CL_VIRUS;
case CL_CLEAN:
break;
default:
cli_warnmsg("cli_magic_scandesc: ignoring bad return code from post_scan callback\n");
}
perf_stop(ctx, PERFT_POSTCB);
}
if (retcode == CL_CLEAN && cache_clean) {
perf_start(ctx, PERFT_CACHE);
cache_add(hash, hashed_size, ctx);
perf_stop(ctx, PERFT_CACHE);
}
return retcode;
}
static int dispatch_prescan(clcb_pre_scan cb, cli_ctx *ctx, const char *filetype, bitset_t *old_hook_lsig_matches, void *parent_property, unsigned char *hash, size_t hashed_size, int *run_cleanup)
{
int res=CL_CLEAN;
*run_cleanup = 0;
if(cb) {
perf_start(ctx, PERFT_PRECB);
switch(cb(fmap_fd(*ctx->fmap), filetype, ctx->cb_ctx)) {
case CL_BREAK:
cli_dbgmsg("cli_magic_scandesc: file whitelisted by callback\n");
perf_stop(ctx, PERFT_PRECB);
ctx->hook_lsig_matches = old_hook_lsig_matches;
*run_cleanup = 1;
case CL_VIRUS:
cli_dbgmsg("cli_magic_scandesc: file blacklisted by callback\n");
cli_append_virus(ctx, "Detected.By.Callback");
perf_stop(ctx, PERFT_PRECB);
ctx->hook_lsig_matches = old_hook_lsig_matches;
*run_cleanup = 1;
res = CL_VIRUS;
case CL_CLEAN:
break;
default:
cli_warnmsg("cli_magic_scandesc: ignoring bad return code from callback\n");
}
perf_stop(ctx, PERFT_PRECB);
}
return res;
}
static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
{
@ -2552,8 +2528,11 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
bitset_t *old_hook_lsig_matches;
const char *filetype;
int cache_clean = 0, res;
int run_cleanup = 0;
#if HAVE_JSON
struct json_object *parent_property = NULL;
#else
void *parent_property = NULL;
#endif
if(!ctx->engine) {
@ -2609,7 +2588,8 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
early_ret_from_magicscan(CL_EMEM);
}
ctx->wrkproperty = ctx->properties;
if (ret = cli_jsonstr(ctx->properties, "Magic", "JSON") != CL_SUCCESS) {
ret = cli_jsonstr(ctx->properties, "Magic", "JSON");
if (ret != CL_SUCCESS) {
early_ret_from_magicscan(ret);
}
} else { /* turn off property collection flag for file types we don't care about */
@ -2637,17 +2617,25 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
}
if (ctx->options & CL_SCAN_FILE_PROPERTIES) { /* separated for cases json is not tracked */
if (ret = cli_jsonstr(ctx->wrkproperty, "FileType", filetype) != CL_SUCCESS) {
ret = cli_jsonstr(ctx->wrkproperty, "FileType", filetype);
if (ret != CL_SUCCESS) {
early_ret_from_magicscan(ret);
}
if (ret = cli_jsonint(ctx->wrkproperty, "FileSize", (*ctx->fmap)->len) != CL_SUCCESS) {
ret = cli_jsonint(ctx->wrkproperty, "FileSize", (*ctx->fmap)->len);
if (ret != CL_SUCCESS) {
early_ret_from_magicscan(ret);
}
}
#endif
hashed_size = 0;
CALL_PRESCAN_CB(cb_pre_cache);
ret = dispatch_prescan(ctx->engine->cb_pre_cache, ctx, filetype, old_hook_lsig_matches, parent_property, hash, hashed_size, &run_cleanup);
if (run_cleanup) {
if (ret == CL_VIRUS)
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, cli_checkfp(hash, hashed_size, ctx), parent_property);
else
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, CL_CLEAN, parent_property);
}
perf_start(ctx, PERFT_CACHE);
res = cache_check(hash, ctx);
@ -2657,7 +2645,8 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
char hashstr[33];
snprintf(hashstr, 33, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", hash[0], hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7], hash[8], hash[9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15]);
if (ret = cli_jsonstr(ctx->wrkproperty, "FileMD5", hashstr) != CL_SUCCESS) {
ret = cli_jsonstr(ctx->wrkproperty, "FileMD5", hashstr);
if (ret != CL_SUCCESS) {
early_ret_from_magicscan(ret);
}
}
@ -2681,7 +2670,13 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
else
cli_dbgmsg("Raw mode: No support for special files\n");
CALL_PRESCAN_CB(cb_pre_scan);
ret = dispatch_prescan(ctx->engine->cb_pre_scan, ctx, filetype, old_hook_lsig_matches, parent_property, hash, hashed_size, &run_cleanup);
if (run_cleanup) {
if (ret == CL_VIRUS)
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, cli_checkfp(hash, hashed_size, ctx), parent_property);
else
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property);
}
/* ret_from_magicscan can be used below here*/
if((ret = cli_fmap_scandesc(ctx, 0, 0, NULL, AC_SCAN_VIR, NULL, hash)) == CL_VIRUS)
cli_dbgmsg("%s found in descriptor %d\n", cli_get_last_virus(ctx), fmap_fd(*ctx->fmap));
@ -2693,10 +2688,16 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
}
ctx->hook_lsig_matches = old_hook_lsig_matches;
ret_from_magicscan(ret);
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property);
}
CALL_PRESCAN_CB(cb_pre_scan);
ret = dispatch_prescan(ctx->engine->cb_pre_scan, ctx, filetype, old_hook_lsig_matches, parent_property, hash, hashed_size, &run_cleanup);
if (run_cleanup) {
if (ret == CL_VIRUS)
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, cli_checkfp(hash, hashed_size, ctx), parent_property);
else
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property);
}
/* ret_from_magicscan can be used below here*/
#ifdef HAVE__INTERNAL__SHA_COLLECT
@ -2706,7 +2707,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
ctx->hook_lsig_matches = cli_bitset_init();
if (!ctx->hook_lsig_matches) {
ctx->hook_lsig_matches = old_hook_lsig_matches;
ret_from_magicscan(CL_EMEM);
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, CL_EMEM, parent_property);
}
if(type != CL_TYPE_IGNORED && ctx->engine->sdb) {
@ -2714,7 +2715,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
ret = cli_checkfp(hash, hashed_size, ctx);
cli_bitset_free(ctx->hook_lsig_matches);
ctx->hook_lsig_matches = old_hook_lsig_matches;
ret_from_magicscan(ret);
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property);
}
}
@ -3012,7 +3013,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
ret = cli_checkfp(hash, hashed_size, ctx);
cli_bitset_free(ctx->hook_lsig_matches);
ctx->hook_lsig_matches = old_hook_lsig_matches;
ret_from_magicscan(ret);
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property);
}
if(type == CL_TYPE_ZIP && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP)) {
@ -3042,7 +3043,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
cli_dbgmsg("Descriptor[%d]: cli_scanraw error %s\n", fmap_fd(*ctx->fmap), cl_strerror(res));
cli_bitset_free(ctx->hook_lsig_matches);
ctx->hook_lsig_matches = old_hook_lsig_matches;
ret_from_magicscan(res);
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property);
/* CL_VIRUS = malware found, check FP and report */
case CL_VIRUS:
ret = cli_checkfp(hash, hashed_size, ctx);
@ -3050,7 +3051,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
break;
cli_bitset_free(ctx->hook_lsig_matches);
ctx->hook_lsig_matches = old_hook_lsig_matches;
ret_from_magicscan(ret);
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property);
/* "MAX" conditions should still fully scan the current file */
case CL_EMAXREC:
case CL_EMAXSIZE:
@ -3119,12 +3120,18 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
case CL_EMAXSIZE:
case CL_EMAXFILES:
cli_dbgmsg("Descriptor[%d]: %s\n", fmap_fd(*ctx->fmap), cl_strerror(ret));
ret_from_magicscan(CL_CLEAN);
#if HAVE_JSON
ctx->wrkproperty = parent_property;
#endif
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, CL_CLEAN, parent_property);
case CL_CLEAN:
cache_clean = 1;
ret_from_magicscan(CL_CLEAN);
#if HAVE_JSON
ctx->wrkproperty = parent_property;
#endif
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, CL_CLEAN, parent_property);
default:
ret_from_magicscan(ret);
return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property);
}
}

Loading…
Cancel
Save