~ubuntu-branches/ubuntu/saucy/clamav/saucy-backports

« back to all changes in this revision

Viewing changes to libclamav/stats.c

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman
  • Date: 2014-07-15 01:08:10 UTC
  • mfrom: (0.35.47 sid)
  • Revision ID: package-import@ubuntu.com-20140715010810-ru66ek4fun2iseba
Tags: 0.98.4+dfsg-2~ubuntu13.10.1
No-change backport to saucy (LP: #1341962)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
 
3
 *
 
4
 *  Author: Shawn Webb
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License version 2 as
 
8
 *  published by the Free Software Foundation.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
18
 *  MA 02110-1301, USA.
 
19
 */
 
20
 
 
21
#if HAVE_CONFIG_H
 
22
#include "clamav-config.h"
 
23
#endif
 
24
 
 
25
#include <stdio.h>
 
26
#include <stdlib.h>
 
27
#include <string.h>
 
28
#if HAVE_UNISTD_H
 
29
#include <unistd.h>
 
30
#endif
 
31
 
 
32
#include <sys/types.h>
 
33
#if !defined(_WIN32)
 
34
#if defined(C_SOLARIS)
 
35
#include <sys/utsname.h>
 
36
#else
 
37
#if HAVE_SYS_PARAM_H
 
38
#include <sys/param.h>
 
39
#endif
 
40
#if HAVE_SYSCTLBYNAME
 
41
#include <sys/sysctl.h>
 
42
#endif
 
43
#endif
 
44
#include <dlfcn.h>
 
45
#else
 
46
#include <Windows.h>
 
47
#include <tchar.h>
 
48
#endif
 
49
 
 
50
#ifdef CL_THREAD_SAFE
 
51
#include <pthread.h>
 
52
#endif
 
53
 
 
54
#include <errno.h>
 
55
 
 
56
#include <openssl/ssl.h>
 
57
#include <openssl/err.h>
 
58
#include "libclamav/crypto.h"
 
59
 
 
60
#include "libclamav/others.h"
 
61
#include "libclamav/clamav.h"
 
62
#include "libclamav/dconf.h"
 
63
#include "libclamav/json.h"
 
64
#include "libclamav/stats.h"
 
65
#include "libclamav/hostid.h"
 
66
#include "libclamav/www.h"
 
67
 
 
68
#define DEBUG_STATS 0
 
69
 
 
70
static cli_flagged_sample_t *find_sample(cli_intel_t *intel, const char *virname, const unsigned char *md5, size_t size, stats_section_t *sections);
 
71
void free_sample(cli_flagged_sample_t *sample);
 
72
 
 
73
#if DEBUG_STATS
 
74
char *get_hash(unsigned char *md5)
 
75
{
 
76
    char *hash;
 
77
    int i;
 
78
 
 
79
    hash = calloc(1, 33);
 
80
    if (!(hash))
 
81
        return NULL;
 
82
 
 
83
    for (i=0; i<16; i++)
 
84
        sprintf(hash+(i*2), "%02x", md5[i]);
 
85
 
 
86
    return hash;
 
87
}
 
88
 
 
89
char *get_sample_names(char **names)
 
90
{
 
91
    char *ret;
 
92
    size_t n, i, sz;
 
93
 
 
94
    sz = 0;
 
95
    for (n=0; names[n] != NULL; n++)
 
96
        sz += strlen(names[n]);
 
97
 
 
98
    ret = calloc(1, sz + n + 1);
 
99
    if (!(ret))
 
100
        return NULL;
 
101
 
 
102
    for (i=0; names[i] != NULL; i++)
 
103
        sprintf(ret+strlen(ret), "%s%s", (i==0) ? "" : " ", names[i]);
 
104
 
 
105
    return ret;
 
106
}
 
107
 
 
108
void print_sample(cli_flagged_sample_t *sample)
 
109
{
 
110
    char *hash, *names;
 
111
    size_t i;
 
112
 
 
113
    if (!(sample))
 
114
        return;
 
115
 
 
116
    hash = get_hash(sample->md5);
 
117
    if (!(hash))
 
118
        return;
 
119
 
 
120
    cli_warnmsg("Sample[%s]:\n", hash);
 
121
    cli_warnmsg("    * Size: %zu\n", sample->size);
 
122
    cli_warnmsg("    * Hits: %u\n", sample->hits);
 
123
 
 
124
    free(hash);
 
125
 
 
126
    names = get_sample_names(sample->virus_name);
 
127
    if ((names))
 
128
        cli_warnmsg("    * Names: %s\n", names);
 
129
 
 
130
    if (sample->sections && sample->sections->nsections) {
 
131
        for (i=0; i < sample->sections->nsections; i++) {
 
132
            hash = get_hash(sample->sections->sections[i].md5);
 
133
            if ((hash)) {
 
134
                cli_warnmsg("    * Section[%zu] (%zu): %s\n", i, sample->sections->sections[i].len, hash);
 
135
                free(hash);
 
136
            }
 
137
        }
 
138
    }
 
139
 
 
140
    if ((names))
 
141
        free(names);
 
142
}
 
143
#endif
 
144
 
 
145
void clamav_stats_add_sample(const char *virname, const unsigned char *md5, size_t size, stats_section_t *sections, void *cbdata)
 
146
{
 
147
    cli_intel_t *intel;
 
148
    cli_flagged_sample_t *sample;
 
149
    size_t i;
 
150
    char **p;
 
151
    int err, submit=0;
 
152
 
 
153
    if (!(cbdata))
 
154
        return;
 
155
 
 
156
    intel = (cli_intel_t *)cbdata;
 
157
    if (!(intel->engine))
 
158
        return;
 
159
 
 
160
    if (intel->engine->dconf->stats & DCONF_STATS_DISABLED)
 
161
        return;
 
162
 
 
163
    /* First check if we need to submit stats based on memory/number limits */
 
164
    if ((intel->engine->cb_stats_get_size))
 
165
        submit = (intel->engine->cb_stats_get_size(cbdata) >= intel->maxmem);
 
166
    else
 
167
        submit = (clamav_stats_get_size(cbdata) >= intel->maxmem);
 
168
 
 
169
    if (submit == 0) {
 
170
        if ((intel->engine->cb_stats_get_num))
 
171
            submit = (intel->engine->cb_stats_get_num(cbdata) >= intel->maxsamples);
 
172
        else
 
173
            submit = (clamav_stats_get_num(cbdata) >= intel->maxsamples);
 
174
    }
 
175
 
 
176
    if (submit) {
 
177
        if ((intel->engine->cb_stats_submit)) {
 
178
            intel->engine->cb_stats_submit(intel->engine, cbdata);
 
179
        } else {
 
180
            if ((intel->engine->cb_stats_flush))
 
181
                intel->engine->cb_stats_flush(intel->engine, intel);
 
182
 
 
183
            return;
 
184
        }
 
185
    }
 
186
 
 
187
#ifdef CL_THREAD_SAFE
 
188
    err = pthread_mutex_lock(&(intel->mutex));
 
189
    if (err) {
 
190
        cli_warnmsg("clamav_stats_add_sample: locking mutex failed (err: %d): %s\n", err, strerror(err));
 
191
        return;
 
192
    }
 
193
#endif
 
194
 
 
195
    sample = find_sample(intel, virname, md5, size, sections);
 
196
    if (!(sample)) {
 
197
        if (!(intel->samples)) {
 
198
            sample = intel->samples = calloc(1, sizeof(cli_flagged_sample_t));
 
199
            if (!(sample))
 
200
                goto end;
 
201
        } else {
 
202
            sample = calloc(1, sizeof(cli_flagged_sample_t));
 
203
            if (!(sample))
 
204
                goto end;
 
205
 
 
206
            sample->next = intel->samples;
 
207
            intel->samples->prev = sample;
 
208
            intel->samples = sample;
 
209
        }
 
210
 
 
211
        if ((sample->virus_name)) {
 
212
            for (i=0; sample->virus_name[i] != NULL; i++)
 
213
                ;
 
214
            p = realloc(sample->virus_name, sizeof(char **) * (i + 1));
 
215
            if (!(p)) {
 
216
                free(sample->virus_name);
 
217
                free(sample);
 
218
                if (sample == intel->samples)
 
219
                    intel->samples = NULL;
 
220
 
 
221
                goto end;
 
222
            }
 
223
 
 
224
            sample->virus_name = p;
 
225
        } else {
 
226
            i=0;
 
227
            sample->virus_name = calloc(1, sizeof(char **));
 
228
            if (!(sample->virus_name)) {
 
229
                free(sample);
 
230
                if (sample == intel->samples)
 
231
                    intel->samples = NULL;
 
232
 
 
233
                goto end;
 
234
            }
 
235
        }
 
236
 
 
237
        sample->virus_name[i] = strdup((virname != NULL) ? virname : "[unknown]");
 
238
        if (!(sample->virus_name[i])) {
 
239
            free(sample->virus_name);
 
240
            free(sample);
 
241
            if (sample == intel->samples)
 
242
                intel->samples = NULL;
 
243
 
 
244
            goto end;
 
245
        }
 
246
 
 
247
        p = realloc(sample->virus_name, sizeof(char **) * (i+2));
 
248
        if (!(p)) {
 
249
            free(sample->virus_name);
 
250
            free(sample);
 
251
            if (sample == intel->samples)
 
252
                intel->samples = NULL;
 
253
 
 
254
            goto end;
 
255
        }
 
256
 
 
257
        sample->virus_name = p;
 
258
        sample->virus_name[i+1] = NULL;
 
259
 
 
260
        memcpy(sample->md5, md5, sizeof(sample->md5));
 
261
        sample->size = (uint32_t)size;
 
262
        intel->nsamples++;
 
263
 
 
264
        if (sections && sections->nsections && !(sample->sections)) {
 
265
            /* Copy the section data that has already been allocated. We don't care if calloc fails; just skip copying if it does. */
 
266
            sample->sections = calloc(1, sizeof(stats_section_t));
 
267
            if ((sample->sections)) {
 
268
                sample->sections->sections = calloc(sections->nsections, sizeof(struct cli_section_hash));
 
269
                if ((sample->sections->sections)) {
 
270
                    memcpy(sample->sections->sections, sections->sections, sections->nsections * sizeof(struct cli_section_hash));
 
271
                    sample->sections->nsections = sections->nsections;
 
272
                } else {
 
273
                    free(sample->sections);
 
274
                    sample->sections = NULL;
 
275
                }
 
276
            }
 
277
        }
 
278
    }
 
279
 
 
280
    sample->hits++;
 
281
 
 
282
end:
 
283
#ifdef CL_THREAD_SAFE
 
284
    err = pthread_mutex_unlock(&(intel->mutex));
 
285
    if (err) {
 
286
        cli_warnmsg("clamav_stats_add_sample: unlcoking mutex failed (err: %d): %s\n", err, strerror(err));
 
287
    }
 
288
#endif
 
289
}
 
290
 
 
291
void clamav_stats_flush(struct cl_engine *engine, void *cbdata)
 
292
{
 
293
    cli_intel_t *intel;
 
294
    cli_flagged_sample_t *sample, *next;
 
295
    int err;
 
296
 
 
297
    if (!(cbdata) || !(engine))
 
298
        return;
 
299
 
 
300
    intel = (cli_intel_t *)cbdata;
 
301
 
 
302
#ifdef CL_THREAD_SAFE
 
303
    err = pthread_mutex_lock(&(intel->mutex));
 
304
    if (err) {
 
305
        cli_warnmsg("clamav_stats_flush: locking mutex failed (err: %d): %s\n", err, strerror(err));
 
306
        return;
 
307
    }
 
308
#endif
 
309
 
 
310
    for (sample=intel->samples; sample != NULL; sample = next) {
 
311
        next = sample->next;
 
312
 
 
313
        free_sample(sample);
 
314
    }
 
315
 
 
316
    intel->samples = NULL;
 
317
    intel->nsamples = 0;
 
318
    if (intel->hostid) {
 
319
        free(intel->hostid);
 
320
        intel->hostid = NULL;
 
321
    }
 
322
 
 
323
#ifdef CL_THREAD_SAFE
 
324
    err = pthread_mutex_unlock(&(intel->mutex));
 
325
    if (err)
 
326
        cli_warnmsg("clamav_stats_flush: unlocking mutex failed (err: %d): %s\n", err, strerror(err));
 
327
#endif
 
328
}
 
329
 
 
330
void free_sample(cli_flagged_sample_t *sample)
 
331
{
 
332
    size_t i;
 
333
 
 
334
    if ((sample->virus_name)) {
 
335
        for (i=0; sample->virus_name[i] != NULL; i++)
 
336
            free(sample->virus_name[i]);
 
337
 
 
338
        free(sample->virus_name);
 
339
    }
 
340
 
 
341
    if ((sample->sections) && (sample->sections->nsections)) {
 
342
        free(sample->sections->sections);
 
343
        free(sample->sections);
 
344
    }
 
345
 
 
346
    free(sample);
 
347
}
 
348
 
 
349
void clamav_stats_submit(struct cl_engine *engine, void *cbdata)
 
350
{
 
351
    char *json;
 
352
    cli_intel_t *intel, myintel;
 
353
    cli_flagged_sample_t *sample, *next;
 
354
    int err;
 
355
 
 
356
    intel = (cli_intel_t *)cbdata;
 
357
    if (!(intel) || !(engine))
 
358
        return;
 
359
 
 
360
    if (engine->dconf->stats & DCONF_STATS_DISABLED)
 
361
        return;
 
362
 
 
363
    if (!(engine->cb_stats_get_hostid)) {
 
364
        /* Submitting stats is disabled due to HostID being turned off */
 
365
        if ((engine->cb_stats_flush))
 
366
            engine->cb_stats_flush(engine, cbdata);
 
367
 
 
368
        return;
 
369
    }
 
370
 
 
371
    cli_dbgmsg("stats - start\n");
 
372
 
 
373
#ifdef CL_THREAD_SAFE
 
374
    err = pthread_mutex_lock(&(intel->mutex));
 
375
    if (err) {
 
376
        cli_warnmsg("clamav_stats_submit: locking mutex failed (err: %d): %s\n", err, strerror(err));
 
377
 
 
378
        if ((intel->engine) && (intel->engine->cb_stats_flush))
 
379
            intel->engine->cb_stats_flush(intel->engine, cbdata);
 
380
 
 
381
        return;
 
382
    }
 
383
#endif
 
384
 
 
385
    /* Empty out the cached intelligence data so that other threads don't sit waiting to add data to the cache */
 
386
    memcpy(&myintel, intel, sizeof(cli_intel_t));
 
387
    intel->samples = NULL;
 
388
    intel->nsamples = 0;
 
389
 
 
390
    json = export_stats_to_json(engine, &myintel);
 
391
 
 
392
#ifdef CL_THREAD_SAFE
 
393
    err = pthread_mutex_unlock(&(intel->mutex));
 
394
    if (err) {
 
395
        cli_warnmsg("clamav_stats_submit: unlocking mutex failed (err: %d): %s\n", err, strerror(err));
 
396
    }
 
397
#endif
 
398
 
 
399
    for (sample=myintel.samples; sample != NULL; sample = next) {
 
400
#if DEBUG_STATS
 
401
        print_sample(sample);
 
402
#endif
 
403
        next = sample->next;
 
404
 
 
405
        free_sample(sample);
 
406
    }
 
407
 
 
408
    if (json) {
 
409
        submit_post(STATS_HOST, STATS_PORT, "PUT", "/clamav/1/submit/stats", json, myintel.timeout);
 
410
        free(json);
 
411
    }
 
412
 
 
413
    if (myintel.hostid && !(intel->hostid)) {
 
414
        free(myintel.hostid);
 
415
        myintel.hostid = NULL;
 
416
    }
 
417
 
 
418
    cli_dbgmsg("stats - end\n");
 
419
}
 
420
 
 
421
void clamav_stats_remove_sample(const char *virname, const unsigned char *md5, size_t size, void *cbdata)
 
422
{
 
423
    cli_intel_t *intel;
 
424
    cli_flagged_sample_t *sample;
 
425
    int err;
 
426
 
 
427
    intel = (cli_intel_t *)cbdata;
 
428
    if (!(intel))
 
429
        return;
 
430
 
 
431
#ifdef CL_THREAD_SAFE
 
432
    err = pthread_mutex_lock(&(intel->mutex));
 
433
    if (err) {
 
434
        cli_warnmsg("clamav_stats_remove_sample: locking mutex failed (err: %d): %s\n", err, strerror(err));
 
435
        return;
 
436
    }
 
437
#endif
 
438
 
 
439
    while ((sample = find_sample(intel, virname, md5, size, NULL))) {
 
440
        if (sample->prev)
 
441
            sample->prev->next = sample->next;
 
442
        if (sample->next)
 
443
            sample->next->prev = sample->prev;
 
444
        if (sample == intel->samples)
 
445
            intel->samples = sample->next;
 
446
 
 
447
        free_sample(sample);
 
448
        intel->nsamples--;
 
449
    }
 
450
 
 
451
#ifdef CL_THREAD_SAFE
 
452
    err = pthread_mutex_unlock(&(intel->mutex));
 
453
    if (err) {
 
454
        cli_warnmsg("clamav_stats_remove_sample: unlocking mutex failed (err: %d): %s\n", err, strerror(err));
 
455
    }
 
456
#endif
 
457
}
 
458
 
 
459
void clamav_stats_decrement_count(const char *virname, const unsigned char *md5, size_t size, void *cbdata)
 
460
{
 
461
    cli_intel_t *intel;
 
462
    cli_flagged_sample_t *sample;
 
463
    int err;
 
464
 
 
465
    intel = (cli_intel_t *)cbdata;
 
466
    if (!(intel))
 
467
        return;
 
468
 
 
469
#ifdef CL_THREAD_SAFE
 
470
    err = pthread_mutex_lock(&(intel->mutex));
 
471
    if (err) {
 
472
        cli_warnmsg("clamav_stats_decrement_count: locking mutex failed (err: %d): %s\n", err, strerror(err));
 
473
        return;
 
474
    }
 
475
#endif
 
476
 
 
477
    sample = find_sample(intel, virname, md5, size, NULL);
 
478
    if (!(sample))
 
479
        goto clamav_stats_decrement_end;
 
480
 
 
481
    if (sample->hits == 1) {
 
482
        if ((intel->engine->cb_stats_remove_sample))
 
483
            intel->engine->cb_stats_remove_sample(virname, md5, size, intel);
 
484
        else
 
485
            clamav_stats_remove_sample(virname, md5, size, intel);
 
486
 
 
487
        goto clamav_stats_decrement_end;
 
488
    }
 
489
 
 
490
    sample->hits--;
 
491
 
 
492
 clamav_stats_decrement_end:
 
493
#ifdef CL_THREAD_SAFE
 
494
    err = pthread_mutex_unlock(&(intel->mutex));
 
495
    if (err) {
 
496
        cli_warnmsg("clamav_stats_decrement_count: unlocking mutex failed (err: %d): %s\n", err, strerror(err));
 
497
    }
 
498
#endif
 
499
}
 
500
 
 
501
size_t clamav_stats_get_num(void *cbdata)
 
502
{
 
503
    cli_intel_t *intel;
 
504
 
 
505
    intel = (cli_intel_t *)cbdata;
 
506
 
 
507
    if (!(intel))
 
508
        return 0;
 
509
 
 
510
    return intel->nsamples;
 
511
}
 
512
 
 
513
size_t clamav_stats_get_size(void *cbdata)
 
514
{
 
515
    cli_intel_t *intel;
 
516
    cli_flagged_sample_t *sample;
 
517
    size_t sz, i;
 
518
    int err;
 
519
 
 
520
    intel = (cli_intel_t *)cbdata;
 
521
    if (!(intel))
 
522
        return 0;
 
523
 
 
524
    sz = sizeof(cli_intel_t);
 
525
 
 
526
#ifdef CL_THREAD_SAFE
 
527
    err = pthread_mutex_lock(&(intel->mutex));
 
528
    if (err) {
 
529
        cli_warnmsg("clamav_stats_get_size: locking mutex failed (err: %d): %s\n", err, strerror(err));
 
530
        return sz;
 
531
    }
 
532
#endif
 
533
 
 
534
    for (sample = intel->samples; sample != NULL; sample = sample->next) {
 
535
        sz += sizeof(cli_flagged_sample_t);
 
536
        if ((sample->virus_name)) {
 
537
            for (i=0; sample->virus_name[i] != NULL; i++)
 
538
                sz += strlen(sample->virus_name[i]);
 
539
            sz += sizeof(char **) * i;
 
540
        }
 
541
    }
 
542
 
 
543
#ifdef CL_THREAD_SAFE
 
544
    err = pthread_mutex_unlock(&(intel->mutex));
 
545
    if (err) {
 
546
        cli_warnmsg("clamav_stats_get_size: unlocking mutex failed (err: %d): %s\n", err, strerror(err));
 
547
    }
 
548
#endif
 
549
 
 
550
    return sz;
 
551
}
 
552
 
 
553
#if defined(_WIN32)
 
554
char *clamav_stats_get_hostid(void *cbdata)
 
555
{
 
556
    HW_PROFILE_INFO HwProfInfo;
 
557
 
 
558
    if (!GetCurrentHwProfile(&HwProfInfo))
 
559
        return strdup(STATS_ANON_UUID);
 
560
 
 
561
    return strdup(HwProfInfo.szHwProfileGuid);
 
562
}
 
563
#elif defined(C_SOLARIS)
 
564
char *clamav_stats_get_hostid(void *cbdata)
 
565
{
 
566
    struct utsname utsnm;
 
567
    int ret;
 
568
 
 
569
    ret = uname(&utsnm);
 
570
    if (ret != -1)
 
571
        return strdup(utsnm.nodename);
 
572
 
 
573
    return strdup(STATS_ANON_UUID);
 
574
}
 
575
#else
 
576
char *clamav_stats_get_hostid(void *cbdata)
 
577
{
 
578
    char *sysctls[] = {
 
579
        "kern.hostuuid",
 
580
        NULL
 
581
    };
 
582
    size_t bufsz, i;
 
583
    char *buf;
 
584
 
 
585
#if HAVE_SYSCTLBYNAME
 
586
    /*
 
587
     * FreeBSD provides a handy-dandy sysctl for grabbing the system's HostID. In a jail that
 
588
     * hasn't run the hostid rc.d script, the hostid defaults to all zeros.
 
589
     */
 
590
    for (i=0; sysctls[i] != NULL; i++) {
 
591
        if (sysctlbyname(sysctls[i], NULL, &bufsz, NULL, 0))
 
592
            continue;
 
593
 
 
594
        break; /* Got one */
 
595
    }
 
596
 
 
597
    if (sysctls[i] != NULL) {
 
598
        buf = calloc(1, bufsz+1);
 
599
        if (sysctlbyname(sysctls[i], buf, &bufsz, NULL, 0))
 
600
            return strdup(STATS_ANON_UUID); /* Not sure why this would happen, but we'll just default to the anon uuid on error */
 
601
 
 
602
        return buf;
 
603
    }
 
604
 
 
605
    return strdup(STATS_ANON_UUID);
 
606
#else
 
607
    buf = internal_get_host_id();
 
608
    if (!(buf))
 
609
        return strdup(STATS_ANON_UUID);
 
610
    return buf;
 
611
#endif
 
612
}
 
613
#endif
 
614
 
 
615
static cli_flagged_sample_t *find_sample(cli_intel_t *intel, const char *virname, const unsigned char *md5, size_t size, stats_section_t *sections)
 
616
{
 
617
    cli_flagged_sample_t *sample;
 
618
    size_t i;
 
619
 
 
620
    for (sample = intel->samples; sample != NULL; sample = sample->next) {
 
621
        int foundSections = 0;
 
622
 
 
623
        if (sample->size != size)
 
624
            continue;
 
625
 
 
626
        if (memcmp(sample->md5, md5, sizeof(sample->md5)))
 
627
            continue;
 
628
 
 
629
        if (!(virname))
 
630
            return sample;
 
631
 
 
632
        if ((sections) && (sample->sections)) {
 
633
            if (sections->nsections == sample->sections->nsections) {
 
634
                for (i=0; i < sections->nsections; i++)
 
635
                    if (sections->sections[i].len == sample->sections->sections[i].len)
 
636
                        if (memcmp(sections->sections[i].md5, sample->sections->sections[i].md5, sizeof(stats_section_t)))
 
637
                            break;
 
638
 
 
639
                if (i == sections->nsections)
 
640
                    foundSections = 1;
 
641
            }
 
642
        } else {
 
643
            foundSections = 1;
 
644
        }
 
645
 
 
646
        if (foundSections)
 
647
            for (i=0; sample->virus_name[i] != NULL; i++)
 
648
                if (!strcmp(sample->virus_name[i], virname))
 
649
                    return sample;
 
650
    }
 
651
 
 
652
    return NULL;
 
653
}
 
654
 
 
655
void cl_engine_set_clcb_stats_submit(struct cl_engine *engine, clcb_stats_submit callback)
 
656
{
 
657
    engine->cb_stats_submit = callback;
 
658
}
 
659
 
 
660
void cl_engine_set_stats_set_cbdata(struct cl_engine *engine, void *cbdata)
 
661
{
 
662
    engine->stats_data = cbdata;
 
663
}
 
664
 
 
665
void cl_engine_set_clcb_stats_add_sample(struct cl_engine *engine, clcb_stats_add_sample callback)
 
666
{
 
667
    engine->cb_stats_add_sample = callback;
 
668
}
 
669
 
 
670
void cl_engine_set_clcb_stats_remove_sample(struct cl_engine *engine, clcb_stats_remove_sample callback)
 
671
{
 
672
    engine->cb_stats_remove_sample = callback;
 
673
}
 
674
 
 
675
void cl_engine_set_clcb_stats_decrement_count(struct cl_engine *engine, clcb_stats_decrement_count callback)
 
676
{
 
677
    engine->cb_stats_decrement_count = callback;
 
678
}
 
679
 
 
680
void cl_engine_set_clcb_stats_flush(struct cl_engine *engine, clcb_stats_flush callback)
 
681
{
 
682
    engine->cb_stats_flush = callback;
 
683
}
 
684
 
 
685
void cl_engine_set_clcb_stats_get_num(struct cl_engine *engine, clcb_stats_get_num callback)
 
686
{
 
687
    engine->cb_stats_get_num = callback;
 
688
}
 
689
 
 
690
void cl_engine_set_clcb_stats_get_size(struct cl_engine *engine, clcb_stats_get_size callback)
 
691
{
 
692
    engine->cb_stats_get_size = callback;
 
693
}
 
694
 
 
695
void cl_engine_set_clcb_stats_get_hostid(struct cl_engine *engine, clcb_stats_get_hostid callback)
 
696
{
 
697
    engine->cb_stats_get_hostid = callback;
 
698
}
 
699
 
 
700
void cl_engine_stats_enable(struct cl_engine *engine)
 
701
{
 
702
    engine->cb_stats_add_sample = clamav_stats_add_sample;
 
703
    engine->cb_stats_submit = clamav_stats_submit;
 
704
}