Browse code

shared/optparser.c: improve cmdline args handling

git-svn: trunk@4625

Tomasz Kojm authored on 2009/01/20 04:41:27
Showing 7 changed files
... ...
@@ -1,3 +1,7 @@
1
+Mon Jan 19 21:01:33 CET 2009 (tk)
2
+---------------------------------
3
+ * shared/optparser.c: improve cmdline args handling
4
+
1 5
 Mon Jan 19 15:38:39 CET 2009 (tk)
2 6
 ---------------------------------
3 7
  * libclamav/dlp.c: fix CC detection and chksumming (bb#1264)
... ...
@@ -82,9 +82,12 @@ int main(int argc, char **argv) {
82 82
 	optfree(opts);
83 83
 	return 0;
84 84
     }
85
-	
86
-    if(opts->filename)
87
-	mprintf("^Ignoring option %s\n", opts->filename);
85
+
86
+    if(opts->filename) {
87
+	int x;
88
+	for(x = 0; opts->filename[x]; x++)
89
+	    mprintf("^Ignoring option %s\n", opts->filename[x]);
90
+    }
88 91
 
89 92
     if(optget(opts, "version")->enabled) {
90 93
 	printf("clamav-milter %s\n", get_version());
... ...
@@ -406,7 +406,7 @@ int client(const struct optstruct *opts, int *infected)
406 406
 	scantype = "MULTISCAN";
407 407
 
408 408
     /* parse argument list */
409
-    if(opts->filename == NULL || strlen(opts->filename) == 0) {
409
+    if(opts->filename == NULL) {
410 410
 	/* scan current directory */
411 411
 	if(!getcwd(cwd, PATH_MAX)) {
412 412
 	    logg("^Can't get absolute pathname of current working directory.\n");
... ...
@@ -423,7 +423,7 @@ int client(const struct optstruct *opts, int *infected)
423 423
 
424 424
 	close(sockd);
425 425
 
426
-    } else if(!strcmp(opts->filename, "-")) { /* scan data from stdin */
426
+    } else if(!strcmp(opts->filename[0], "-")) { /* scan data from stdin */
427 427
         int is_unix;
428 428
 	if((sockd = dconnect(opts, &is_unix)) < 0)
429 429
 	    return 2;
... ...
@@ -458,19 +458,16 @@ int client(const struct optstruct *opts, int *infected)
458 458
 
459 459
     } else {
460 460
 	int x;
461
-	char *thefilename;
462
-	for (x = 0; (thefilename = cli_strtok(opts->filename, x, "\t")) != NULL; x++) {
463
-	    fullpath = thefilename;
464
-
461
+	for (x = 0; opts->filename[x] && (fullpath = strdup(opts->filename[x])); x++) {
465 462
 	    if(stat(fullpath, &sb) == -1) {
466 463
 		logg("^Can't access file %s\n", fullpath);
467 464
 		perror(fullpath);
468 465
 		errors++;
469 466
 	    } else {
470 467
 		if(strcmp(fullpath, "/") && (strlen(fullpath) < 2 || (fullpath[0] != '/' && fullpath[0] != '\\' && fullpath[1] != ':'))) {
471
-		    fullpath = abpath(thefilename);
472
-		    free(thefilename);
473
-
468
+		    char *pt = abpath(fullpath);
469
+		    free(fullpath);
470
+		    fullpath = pt;
474 471
 		    if(!fullpath) {
475 472
 			logg("^Can't determine absolute path.\n");
476 473
 			return 2;
... ...
@@ -496,7 +493,6 @@ int client(const struct optstruct *opts, int *infected)
496 496
 			errors++;
497 497
 		}
498 498
 	    }
499
-
500 499
 	    free(fullpath);
501 500
 	}
502 501
     }
... ...
@@ -608,8 +608,7 @@ int scanmanager(const struct optstruct *opts)
608 608
 #endif
609 609
 
610 610
     /* check filetype */
611
-    if(opts->filename == NULL || strlen(opts->filename) == 0) {
612
-
611
+    if(opts->filename == NULL) {
613 612
 	/* we need full path for some reasons (eg. archive handling) */
614 613
 	if(!getcwd(cwd, sizeof(cwd))) {
615 614
 	    logg("!Can't get absolute pathname of current working directory\n");
... ...
@@ -617,11 +616,11 @@ int scanmanager(const struct optstruct *opts)
617 617
 	} else
618 618
 	    ret = scandirs(cwd, engine, opts, options, 1);
619 619
 
620
-    } else if(!strcmp(opts->filename, "-")) { /* read data from stdin */
620
+    } else if(!strcmp(opts->filename[0], "-")) { /* read data from stdin */
621 621
 	ret = scanstdin(engine, opts, options);
622 622
 
623 623
     } else {
624
-	for (x = 0; (file = cli_strtok(opts->filename, x, "\t")) != NULL; x++) {
624
+	for (x = 0; opts->filename[x] && (file = strdup(opts->filename[x])); x++) {
625 625
 	    if((fmodeint = fileinfo(file, 2)) == -1) {
626 626
 		logg("^Can't access file %s\n", file);
627 627
 		perror(file);
... ...
@@ -578,9 +578,13 @@ static int optaddarg(struct optstruct *opts, const char *name, const char *strar
578 578
 void optfree(struct optstruct *opts)
579 579
 {
580 580
     	struct optstruct *h, *a;
581
+	int i;
581 582
 
582
-    if(opts && opts->filename)
583
+    if(opts && opts->filename) {
584
+	for(i = 0; opts->filename[i]; i++)
585
+	    free(opts->filename[i]);
583 586
 	free(opts->filename);
587
+    }
584 588
 
585 589
     while(opts) {
586 590
 	a = opts->nextarg;
... ...
@@ -924,24 +928,19 @@ struct optstruct *optparse(const char *cfgfile, int argc, char **argv, int verbo
924 924
     }
925 925
 
926 926
     if(!cfgfile && (optind < argc)) {
927
-        lc = 0;
928
-
929
-	/* count length of non-option arguments */
930
-	for(i = optind; i < argc; i++)
931
-	    lc += strlen(argv[i]);
932
-
933
-	lc += argc - optind + 1;
934
-	opts->filename = (char *) calloc(lc, sizeof(char));
927
+	opts->filename = (char **) calloc(argc - optind + 1, sizeof(char *));
935 928
 	if(!opts->filename) {
936 929
 	    fprintf(stderr, "ERROR: optparse: calloc failed\n");
937 930
 	    optfree(opts);
938 931
 	    return NULL;
939 932
 	}
940
-
941 933
         for(i = optind; i < argc; i++) {
942
-	    strncat(opts->filename, argv[i], strlen(argv[i]));
943
-	    if(i != argc - 1)
944
-		strncat(opts->filename, "\t", 1);
934
+	    opts->filename[i - optind] = strdup(argv[i]);
935
+	    if(!opts->filename[i - optind]) {
936
+		fprintf(stderr, "ERROR: optparse: strdup failed\n");
937
+		optfree(opts);
938
+		return NULL;
939
+	    }
945 940
 	}
946 941
     }
947 942
 
... ...
@@ -42,7 +42,7 @@ struct optstruct {
42 42
     struct optstruct *nextarg;
43 43
     struct optstruct *next;
44 44
 
45
-    char *filename; /* cmdline */
45
+    char **filename; /* cmdline */
46 46
 };
47 47
 
48 48
 const struct optstruct *optget(const struct optstruct *opts, const char *name);
... ...
@@ -119,34 +119,31 @@ static int hexdump(void)
119 119
 
120 120
 static int md5sig(const struct optstruct *opts, unsigned int mdb)
121 121
 {
122
-	char *md5, *filename;
122
+	char *md5;
123 123
 	unsigned int i;
124 124
 	struct stat sb;
125 125
 
126 126
 
127 127
     if(opts->filename) {
128
-	for(i = 0; (filename = cli_strtok(opts->filename, i, "\t")); i++) {
129
-	    if(stat(filename, &sb) == -1) {
130
-		mprintf("!md5sig: Can't access file %s\n", filename);
128
+	for(i = 0; opts->filename[i]; i++) {
129
+	    if(stat(opts->filename[i], &sb) == -1) {
130
+		mprintf("!md5sig: Can't access file %s\n", opts->filename[i]);
131 131
 		perror("md5sig");
132
-		free(filename);
133 132
 		return -1;
134 133
 	    } else {
135 134
 		if((sb.st_mode & S_IFMT) == S_IFREG) {
136
-		    if((md5 = cli_md5file(filename))) {
135
+		    if((md5 = cli_md5file(opts->filename[i]))) {
137 136
 			if(mdb)
138
-			    mprintf("%u:%s:%s\n", (unsigned int) sb.st_size, md5, filename);
137
+			    mprintf("%u:%s:%s\n", (unsigned int) sb.st_size, md5, opts->filename[i]);
139 138
 			else
140
-			    mprintf("%s:%u:%s\n", md5, (unsigned int) sb.st_size, filename);
139
+			    mprintf("%s:%u:%s\n", md5, (unsigned int) sb.st_size, opts->filename[i]);
141 140
 			free(md5);
142 141
 		    } else {
143
-			mprintf("!md5sig: Can't generate MD5 checksum for %s\n", filename);
144
-			free(filename);
142
+			mprintf("!md5sig: Can't generate MD5 checksum for %s\n", opts->filename[i]);
145 143
 			return -1;
146 144
 		    }
147 145
 		}
148 146
 	    }
149
-	    free(filename);
150 147
 	}
151 148
 
152 149
     } else { /* stream */
... ...
@@ -589,8 +586,8 @@ static int build(const struct optstruct *opts)
589 589
 
590 590
     /* try to read cvd header of current database */
591 591
     if(opts->filename) {
592
-	if(cli_strbcasestr(opts->filename, ".cvd") || cli_strbcasestr(opts->filename, ".cld")) {
593
-	    strncpy(olddb, opts->filename, sizeof(olddb));
592
+	if(cli_strbcasestr(opts->filename[0], ".cvd") || cli_strbcasestr(opts->filename[0], ".cld")) {
593
+	    strncpy(olddb, opts->filename[0], sizeof(olddb));
594 594
 	    olddb[sizeof(olddb)-1]='\0';
595 595
 	} else {
596 596
 	    mprintf("!build: Not a CVD/CLD file\n");
... ...
@@ -1611,8 +1608,8 @@ static int makediff(const struct optstruct *opts)
1611 1611
 	return -1;
1612 1612
     }
1613 1613
 
1614
-    if(!(cvd = cl_cvdhead(opts->filename))) {
1615
-	mprintf("!makediff: Can't read CVD header from %s\n", opts->filename);
1614
+    if(!(cvd = cl_cvdhead(opts->filename[0]))) {
1615
+	mprintf("!makediff: Can't read CVD header from %s\n", opts->filename[0]);
1616 1616
 	return -1;
1617 1617
     }
1618 1618
     newver = cvd->version;
... ...
@@ -1665,8 +1662,8 @@ static int makediff(const struct optstruct *opts)
1665 1665
 	return -1;
1666 1666
     }
1667 1667
 
1668
-    if(cvd_unpack(opts->filename, ndir) == -1) {
1669
-	mprintf("!makediff: Can't unpack CVD file %s\n", opts->filename);
1668
+    if(cvd_unpack(opts->filename[0], ndir) == -1) {
1669
+	mprintf("!makediff: Can't unpack CVD file %s\n", opts->filename[0]);
1670 1670
 	cli_rmdirs(odir);
1671 1671
 	cli_rmdirs(ndir);
1672 1672
 	free(odir);
... ...
@@ -1674,7 +1671,7 @@ static int makediff(const struct optstruct *opts)
1674 1674
 	return -1;
1675 1675
     }
1676 1676
 
1677
-    if(strstr(opts->filename, "main"))
1677
+    if(strstr(opts->filename[0], "main"))
1678 1678
 	snprintf(name, sizeof(name), "main-%u.script", newver);
1679 1679
     else
1680 1680
 	snprintf(name, sizeof(name), "daily-%u.script", newver);
... ...
@@ -1801,14 +1798,14 @@ int main(int argc, char **argv)
1801 1801
 	    mprintf("!--verify-cdiff requires two arguments\n");
1802 1802
 	    ret = -1;
1803 1803
 	} else {
1804
-	    if(stat(opts->filename, &sb) == -1) {
1805
-		mprintf("--verify-cdiff: Can't get status of %s\n", opts->filename);
1804
+	    if(stat(opts->filename[0], &sb) == -1) {
1805
+		mprintf("--verify-cdiff: Can't get status of %s\n", opts->filename[0]);
1806 1806
 		ret = -1;
1807 1807
 	    } else {
1808 1808
 		if(S_ISDIR(sb.st_mode))
1809
-		    ret = verifydiff(optget(opts, "verify-cdiff")->strarg, NULL, opts->filename);
1809
+		    ret = verifydiff(optget(opts, "verify-cdiff")->strarg, NULL, opts->filename[0]);
1810 1810
 		else
1811
-		    ret = verifydiff(optget(opts, "verify-cdiff")->strarg, opts->filename, NULL);
1811
+		    ret = verifydiff(optget(opts, "verify-cdiff")->strarg, opts->filename[0], NULL);
1812 1812
 	    }
1813 1813
 	}
1814 1814
     } else