Browse code

allow loading multiple .pdb/.wdb files

git-svn: trunk@2389

Tomasz Kojm authored on 2006/10/16 04:16:33
Showing 3 changed files
... ...
@@ -1,3 +1,7 @@
1
+Sun Oct 15 21:15:58 CEST 2006 (tk)
2
+----------------------------------
3
+  * libclamav: allow loading multiple .pdb/.wdb files (Edwin)
4
+
1 5
 Sun Oct 15 12:11:26 BST 2006 (njh)
2 6
 ----------------------------------
3 7
   * libclamav/untar.c:	Fix compilation warning on Linux
... ...
@@ -19,6 +19,9 @@
19 19
  *  MA 02110-1301, USA.
20 20
  *
21 21
  *  $Log: regex_list.c,v $
22
+ *  Revision 1.11  2006/10/15 19:16:33  tkojm
23
+ *  allow loading multiple .pdb/.wdb files
24
+ *
22 25
  *  Revision 1.10  2006/10/14 23:52:02  tkojm
23 26
  *  code cleanup
24 27
  *
... ...
@@ -337,6 +340,7 @@ int regex_list_match(struct regex_matcher* matcher,const char* real_url,const ch
337 337
 		size_t display_len = strlen(display_url);
338 338
 		size_t buffer_len  = hostOnly ? real_len : real_len + display_len + 1;
339 339
 		char*  buffer = cli_malloc(buffer_len+1);
340
+		size_t i;
340 341
 		int partcnt,rc;
341 342
 		unsigned long int partoff;
342 343
 
... ...
@@ -351,7 +355,13 @@ int regex_list_match(struct regex_matcher* matcher,const char* real_url,const ch
351 351
 		}
352 352
 		cli_dbgmsg("Looking up in regex_list: %s\n", buffer);
353 353
 
354
-		rc = cli_ac_scanbuff(buffer,buffer_len,info,hostOnly ? matcher->root_hosts : matcher->root_urls,&partcnt,0,0,&partoff,0,-1,NULL);
354
+		if(hostOnly)
355
+			for(i = 0; i < matcher->root_hosts_cnt; i++) {
356
+				if(( rc = cli_ac_scanbuff((unsigned char*)buffer,buffer_len,info, &matcher->root_hosts[i] ,&partcnt,0,0,&partoff,0,-1,NULL) ))
357
+					break;
358
+			}
359
+		else
360
+			rc = 0;
355 361
 		if(!rc && !hostOnly) 
356 362
 			rc = match_node(matcher->root_regex,(unsigned char*)buffer,buffer_len,info) == MATCH_SUCCESS ? CL_VIRUS : CL_SUCCESS;
357 363
 		free(buffer);
... ...
@@ -417,6 +427,7 @@ static inline struct tree_node* stack_pop(struct node_stack* stack)
417 417
 /* Initializes @matcher, allocating necesarry substructures */
418 418
 int init_regex_list(struct regex_matcher* matcher)
419 419
 {
420
+	int rc;
420 421
 	/*
421 422
 	if(!engine_ok) {
422 423
 		cli_dbgmsg("Matcher engine not initialized\n");
... ...
@@ -426,45 +437,27 @@ int init_regex_list(struct regex_matcher* matcher)
426 426
 
427 427
 	massert(matcher);
428 428
 	matcher->list_inited = 0;
429
-	matcher->root_hosts = (struct cli_matcher*) cli_calloc(1,sizeof(*matcher->root_hosts));
430
-	if(!matcher->root_hosts)
431
-		return CL_EMEM;
432
-
433
-	matcher->root_hosts->ac_root =  (struct cli_ac_node *) cli_calloc(1, sizeof(struct cli_ac_node));
434
-	if(!matcher->root_hosts->ac_root) {
435
-		free(matcher->root_hosts);
436
-		return CL_EMEM;
437
-	}
438
-
439
-	matcher->root_urls = (struct cli_matcher*) cli_calloc(1,sizeof(*matcher->root_hosts));
440
-	if(!matcher->root_urls) {
441
-		free(matcher->root_hosts->ac_root);
442
-		free(matcher->root_hosts);
443
-		return CL_EMEM;
444
-	}
445
-
446
-	matcher->root_urls->ac_root =  (struct cli_ac_node *) cli_calloc(1, sizeof(struct cli_ac_node));
447
-	if(!matcher->root_urls->ac_root) {
448
-		free(matcher->root_hosts->ac_root);
449
-		free(matcher->root_hosts);
450
-		free(matcher->root_urls);
451
-		return CL_EMEM;
452
-	}
429
+ 	matcher->root_hosts_cnt = 0;
430
+ 	matcher->root_hosts = NULL;
431
+ 	matcher->root_hosts_cnt = 0;
453 432
 
454 433
 	matcher->root_regex = tree_root_alloc();
455 434
 	if(!matcher->root_regex) {
456
-		free(matcher->root_hosts->ac_root);
457
-		free(matcher->root_hosts);
458
-		free(matcher->root_urls->ac_root);
459
-		free(matcher->root_urls);
460 435
 		return CL_EMEM;
461 436
 	}
462 437
 
463
-	stack_init(&matcher->node_stack);
464
-	stack_init(&matcher->node_stack_alt);
438
+	if(( rc = stack_init(&matcher->node_stack) )) {
439
+		free(matcher->root_regex);
440
+		return rc;
441
+	}
442
+	if(( rc = stack_init(&matcher->node_stack_alt) )) {
443
+		free(matcher->root_regex);
444
+		stack_destroy(&matcher->node_stack);
445
+		return rc;
446
+	}
465 447
 
466 448
 	matcher->list_inited=1;
467
-	matcher->list_built=0;
449
+	matcher->list_built=1;/* its empty, but pretend its built, so that load_ will realloc root_hosts */
468 450
 	matcher->list_loaded=0;
469 451
 
470 452
 	return CL_SUCCESS;
... ...
@@ -525,10 +518,10 @@ int load_regex_matcher(struct regex_matcher* matcher,FILE* fd,unsigned int optio
525 525
 
526 526
 	if(matcher->list_inited==-1)
527 527
 		return CL_EMALFDB; /* already failed to load */
528
-	if(matcher->list_loaded) {
528
+/*	if(matcher->list_loaded) {
529 529
 		cli_warnmsg("Regex list has already been loaded, ignoring further requests for load\n");
530 530
 		return CL_SUCCESS;
531
-	}
531
+	}*/
532 532
 	if(!fd) {
533 533
 		cli_errmsg("Unable to load regex list (null file)\n");
534 534
 		return CL_EIO;
... ...
@@ -577,12 +570,26 @@ int load_regex_matcher(struct regex_matcher* matcher,FILE* fd,unsigned int optio
577 577
 			if(( rc = add_pattern(matcher,(const unsigned char*)pattern,flags) ))
578 578
 				return rc==CL_EMEM ? CL_EMEM : CL_EMALFDB;
579 579
 		}
580
-		else if(buffer[0] == 'H' && !is_whitelist) {/*matches displayed host*/
581
-			if(( rc = add_regex_list_element(matcher->root_hosts,pattern,flags) ))
582
-				return rc==CL_EMEM ? CL_EMEM : CL_EMALFDB;
580
+		else if( ( buffer[0] == 'H' && !is_whitelist) || (buffer[0] == 'M' && is_whitelist)) {/*matches displayed host*/
581
+ 			if(matcher->list_built) {
582
+ 				struct cli_matcher* old_hosts = matcher->root_hosts;
583
+ 				matcher->root_hosts_cnt++;
584
+ 
585
+ 				matcher->root_hosts = cli_realloc(matcher->root_hosts, matcher->root_hosts_cnt * sizeof(*matcher->root_hosts));
586
+ 				if(!matcher->root_hosts) {
587
+ 					matcher->root_hosts = old_hosts;/* according to manpage this must still be valid*/
588
+ 					return CL_EMEM;
583 589
 		} 
584
-		else if(buffer[0] == 'M' && is_whitelist) {/*matches real host <-> displayed host */							
585
-			if(( rc = add_regex_list_element(matcher->root_hosts,pattern,flags) ))
590
+ 				memset(&matcher->root_hosts[matcher->root_hosts_cnt-1], 0, sizeof(struct cli_matcher));
591
+ 				matcher->root_hosts[matcher->root_hosts_cnt-1].ac_root = cli_calloc(1, sizeof(struct cli_ac_node));
592
+ 				if(!matcher->root_hosts[matcher->root_hosts_cnt-1].ac_root) {
593
+ 					matcher->root_hosts_cnt--;
594
+ 					return CL_EMEM;
595
+ 				}
596
+ 				cli_dbgmsg("Increased number of root_hosts in regex_list.c\n");
597
+ 				matcher->list_built = 0;
598
+ 			}
599
+ 			if(( rc = add_regex_list_element(&matcher->root_hosts[matcher->root_hosts_cnt-1],pattern,flags) ))
586 600
 				return rc==CL_EMEM ? CL_EMEM : CL_EMALFDB;
587 601
 		}
588 602
 		else {
... ...
@@ -593,7 +600,8 @@ int load_regex_matcher(struct regex_matcher* matcher,FILE* fd,unsigned int optio
593 593
 		}
594 594
 	}
595 595
 	matcher->list_loaded = 1;
596
-	build_regex_list(matcher);
596
+	if(( rc = build_regex_list(matcher) ))
597
+		return rc;
597 598
 
598 599
 #ifndef NDEBUG
599 600
 /*			dump_tree(matcher->root_regex);*/
... ...
@@ -724,13 +732,14 @@ static void regex_list_dobuild(struct tree_node* called_from,struct tree_node* n
724 724
 /* Build the matcher list */
725 725
 static int build_regex_list(struct regex_matcher* matcher)
726 726
 {
727
+	int rc;
727 728
 	if(!matcher->list_inited || !matcher->list_loaded) {
728 729
 		cli_errmsg("Regex list not loaded!\n");
729 730
 		return -1;/*TODO: better error code */
730 731
 	}
731 732
 	cli_dbgmsg("Building regex list\n");
732
-	cli_ac_buildtrie(matcher->root_hosts);
733
-	cli_ac_buildtrie(matcher->root_urls);
733
+ 	if(( rc = cli_ac_buildtrie(&matcher->root_hosts[matcher->root_hosts_cnt-1]) ))
734
+ 			return rc;
734 735
 	matcher->list_built=1;
735 736
 
736 737
 	return CL_SUCCESS;
... ...
@@ -744,17 +753,14 @@ void regex_list_done(struct regex_matcher* matcher)
744 744
 	regex_list_cleanup(matcher);
745 745
 	if(matcher->list_loaded) {
746 746
 		if(matcher->root_hosts) {
747
-			cli_ac_free(matcher->root_hosts);
747
+			size_t i;
748
+			for(i=0;i<matcher->root_hosts_cnt;i++)
749
+				cli_ac_free(&matcher->root_hosts[i]);
748 750
 			free(matcher->root_hosts);
749 751
 			matcher->root_hosts=NULL;
750 752
 		}
751 753
 
752
-		if(matcher->root_urls) {
753
-			cli_ac_free(matcher->root_urls);
754
-			free(matcher->root_urls);
755
-			matcher->root_urls=NULL;
756
-		}
757
-
754
+		matcher->root_hosts_cnt=0;
758 755
 		matcher->list_built=0;
759 756
 		destroy_tree(matcher);
760 757
 		matcher->list_loaded=0;
... ...
@@ -1120,7 +1126,6 @@ static inline void tree_node_insert_nonbin(struct tree_node* node, struct tree_n
1120 1120
 				node->listend = 0;
1121 1121
 				node->next = new;
1122 1122
 				new->listend=1;
1123
-				return;
1124 1123
 			}
1125 1124
 		node->u.children = cli_realloc(node->u.children,sizeof(node->u.children[0])*(2));
1126 1125
 		if(node->u.children) {
... ...
@@ -45,8 +45,8 @@ struct node_stack {
45 45
 
46 46
 struct regex_matcher {
47 47
 	struct cli_matcher* root_hosts;
48
-	struct cli_matcher* root_urls;
49 48
 	struct tree_node* root_regex;
49
+	size_t root_hosts_cnt;
50 50
 	int list_inited;
51 51
 	int list_loaded;
52 52
 	int list_built;