Browse code

New fixes from Thomas Lamy. And others.

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@137 77e5149b-7576-45b1-b177-96237e5ba77b

Tomasz Kojm authored on 2003/12/03 07:48:56
Showing 32 changed files
... ...
@@ -1,3 +1,27 @@
1
+Tue Dec  2 23:41:04 CET 2003 (tk)
2
+---------------------------------
3
+  * New fixes from Thomas Lamy <Thomas.Lamy*in-online.net>:
4
+    + configure.in: check for memcpy()
5
+    + libclamav:
6
+      + cli_strtok(): more generic replacement for tok() and cli_tok()
7
+      + cli_enqueue(): return CL_EMEM on malloc problems
8
+      + cli_maketrans(): return cli_enqueue()s result
9
+      + cl_buildtrie(): same
10
+    + clamd:
11
+      + fixed memleaks in config file parsing
12
+      + replaced tok() with new and more general cli_strtok() in libclamav
13
+      + check return value of cl_buildtrie()
14
+    + clamscan:
15
+      + more than one filename may be given on cmdline
16
+      + check return value of cl_buildtrie()
17
+      + opt->filename cleanup
18
+    + examples/ex1.c: check return value of cl_buildtrie()
19
+    + other cosmetic fixes (removed unused variables, added missing includes)
20
+
21
+  * configure.in: define _REENTRANT on pthread compliant systems only (thanks
22
+		  to Nigel)
23
+  * clamd: usleep if there are no free sessions (thanks to Ed Phillips)
24
+
1 25
 Tue Dec  2 06:38:13 GMT 2003 (njh)
2 26
 ----------------------------------
3 27
   * clamav-milter: use setsid if setpgrp not available
... ...
@@ -81,7 +81,7 @@ dnl there is now a CREATE_PREFIX_TARGET_H in this file as a shorthand for
81 81
 dnl PREFIX_CONFIG_H from a target.h file, however w/o the target.h ever created
82 82
 dnl (the prefix is a bit different, since we add an extra -target- and -host-)
83 83
 dnl 
84
-dnl @version: $Id: aclocal.m4,v 1.13 2003/12/01 22:55:35 kojm Exp $
84
+dnl @version: $Id: aclocal.m4,v 1.14 2003/12/02 22:48:56 kojm Exp $
85 85
 dnl @author Guido Draheim <guidod@gmx.de>                 STATUS: used often
86 86
 
87 87
 AC_DEFUN([AC_CREATE_TARGET_H],
... ...
@@ -4041,7 +4041,7 @@ dnl      AC_COMPILE_CHECK_SIZEOF(ptrdiff_t, $headers)
4041 4041
 dnl      AC_COMPILE_CHECK_SIZEOF(off_t, $headers)
4042 4042
 dnl
4043 4043
 dnl @author Kaveh Ghazi <ghazi@caip.rutgers.edu>
4044
-dnl @version $Id: aclocal.m4,v 1.13 2003/12/01 22:55:35 kojm Exp $
4044
+dnl @version $Id: aclocal.m4,v 1.14 2003/12/02 22:48:56 kojm Exp $
4045 4045
 dnl
4046 4046
 AC_DEFUN([AC_COMPILE_CHECK_SIZEOF],
4047 4047
 [changequote(<<, >>)dnl
... ...
@@ -25,6 +25,7 @@
25 25
 #include "cfgfile.h"
26 26
 #include "others.h"
27 27
 #include "defaults.h"
28
+#include "str.h"
28 29
 
29 30
 
30 31
 struct cfgstruct *parsecfg(const char *cfgfile)
... ...
@@ -103,8 +104,8 @@ struct cfgstruct *parsecfg(const char *cfgfile)
103 103
 	}
104 104
 
105 105
 
106
-	if((name = tok(buff, 1))) {
107
-	    arg = tok(buff, 2);
106
+	if((name = cli_strtok(buff, 0, " \r\n"))) {
107
+	    arg = cli_strtok(buff, 1, " \r\n");
108 108
 	    found = 0;
109 109
 	    for(i = 0; ; i++) {
110 110
 		pt = &cfg_options[i];
... ...
@@ -137,6 +138,7 @@ struct cfgstruct *parsecfg(const char *cfgfile)
137 137
 				    return NULL;
138 138
 				}
139 139
 				copt = regcfg(copt, name, NULL, atoi(arg));
140
+				free(arg);
140 141
 				break;
141 142
 			    case OPT_COMPSIZE:
142 143
 				if(!arg) {
... ...
@@ -164,10 +166,11 @@ struct cfgstruct *parsecfg(const char *cfgfile)
164 164
 				    calc = atoi(arg);
165 165
 				}
166 166
 				copt = regcfg(copt, name, NULL, calc);
167
+				free(arg);
167 168
 				break;
168 169
 			    case OPT_NOARG:
169 170
 				if(arg) {
170
-				    fprintf(stderr, "ERROR: Parse error at line %d: Option %s doesn't support arguments.\n", line, name);
171
+				    fprintf(stderr, "ERROR: Parse error at line %d: Option %s doesn't support arguments (got '%s').\n", line, name, arg);
171 172
 				    return NULL;
172 173
 				}
173 174
 				copt = regcfg(copt, name, NULL, 0);
... ...
@@ -175,6 +178,11 @@ struct cfgstruct *parsecfg(const char *cfgfile)
175 175
 			    case OPT_OPTARG:
176 176
 				copt = regcfg(copt, name, arg, 0);
177 177
 				break;
178
+			    default:
179
+				fprintf(stderr, "ERROR: Parse error at line %d: Option %s is of unknown type %d\n", line, name, pt->argtype);
180
+				free(name);
181
+				free(arg);
182
+				break;
178 183
 			}
179 184
 		    }
180 185
 		} else
... ...
@@ -221,44 +229,6 @@ void freecfg(struct cfgstruct *copt)
221 221
     return;
222 222
 }
223 223
 
224
-char *tok(const char *line, int field)
225
-{
226
-        int length, counter = 0, i, j = 0, k;
227
-        char *buffer;
228
-
229
-
230
-    length = strlen(line);
231
-    buffer = (char *) mcalloc(length, sizeof(char));
232
-
233
-    for(i = 0; i < length; i++) {
234
-        if(line[i] == ' ' || line[i] == '\n') {
235
-            counter++;
236
-            if(counter == field)
237
-		break;
238
-
239
-            for(k = 0; k < length; k++)
240
-		buffer[k] = 0;
241
-
242
-            j = 0;
243
-	    while((line[i+1] == ' ' || line[i+1] == '\n') && i < length)
244
-		i++;
245
-        } else {
246
-	    if(line[i] != ' ') {
247
-		buffer[j]=line[i];
248
-		j++;
249
-	    }
250
-	}
251
-    }
252
-
253
-    chomp(buffer); /* preventive */
254
-
255
-    if(strlen(buffer) == 0) {
256
-	free(buffer);
257
-	return NULL;
258
-    } else
259
-	return realloc(buffer, strlen(buffer) + 1);
260
-}
261
-
262 224
 struct cfgstruct *regcfg(struct cfgstruct *copt, char *optname, char *strarg, int numarg)
263 225
 {
264 226
 	struct cfgstruct *newnode, *pt;
... ...
@@ -304,3 +274,4 @@ struct cfgstruct *cfgopt(const struct cfgstruct *copt, const char *optname)
304 304
 
305 305
     return NULL;
306 306
 }
307
+
... ...
@@ -50,7 +50,6 @@ struct cfgstruct *parsecfg(const char *cfgfile);
50 50
 struct cfgstruct *regcfg(struct cfgstruct *copt, char *optname, char *strarg, int numarg);
51 51
 
52 52
 struct cfgstruct *cfgopt(const struct cfgstruct *copt, const char *optname);
53
-char *tok(const char *line, int field);
54 53
 
55 54
 void freecfg(struct cfgstruct *copt);
56 55
 
... ...
@@ -190,7 +190,11 @@ void clamd(struct optstruct *opt)
190 190
     }
191 191
 
192 192
     logg("Protecting against %d viruses.\n", virnum);
193
-    cl_buildtrie(root);
193
+    if((ret = cl_buildtrie(root)) != 0) {
194
+	fprintf(stderr, "ERROR: Database initialization error: %s\n", cl_strerror(ret));;
195
+	logg("!Database initialization error: %s\n", cl_strerror(ret));;
196
+	exit(1);
197
+    }
194 198
 
195 199
 
196 200
     /* fork into background */
... ...
@@ -31,6 +31,7 @@
31 31
 
32 32
 #include "options.h"
33 33
 #include "others.h"
34
+#include "../libclamav/others.h"
34 35
 
35 36
 void clamd(struct optstruct *opt);
36 37
 
... ...
@@ -58,6 +59,7 @@ int main(int argc, char **argv)
58 58
 #endif
59 59
     opt=(struct optstruct*)mmalloc(sizeof(struct optstruct));
60 60
     opt->optlist = NULL;
61
+    opt->filename = NULL;
61 62
 
62 63
     while(1) {
63 64
 
... ...
@@ -101,15 +103,13 @@ int main(int argc, char **argv)
101 101
 		strncat(opt->filename, " ", 1);
102 102
 	}
103 103
 
104
-    } else
105
-	/* FIXME !!! Without this, we have segfault */
106
-	opt->filename=(char*)mcalloc(1, sizeof(char));
107
-
104
+    }
108 105
 
109 106
     clamd(opt);
110 107
 
111 108
     free_opt(opt);
112 109
 
110
+    cli_dbgmsg("exit main()");
113 111
     return(0);
114 112
 }
115 113
 
... ...
@@ -299,10 +299,9 @@ void free_opt(struct optstruct *opt)
299 299
 {
300 300
 	struct optnode *handler, *prev;
301 301
 
302
-    if(!opt || !opt->optlist)
302
+    if(!opt)
303 303
 	return;
304 304
 
305
-    //mprintf("*Freeing option list... ");
306 305
     handler = opt->optlist;
307 306
 
308 307
     while(handler != NULL) {
... ...
@@ -314,7 +313,7 @@ void free_opt(struct optstruct *opt)
314 314
 	free(prev);
315 315
     }
316 316
 
317
-    free(opt->filename);
317
+    if(opt->filename)
318
+	free(opt->filename);
318 319
     free(opt);
319
-    //mprintf("*done\n");
320 320
 }
... ...
@@ -128,13 +128,13 @@ int logg(const char *str, ...)
128 128
 
129 129
 	if(*str == '!') {
130 130
 	    fprintf(log_fd, "ERROR: ");
131
-	    vfprintf(log_fd, ++str, args);
131
+	    vfprintf(log_fd, str+1, args);
132 132
 	} else if(*str == '^') {
133 133
 	    fprintf(log_fd, "WARNING: ");
134
-	    vfprintf(log_fd, ++str, args);
134
+	    vfprintf(log_fd, str+1, args);
135 135
 	} else if(*str == '*') {
136 136
 	    if(logverbose)
137
-		vfprintf(log_fd, ++str, args);
137
+		vfprintf(log_fd, str+1, args);
138 138
 	} else vfprintf(log_fd, str, args);
139 139
 
140 140
 	va_end(args);
... ...
@@ -159,12 +159,13 @@ int logg(const char *str, ...)
159 159
 	va_start(args, str);
160 160
 
161 161
 	if(*str == '!') {
162
-	    vsyslog(LOG_ERR,++str, args);
162
+	    vsyslog(LOG_ERR, str+1, args);
163 163
 	} else if(*str == '^') {
164
-	    vsyslog(LOG_WARNING,++str, args);
164
+	    vsyslog(LOG_WARNING, str+1, args);
165 165
 	} else if(*str == '*') {
166
-	    if(logverbose)
167
-		vsyslog(LOG_DEBUG, ++str, args);
166
+	    if(logverbose) {
167
+		vsyslog(LOG_DEBUG, str+1, args);
168
+	    }
168 169
 	} else vsyslog(LOG_INFO, str, args);
169 170
 
170 171
 	va_end(args);
... ...
@@ -16,8 +16,8 @@
16 16
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 17
  */
18 18
 
19
-#ifndef __OTHERS_H
20
-#define __OTHERS_H
19
+#ifndef __CLAMD_OTHERS_H
20
+#define __CLAMD_OTHERS_H
21 21
 
22 22
 #include <stdlib.h>
23 23
 #include "cfgfile.h"
... ...
@@ -32,6 +32,7 @@ short int logverbose, logcompressed, loglock, logtime, sighup;
32 32
 int logsize;
33 33
 const char *logfile;
34 34
 int logg(const char *str, ...);
35
+void logg_close(void);
35 36
 
36 37
 #if defined(CLAMD_USE_SYSLOG) && !defined(C_AIX)
37 38
 short use_syslog;
... ...
@@ -86,8 +86,8 @@ int dirscan(const char *dirname, char **virname, unsigned long int *scanned, con
86 86
 				closedir(dd);
87 87
 				return 1;
88 88
 			    }
89
-			} else
90
-			    if(S_ISREG(statbuf.st_mode) || (S_ISLNK(statbuf.st_mode) && (checksymlink(fname) == 2) && cfgopt(copt, "FollowFileSymlinks")))
89
+			} else {
90
+			    if(S_ISREG(statbuf.st_mode) || (S_ISLNK(statbuf.st_mode) && (checksymlink(fname) == 2) && cfgopt(copt, "FollowFileSymlinks"))) {
91 91
 				if((scanret = cl_scanfile(fname, virname, scanned, root, limits, options)) == CL_VIRUS) {
92 92
 				    mdprintf(odesc, "%s: %s FOUND\n", fname, *virname);
93 93
 				    logg("%s: %s FOUND\n", fname, *virname);
... ...
@@ -102,18 +102,20 @@ int dirscan(const char *dirname, char **virname, unsigned long int *scanned, con
102 102
 				    mdprintf(odesc, "%s: %s ERROR\n", fname, cl_strerror(scanret));
103 103
 				    logg("%s: %s ERROR\n", fname, cl_strerror(scanret));
104 104
 				}
105
+			    }
106
+			}
105 107
 		    }
106 108
 
107 109
 		    free(fname);
108 110
 		}
109 111
 	    }
110 112
 	}
113
+	closedir(dd);
111 114
     } else {
112 115
 	return -1;
113 116
     }
114 117
 
115 118
     (*reclev)--;
116
-    closedir(dd);
117 119
     return ret;
118 120
 
119 121
 }
... ...
@@ -80,7 +80,7 @@ int acceptd = -1;
80 80
 
81 81
 int acceptloop_proc(int socketd, struct cl_node *root, const struct cfgstruct *copt)
82 82
 {
83
-	int i, j, bread, options = 0, maxwait, childs, *session, status,
83
+	int i, j, bread, options = 0, childs, *session, status,
84 84
 	    virnum, need_wait, ret;
85 85
 	struct cfgstruct *cpt;
86 86
 	struct cl_limits limits;
... ...
@@ -223,8 +223,10 @@ int acceptloop_proc(int socketd, struct cl_node *root, const struct cfgstruct *c
223 223
 		if(session[j] && waitpid(session[j], &status, WNOHANG))
224 224
 		    session[j] = 0;
225 225
 
226
-	    if(i == childs)
226
+	    if(i == childs) {
227 227
 		i = 0;
228
+		usleep(50000);
229
+	    }
228 230
 
229 231
 	    if(!session[i])
230 232
 		break;
... ...
@@ -289,7 +291,10 @@ int acceptloop_proc(int socketd, struct cl_node *root, const struct cfgstruct *c
289 289
 		    logg("!Database initialization problem.\n");
290 290
 		    exit(1);
291 291
 		} else {
292
-		    cl_buildtrie(root);
292
+		    if((ret = cl_buildtrie(root)) != 0) {
293
+			logg("!Database initialization error: can't build the trie: %s\n", cl_strerror(i));
294
+			exit(1);
295
+		    }
293 296
 		    /* check integrity */
294 297
 		    if(!testsignature(root)) {
295 298
 			logg("!Unable to detect test signature.\n");
... ...
@@ -61,7 +61,7 @@ void *threadscanner(void *arg)
61 61
 	struct thrarg *tharg = (struct thrarg *) arg;
62 62
 	char buff[32769];
63 63
 	sigset_t sigset;
64
-	int bread, options, maxwait = CL_DEFAULT_MAXWHILEWAIT;
64
+	int bread, options;
65 65
 
66 66
 
67 67
     /* ignore all signals */
... ...
@@ -343,7 +343,10 @@ void *threadwatcher(void *arg)
343 343
 		logg("!Database initialization problem.\n");
344 344
 		kill(progpid, SIGTERM);
345 345
 	    } else {
346
-		cl_buildtrie(*thwarg->root);
346
+		if((ret = cl_buildtrie(*thwarg->root)) != 0) {
347
+		    logg("!Database initialization error: can't build the trie: %s\n", cl_strerror(ret));
348
+		    kill(progpid, SIGTERM);
349
+		}
347 350
 		/* check integrity */
348 351
 		if(!testsignature(*thwarg->root)) {
349 352
 		    logg("!Unable to detect test signature.\n");
... ...
@@ -562,8 +565,10 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
562 562
 
563 563
 	/* find a free session */
564 564
 	for(i = 0; ; i++) {
565
-	    if(i == threads)
565
+	    if(i == threads) {
566 566
 		i = 0;
567
+		usleep(50000);
568
+	    }
567 569
 
568 570
 	    if(!ths[i].active) {
569 571
 		/* logg("*Found free slot: %d\n", i); */
... ...
@@ -623,12 +628,16 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
623 623
 	}
624 624
     }
625 625
     free(ths);
626
+    return 0;
626 627
 }
627 628
 
628 629
 void sighandler_th(int sig)
629 630
 {
630 631
 	time_t currtime;
631
-	int maxwait = CL_DEFAULT_MAXWHILEWAIT * 5, i;
632
+	int maxwait = CL_DEFAULT_MAXWHILEWAIT * 5;
633
+#ifndef CL_DEBUG
634
+	int i;
635
+#endif
632 636
 
633 637
     switch(sig) {
634 638
 	case SIGINT:
... ...
@@ -21,9 +21,11 @@
21 21
 #include <sys/types.h>
22 22
 #include <sys/socket.h>
23 23
 #include <netinet/in.h>
24
+#include <arpa/inet.h>
24 25
 #include <clamav.h>
25 26
 #include <errno.h>
26 27
 
28
+
27 29
 #include "options.h"
28 30
 #include "cfgfile.h"
29 31
 #include "defaults.h"
... ...
@@ -44,7 +46,7 @@ int tcpserver(const struct optstruct *opt, const struct cfgstruct *copt, struct
44 44
     server.sin_port = htons(cfgopt(copt, "TCPSocket")->numarg);
45 45
 
46 46
 
47
-    if (taddr = cfgopt(copt, "TCPAddr"))
47
+    if((taddr = cfgopt(copt, "TCPAddr")))
48 48
     {
49 49
 	server.sin_addr.s_addr = inet_addr( taddr->strarg );
50 50
     }else
... ...
@@ -27,6 +27,7 @@
27 27
 #include "others.h"
28 28
 #include "shared.h"
29 29
 #include "defaults.h"
30
+#include "client.h"
30 31
 
31 32
 void help(void);
32 33
 
... ...
@@ -38,7 +38,6 @@ int client(const struct optstruct *opt)
38 38
 	int sockd, wsockd, loopw = 60, bread, port;
39 39
 	const char *clamav_conf = getargl(opt, "config-file");
40 40
 	FILE *fd;
41
-int bw;
42 41
 
43 42
     if(!clamav_conf)
44 43
 	clamav_conf = DEFAULT_CFG;
... ...
@@ -41,6 +41,8 @@
41 41
 #include "treewalk.h"
42 42
 #include "shared.h"
43 43
 #include "mbox.h"
44
+#include "str.h"
45
+#include "strrcpy.h"
44 46
 
45 47
 #ifdef C_LINUX
46 48
 dev_t procdev;
... ...
@@ -111,7 +113,10 @@ int scanmanager(const struct optstruct *opt)
111 111
     }
112 112
 
113 113
     /* build the proper trie */
114
-    cl_buildtrie(trie);
114
+    if((ret=cl_buildtrie(trie)) != 0) {
115
+	mprintf("@Database initialization error: %s\n", cl_strerror(ret));;
116
+	return 50;
117
+    }
115 118
 
116 119
     /* set (default) limits */
117 120
 
... ...
@@ -149,7 +154,16 @@ int scanmanager(const struct optstruct *opt)
149 149
 #endif
150 150
 
151 151
     /* check filetype */
152
-    if(!strcmp(opt->filename, "-")) { /* read data from stdin */
152
+    if(opt->filename == NULL || strlen(opt->filename) == 0) {
153
+
154
+	/* we need full path for some reasons (eg. archive handling) */
155
+	if(!getcwd(cwd, 200)) {
156
+	    mprintf("@Can't get absolute pathname of current working directory.\n");
157
+	    ret = 57;
158
+	} else
159
+	    ret = scandirs(cwd, trie, user, opt, limits);
160
+
161
+    } else if(!strcmp(opt->filename, "-")) { /* read data from stdin */
153 162
 	/*
154 163
 	 * njh@bandsman.co.uk: treat the input as a mailbox, the program
155 164
 	 * can then be used as a filter called when mail is received
... ...
@@ -212,60 +226,57 @@ int scanmanager(const struct optstruct *opt)
212 212
 	} else
213 213
 	    ret = checkstdin(trie, limits);
214 214
 
215
-    } else if(strlen(opt->filename) == 0) {
216
-
217
-	/* we need full path for some reasons (eg. archive handling) */
218
-	if(!getcwd(cwd, 200)) {
219
-	    mprintf("@Can't get absolute pathname of current working directory.\n");
220
-	    ret = 57;
221
-	} else
222
-	    ret = scandirs(cwd, trie, user, opt, limits);
223
-
224
-    } else if((fmodeint = fileinfo(opt->filename, 2)) == -1) {
225
-               mprintf("@Can't access file %s\n", opt->filename);
226
-               perror(opt->filename);
227
-               ret = 56;
228 215
     } else {
229
-	fmode = (mode_t) fmodeint;
230
-
231
-        if(compression && (opt->filename[0] != '/')) {
232
-	    /* we need to complete the path */
233
-            if(!getcwd(cwd, 200)) {
234
-		mprintf("@Can't get absolute pathname of current working directory.\n");
235
-                return 57;
236
-            } else {
237
-		fullpath = mcalloc(512, sizeof(char));
216
+	int x;
217
+	char *thefilename;
218
+	for (x=0; (thefilename = cli_strtok(opt->filename, x, "\t")) != NULL; x++) {
219
+	    if((fmodeint = fileinfo(thefilename, 2)) == -1) {
220
+		mprintf("@Can't access file %s\n", thefilename);
221
+		perror(thefilename);
222
+		ret = 56;
223
+	    } else {
224
+		fmode = (mode_t) fmodeint;
225
+
226
+		if(compression && (thefilename[0] != '/')) {
227
+		    /* we need to complete the path */
228
+		    if(!getcwd(cwd, 200)) {
229
+			mprintf("@Can't get absolute pathname of current working directory.\n");
230
+			return 57;
231
+		    } else {
232
+			fullpath = mcalloc(512, sizeof(char));
238 233
 #ifdef NO_SNPRINTF
239
-                sprintf(fullpath, "%s/%s", cwd, opt->filename);
234
+			sprintf(fullpath, "%s/%s", cwd, thefilename);
240 235
 #else
241
-                snprintf(fullpath, 512, "%s/%s", cwd, opt->filename);
236
+			snprintf(fullpath, 512, "%s/%s", cwd, thefilename);
242 237
 #endif
243
-                mprintf("*Full path: %s\n", fullpath);
244
-            }
245
-        } else
246
-	    fullpath = (char *) opt->filename;
238
+			mprintf("*Full path: %s\n", fullpath);
239
+		    }
240
+		} else
241
+		    fullpath = (char *) thefilename;
247 242
 
248
-        switch(fmode & S_IFMT) {
249
-	    case S_IFREG:
250
-		ret = scanfile(fullpath, trie, user, opt, limits);
251
-                break;
243
+		switch(fmode & S_IFMT) {
244
+		    case S_IFREG:
245
+			ret = scanfile(fullpath, trie, user, opt, limits);
246
+			break;
252 247
 
253
-            case S_IFDIR:
254
-		ret = scandirs(fullpath, trie, user, opt, limits);
255
-                break;
248
+		    case S_IFDIR:
249
+			ret = scandirs(fullpath, trie, user, opt, limits);
250
+			break;
256 251
 
257
-            default:
258
-                mprintf("@Not supported file type (%s)\n", opt->filename);
259
-                ret = 52;
260
-	}
252
+		    default:
253
+			mprintf("@Not supported file type (%s)\n", thefilename);
254
+			ret = 52;
255
+		}
261 256
 
262
-	if(compression && fullpath) {
263
-	    free(fullpath);
264
-	    fullpath = NULL;
257
+		if(compression && thefilename[0] != '/') {
258
+		    free(fullpath);
259
+		    fullpath = NULL;
260
+		}
261
+	    }
262
+	    free(thefilename);
265 263
 	}
266 264
     }
267 265
 
268
-
269 266
     /* free the trie */
270 267
     cl_freetrie(trie);
271 268
 
... ...
@@ -127,16 +127,14 @@ int main(int argc, char **argv)
127 127
         for(i=optind; i<argc; i++) {
128 128
 	    strncat(opt->filename, argv[i], strlen(argv[i]));
129 129
 	    if(i != argc-1)
130
-		strncat(opt->filename, " ", 1);
130
+		strncat(opt->filename, "\t", 1);
131 131
 	}
132 132
 
133
-    } else
134
-	/* FIXME !!! Without this, we have segfault */
135
-	opt->filename=(char*)mcalloc(1, sizeof(char));
136
-
137
-
133
+    }
138 134
     clamscan(opt);
139 135
 
136
+    free_opt(opt);
137
+
140 138
     return(0);
141 139
 }
142 140
 
... ...
@@ -323,10 +321,9 @@ void free_opt(struct optstruct *opt)
323 323
 {
324 324
 	struct optnode *handler, *prev;
325 325
 
326
-    if(!opt || !opt->optlist)
326
+    if(!opt)
327 327
 	return;
328 328
 
329
-    mprintf("*Freeing option list... ");
330 329
     handler = opt->optlist;
331 330
 
332 331
     while(handler != NULL) {
... ...
@@ -338,7 +335,7 @@ void free_opt(struct optstruct *opt)
338 338
 	free(prev);
339 339
     }
340 340
 
341
-    free(opt->filename);
341
+    if (opt->filename)
342
+    	free(opt->filename);
342 343
     free(opt);
343
-    mprintf("*done\n");
344 344
 }
... ...
@@ -8619,7 +8619,8 @@ fi
8619 8619
 fi
8620 8620
 
8621 8621
 
8622
-for ac_func in setsid
8622
+
8623
+for ac_func in setsid memcpy
8623 8624
 do
8624 8625
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
8625 8626
 echo "$as_me:$LINENO: checking for $ac_func" >&5
... ...
@@ -9130,11 +9131,6 @@ fi
9130 9130
 if test "${enable_pthreads+set}" = set; then
9131 9131
   enableval="$enable_pthreads"
9132 9132
   have_pthreads=no
9133
-else
9134
-  cat >>confdefs.h <<\_ACEOF
9135
-#define _REENTRANT 1
9136
-_ACEOF
9137
-
9138 9133
 fi;
9139 9134
 
9140 9135
 # Check whether --enable-cr or --disable-cr was given.
... ...
@@ -9335,6 +9331,10 @@ _ACEOF
9335 9335
 #define CL_THREAD_SAFE 1
9336 9336
 _ACEOF
9337 9337
 
9338
+	cat >>confdefs.h <<\_ACEOF
9339
+#define _REENTRANT 1
9340
+_ACEOF
9341
+
9338 9342
 	CLAMD_LIBS="-lpthread"
9339 9343
 	if test "$want_clamuko" = "yes"; then
9340 9344
 	    cat >>confdefs.h <<\_ACEOF
... ...
@@ -9362,6 +9362,10 @@ _ACEOF
9362 9362
 #define CL_THREAD_SAFE 1
9363 9363
 _ACEOF
9364 9364
 
9365
+	cat >>confdefs.h <<\_ACEOF
9366
+#define _REENTRANT 1
9367
+_ACEOF
9368
+
9365 9369
     fi
9366 9370
     ;;
9367 9371
 solaris*)
... ...
@@ -9374,6 +9378,10 @@ solaris*)
9374 9374
 #define CL_THREAD_SAFE 1
9375 9375
 _ACEOF
9376 9376
 
9377
+	cat >>confdefs.h <<\_ACEOF
9378
+#define _REENTRANT 1
9379
+_ACEOF
9380
+
9377 9381
     fi
9378 9382
     cat >>confdefs.h <<\_ACEOF
9379 9383
 #define C_SOLARIS 1
... ...
@@ -9389,6 +9397,10 @@ freebsd*)
9389 9389
 #define CL_THREAD_SAFE 1
9390 9390
 _ACEOF
9391 9391
 
9392
+	cat >>confdefs.h <<\_ACEOF
9393
+#define _REENTRANT 1
9394
+_ACEOF
9395
+
9392 9396
     fi
9393 9397
     cat >>confdefs.h <<\_ACEOF
9394 9398
 #define C_BSD 1
... ...
@@ -9408,6 +9420,10 @@ openbsd*)
9408 9408
 #define CL_THREAD_SAFE 1
9409 9409
 _ACEOF
9410 9410
 
9411
+	cat >>confdefs.h <<\_ACEOF
9412
+#define _REENTRANT 1
9413
+_ACEOF
9414
+
9411 9415
     fi
9412 9416
     cat >>confdefs.h <<\_ACEOF
9413 9417
 #define C_BSD 1
... ...
@@ -9469,6 +9485,10 @@ hpux*)
9469 9469
 #define CL_THREAD_SAFE 1
9470 9470
 _ACEOF
9471 9471
 
9472
+	cat >>confdefs.h <<\_ACEOF
9473
+#define _REENTRANT 1
9474
+_ACEOF
9475
+
9472 9476
     fi
9473 9477
     cat >>confdefs.h <<\_ACEOF
9474 9478
 #define C_HPUX 1
... ...
@@ -9484,6 +9504,10 @@ aix*)
9484 9484
 #define CL_THREAD_SAFE 1
9485 9485
 _ACEOF
9486 9486
 
9487
+	cat >>confdefs.h <<\_ACEOF
9488
+#define _REENTRANT 1
9489
+_ACEOF
9490
+
9487 9491
     fi
9488 9492
     cat >>confdefs.h <<\_ACEOF
9489 9493
 #define C_AIX 1
... ...
@@ -9499,6 +9523,10 @@ irix*)
9499 9499
 #define CL_THREAD_SAFE 1
9500 9500
 _ACEOF
9501 9501
 
9502
+	cat >>confdefs.h <<\_ACEOF
9503
+#define _REENTRANT 1
9504
+_ACEOF
9505
+
9502 9506
     fi
9503 9507
     cat >>confdefs.h <<\_ACEOF
9504 9508
 #define C_IRIX 1
... ...
@@ -74,7 +74,7 @@ then
74 74
     AC_CHECK_LIB(bz2, bzReadOpen, AC_DEFINE(NOBZ2PREFIX),)
75 75
 fi
76 76
 
77
-AC_CHECK_FUNCS(setsid)
77
+AC_CHECK_FUNCS(setsid memcpy)
78 78
 AC_FUNC_SETPGRP
79 79
 
80 80
 have_milter="no"
... ...
@@ -101,7 +101,7 @@ dnl AC_CHECK_LIB(c, mkstemp, AC_DEFINE(HAVE_MKSTEMP),)
101 101
 
102 102
 AC_ARG_ENABLE(pthreads,
103 103
 [  --disable-pthreads      Disable POSIX threads support],
104
-have_pthreads=no, AC_DEFINE(_REENTRANT))
104
+have_pthreads=no, )
105 105
 
106 106
 AC_ARG_ENABLE(cr,
107 107
 [  --disable-cr      Don't link with C reentrant library (BSD) ],
... ...
@@ -220,6 +220,7 @@ linux*)
220 220
 	LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lpthread"
221 221
 	TH_SAFE="-thread-safe"
222 222
 	AC_DEFINE(CL_THREAD_SAFE)
223
+	AC_DEFINE(_REENTRANT)
223 224
 	CLAMD_LIBS="-lpthread"
224 225
 	if test "$want_clamuko" = "yes"; then
225 226
 	    AC_DEFINE(CLAMUKO)
... ...
@@ -239,6 +240,7 @@ cygwin*)
239 239
 	LIBCLAMAV_LIBS="$LIBCLAMAV_LIBS -lpthread"
240 240
 	TH_SAFE="-thread-safe"
241 241
 	AC_DEFINE(CL_THREAD_SAFE)
242
+	AC_DEFINE(_REENTRANT)
242 243
     fi
243 244
     ;;
244 245
 solaris*)
... ...
@@ -248,6 +250,7 @@ solaris*)
248 248
 	CLAMD_LIBS="-lpthread -lsocket -lnsl -lresolv"
249 249
 	TH_SAFE="-thread-safe"
250 250
 	AC_DEFINE(CL_THREAD_SAFE)
251
+	AC_DEFINE(_REENTRANT)
251 252
     fi
252 253
     AC_DEFINE(C_SOLARIS)
253 254
     ;;
... ...
@@ -257,6 +260,7 @@ freebsd*)
257 257
 	CLAMD_LIBS="-pthread -lc_r"
258 258
 	TH_SAFE="-thread-safe"
259 259
 	AC_DEFINE(CL_THREAD_SAFE)
260
+	AC_DEFINE(_REENTRANT)
260 261
     fi
261 262
     AC_DEFINE(C_BSD)
262 263
     ;;
... ...
@@ -270,6 +274,7 @@ openbsd*)
270 270
 	fi
271 271
 	TH_SAFE="-thread-safe"
272 272
 	AC_DEFINE(CL_THREAD_SAFE)
273
+	AC_DEFINE(_REENTRANT)
273 274
     fi
274 275
     AC_DEFINE(C_BSD)
275 276
     ;;
... ...
@@ -307,6 +312,7 @@ hpux*)
307 307
 	CLAMD_LIBS="-lpthread"
308 308
 	TH_SAFE="-thread-safe"
309 309
 	AC_DEFINE(CL_THREAD_SAFE)
310
+	AC_DEFINE(_REENTRANT)
310 311
     fi
311 312
     AC_DEFINE(C_HPUX)
312 313
     ;;
... ...
@@ -316,6 +322,7 @@ aix*)
316 316
 	CLAMD_LIBS="-lpthread"
317 317
 	TH_SAFE="-thread-safe"
318 318
 	AC_DEFINE(CL_THREAD_SAFE)
319
+	AC_DEFINE(_REENTRANT)
319 320
     fi
320 321
     AC_DEFINE(C_AIX)
321 322
     ;;
... ...
@@ -325,6 +332,7 @@ irix*)
325 325
 	CLAMD_LIBS="-lpthread"
326 326
 	TH_SAFE="-thread-safe"
327 327
 	AC_DEFINE(CL_THREAD_SAFE)
328
+	AC_DEFINE(_REENTRANT)
328 329
     fi
329 330
     AC_DEFINE(C_IRIX)
330 331
     AC_DEFINE(NO_SNPRINTF)
... ...
@@ -52,7 +52,10 @@ int main(int argc, char **argv)
52 52
     printf("Loaded %d signatures.\n", no);
53 53
 
54 54
     /* build the trie */
55
-    cl_buildtrie(root);
55
+    if((ret = cl_buildtrie(root)) != 0) {
56
+	printf("Database initialization error: %s\n", cl_strerror(ret));;
57
+	exit(2);
58
+    }
56 59
 
57 60
     if((fd = open(argv[1], O_RDONLY)) == -1) {
58 61
 	printf("Can't open file %s\n", argv[1]);
... ...
@@ -39,7 +39,7 @@
39 39
 
40 40
 #define TIMEOUT 1200
41 41
 
42
-void freshclam(struct optstruct *opt)
42
+int freshclam(struct optstruct *opt)
43 43
 {
44 44
 	int ret;
45 45
 	char *newdir;
... ...
@@ -154,8 +154,7 @@ void freshclam(struct optstruct *opt)
154 154
 	if(ret > 1)
155 155
 	    system(getargl(opt, "on-error-execute"));
156 156
 
157
-    exit(ret);
158
-
157
+    return(ret);
159 158
 }
160 159
 
161 160
 void d_timeout(int sig)
... ...
@@ -103,13 +103,12 @@ int main(int argc, char **argv)
103 103
 		strncat(opt->filename, " ", 1);
104 104
 	}
105 105
 
106
-    } else
107
-	/* FIXME !!! Without this, we have segfault */
108
-	opt->filename=(char*)mcalloc(1, sizeof(char));
109
-
106
+    }
110 107
 
111 108
     freshclam(opt);
112 109
 
110
+    free_opt(opt);
111
+
113 112
     return(0);
114 113
 }
115 114
 
... ...
@@ -216,10 +215,10 @@ void free_opt(struct optstruct *opt)
216 216
 {
217 217
 	struct optnode *handler, *prev;
218 218
 
219
-    if(!opt || !opt->optlist)
219
+    if(!opt)
220 220
 	return;
221 221
 
222
-    mprintf("*Freeing option list... ");
222
+    mprintf("*Freeing option list...");
223 223
     handler = opt->optlist;
224 224
 
225 225
     while(handler != NULL) {
... ...
@@ -231,7 +230,8 @@ void free_opt(struct optstruct *opt)
231 231
 	free(prev);
232 232
     }
233 233
 
234
-    free(opt->filename);
234
+    if (opt->filename)
235
+	free(opt->filename);
235 236
     free(opt);
236 237
     mprintf("*done\n");
237 238
 }
... ...
@@ -136,7 +136,7 @@ extern int cl_statfree(struct cl_stat *dbstat);
136 136
 extern void cl_debug(void);
137 137
 
138 138
 /* build a trie */
139
-extern void cl_buildtrie(struct cl_node *root);
139
+extern int cl_buildtrie(struct cl_node *root);
140 140
 
141 141
 extern void cl_freetrie(struct cl_node *root);
142 142
 
... ...
@@ -162,13 +162,13 @@ struct cl_cvd *cl_cvdparse(const char *head)
162 162
 
163 163
     cvd = (struct cl_cvd *) cli_calloc(1, sizeof(struct cl_cvd));
164 164
 
165
-    if(!(cvd->time = cli_tok(head, 2, ':'))) {
165
+    if(!(cvd->time = cli_strtok(head, 1, ":"))) {
166 166
 	cli_errmsg("CVD -> Can't extract time from header.\n");
167 167
 	free(cvd);
168 168
 	return NULL;
169 169
     }
170 170
 
171
-    if(!(pt = cli_tok(head, 3, ':'))) {
171
+    if(!(pt = cli_strtok(head, 2, ":"))) {
172 172
 	cli_errmsg("CVD -> Can't extract version from header.\n");
173 173
 	free(cvd->time);
174 174
 	free(cvd);
... ...
@@ -177,7 +177,7 @@ struct cl_cvd *cl_cvdparse(const char *head)
177 177
     cvd->version = atoi(pt);
178 178
     free(pt);
179 179
 
180
-    if(!(pt = cli_tok(head, 4, ':'))) {
180
+    if(!(pt = cli_strtok(head, 3, ":"))) {
181 181
 	cli_errmsg("CVD -> Can't extract signature number from header.\n");
182 182
 	free(cvd->time);
183 183
 	free(cvd);
... ...
@@ -186,7 +186,7 @@ struct cl_cvd *cl_cvdparse(const char *head)
186 186
     cvd->sigs = atoi(pt);
187 187
     free(pt);
188 188
 
189
-    if(!(pt = cli_tok(head, 5, ':'))) {
189
+    if(!(pt = cli_strtok(head, 4, ":"))) {
190 190
 	cli_errmsg("CVD -> Can't extract functionality level from header.\n");
191 191
 	free(cvd->time);
192 192
 	free(cvd);
... ...
@@ -195,14 +195,14 @@ struct cl_cvd *cl_cvdparse(const char *head)
195 195
     cvd->fl = (short int) atoi(pt);
196 196
     free(pt);
197 197
 
198
-    if(!(cvd->md5 = cli_tok(head, 6, ':'))) {
198
+    if(!(cvd->md5 = cli_strtok(head, 5, ":"))) {
199 199
 	cli_errmsg("CVD -> Can't extract MD5 checksum from header.\n");
200 200
 	free(cvd->time);
201 201
 	free(cvd);
202 202
 	return NULL;
203 203
     }
204 204
 
205
-    if(!(cvd->dsig = cli_tok(head, 7, ':'))) {
205
+    if(!(cvd->dsig = cli_strtok(head, 6, ":"))) {
206 206
 	cli_errmsg("CVD -> Can't extract digital signature from header.\n");
207 207
 	free(cvd->time);
208 208
 	free(cvd->md5);
... ...
@@ -210,7 +210,7 @@ struct cl_cvd *cl_cvdparse(const char *head)
210 210
 	return NULL;
211 211
     }
212 212
 
213
-    if(!(cvd->builder = cli_tok(head, 8, ':'))) {
213
+    if(!(cvd->builder = cli_strtok(head, 7, ":"))) {
214 214
 	cli_errmsg("CVD -> Can't extract builder name from header.\n");
215 215
 	free(cvd->time);
216 216
 	free(cvd->md5);
... ...
@@ -23,5 +23,6 @@
23 23
 #include "clamav.h"
24 24
 
25 25
 int cli_cvdload(FILE *fd, struct cl_node **root, int *virnum);
26
+int cli_untgz(int fd, const char *destdir);
26 27
 
27 28
 #endif
... ...
@@ -75,19 +75,20 @@ int cli_addpatt(struct cl_node *root, struct cli_patt *pattern)
75 75
     return 0;
76 76
 }
77 77
 
78
-void cli_enqueue(struct nodelist **bfs, struct cl_node *n)
78
+int cli_enqueue(struct nodelist **bfs, struct cl_node *n)
79 79
 {
80 80
 	struct nodelist *new;
81 81
 
82 82
     new = (struct nodelist *) cli_calloc(1, sizeof(struct nodelist));
83 83
     if (new == NULL) {
84 84
 	cli_dbgmsg("Unable to allocate node list (%d)\n", sizeof(struct nodelist));
85
-	return; /* FIXME: should return CL_EMEM */
85
+	return CL_EMEM;
86 86
     }
87 87
 
88 88
     new->next = *bfs;
89 89
     new->node = n;
90 90
     *bfs = new;
91
+    return 0;
91 92
 }
92 93
 
93 94
 struct cl_node *cli_dequeue(struct nodelist **bfs)
... ...
@@ -116,15 +117,17 @@ struct cl_node *cli_dequeue(struct nodelist **bfs)
116 116
     }
117 117
 }
118 118
 
119
-void cli_maketrans(struct cl_node *root)
119
+int cli_maketrans(struct cl_node *root)
120 120
 {
121 121
 	struct nodelist *bfs = NULL;
122 122
 	struct cl_node *child, *node;
123
-	int i;
123
+	int i, ret;
124 124
 
125 125
 
126 126
     root->fail = NULL;
127
-    cli_enqueue(&bfs, root);
127
+    if((ret = cli_enqueue(&bfs, root)) != 0) {
128
+	return ret;
129
+    }
128 130
 
129 131
     while((node = cli_dequeue(&bfs))) {
130 132
 	if(node->islast)
... ...
@@ -143,15 +146,18 @@ void cli_maketrans(struct cl_node *root)
143 143
 		else
144 144
 		    child->fail = root;
145 145
 
146
-		cli_enqueue(&bfs, child);
146
+		if((ret = cli_enqueue(&bfs, child)) != 0) {
147
+		    return ret;
148
+		}
147 149
 	    }
148 150
 	}
149 151
     }
152
+    return 0;
150 153
 }
151 154
 
152
-void cl_buildtrie(struct cl_node *root)
155
+int cl_buildtrie(struct cl_node *root)
153 156
 {
154
-    cli_maketrans(root);
157
+    return cli_maketrans(root);
155 158
 }
156 159
 
157 160
 void cli_freepatt(struct cli_patt *list)
... ...
@@ -38,11 +38,6 @@
38 38
 #include "others.h"
39 39
 #include "md5.h"
40 40
 
41
-#ifdef CL_THREAD_SAFE
42
-# include <pthread.h>
43
-pthread_mutex_t cli_rand_mutex = PTHREAD_MUTEX_INITIALIZER;
44
-#endif
45
-
46 41
 int cli_debug_flag = 0;
47 42
 
48 43
 void cli_warnmsg(const char *str, ...)
... ...
@@ -255,23 +250,15 @@ unsigned int cl_rndnum(unsigned int max)
255 255
 
256 256
 unsigned int cl_rndnum(unsigned int max)
257 257
 {
258
-	static FILE *fd = NULL;
258
+	FILE *fd;
259 259
 	unsigned int generated;
260 260
 	char *byte;
261 261
 	int size;
262 262
 
263
-#ifdef CL_THREAD_SAFE
264
-    pthread_mutex_lock(&cli_rand_mutex);
265
-#endif
266 263
 
267
-    if(fd == NULL) {
268
-	if((fd = fopen("/dev/urandom", "rb")) == NULL) {
269
-	    cli_errmsg("!Can't open /dev/urandom.\n");
270
-#ifdef CL_THREAD_SAFE
271
-	    pthread_mutex_unlock(&cli_rand_mutex);
272
-#endif
273
-	    return -1;
274
-	}
264
+    if((fd = fopen("/dev/urandom", "rb")) == NULL) {
265
+	cli_errmsg("!Can't open /dev/urandom.\n");
266
+	return -1;
275 267
     }
276 268
 
277 269
     byte = (char *) &generated;
... ...
@@ -283,9 +270,7 @@ unsigned int cl_rndnum(unsigned int max)
283 283
 	byte += bread;
284 284
     } while(size > 0);
285 285
 
286
-#ifdef CL_THREAD_SAFE
287
-    pthread_mutex_unlock(&cli_rand_mutex);
288
-#endif
286
+    fclose(fd);
289 287
     return generated % max;
290 288
 }
291 289
 #endif
... ...
@@ -304,6 +289,10 @@ char *cl_gentemp(const char *dir)
304 304
 	mdir = (char *) dir;
305 305
 
306 306
     name = (char*) cli_calloc(strlen(mdir) + 1 + 16 + 1, sizeof(char));
307
+    if(name == NULL) {
308
+	cli_dbgmsg("cl_gentemp('%s'): out of memory\n", dir);
309
+	return NULL;
310
+    }
307 311
     cnt += sprintf(name, "%s/", mdir);
308 312
 
309 313
     do {
... ...
@@ -149,9 +149,9 @@ int cl_loaddb(const char *filename, struct cl_node **root, int *virnum)
149 149
 
150 150
 	    if(parts) /* there's always one part more */
151 151
 		parts++;
152
-	    for(i = 1; i <= parts; i++) {
153
-		if((pt2 = cli_tok(pt, i, '*')) == NULL) {
154
-		    cli_errmsg("Can't extract part %d of partial signature in line %d\n", i, line);
152
+	    for(i = 0; i < parts; i++) {
153
+		if((pt2 = cli_strtok(pt, i, "*")) == NULL) {
154
+		    cli_errmsg("Can't extract part %d of partial signature in line %d\n", i + 1, line);
155 155
 		    return CL_EMALFDB;
156 156
 		}
157 157
 
... ...
@@ -128,37 +128,46 @@ void cli_chomp(char *string)
128 128
 	string[l - 1] = 0;
129 129
 }
130 130
 
131
-char *cli_tok(const char *line, int field, char delimiter)
131
+/*
132
+ * char *cli_strok(const char *line, int fieldno, char *delim)
133
+ * Return a copy of field <fieldno> from the string <line>, where
134
+ * fields are delimited by any char from <delim>, or NULL if <line>
135
+ * doesn't have <fieldno> fields or not enough memory is available.
136
+ * The caller has to free() the result afterwards.
137
+ */
138
+char *cli_strtok(const char *line, int fieldno, char *delim)
132 139
 {
133
-        int length, counter = 0, i, j = 0;
134
-        char *buffer;
135
-
136
-
137
-    if(!(length = strlen(line)))
138
-	return NULL;
140
+    int counter = 0, i, j;
141
+    char *buffer = NULL;
139 142
 
140
-    buffer = (char *) cli_calloc(length, sizeof(char));
141 143
 
142
-    for(i = 0; i < length; i++) {
143
-        if(line[i] == delimiter) {
144
-            counter++;
145
-            if(counter == field) {
146
-		break;
147
-	    } else {
148
-		memset(buffer, 0, length);
149
-		j = 0;
144
+    /* step to arg # <fieldno> */
145
+    for (i=0; line[i] && counter != fieldno; i++) {
146
+	if (strchr(delim, line[i])) {
147
+	    counter++;
148
+	    while(line[i+1] && strchr(delim, line[i+1])) {
149
+		i++;
150 150
 	    }
151
-        } else {
152
-            buffer[j++] = line[i];
153
-        }
151
+	}
152
+    }
153
+    if (!line[i]) {
154
+	/* end of buffer before field reached */
155
+	return NULL;
154 156
     }
155 157
 
156
-    cli_chomp(buffer); /* preventive */
157
-
158
-    if((length = strlen(buffer)))
159
-	return (char *) cli_realloc(buffer, strlen(buffer) + 1);
160
-    else {
161
-	free(buffer);
158
+    for (j=i; line[j]; j++) {
159
+	if (strchr(delim, line[j])) {
160
+	    break;
161
+	}
162
+    }
163
+    if (i == j) {
162 164
 	return NULL;
163 165
     }
166
+    buffer = malloc(j-i+1);
167
+    strncpy(buffer, line+i, j-i);
168
+    buffer[j-i] = '\0';
169
+
170
+    return buffer;
164 171
 }
172
+
173
+
... ...
@@ -21,6 +21,6 @@
21 21
 
22 22
 int cli_strbcasestr(const char *haystack, const char *needle);
23 23
 void cli_chomp(char *string);
24
-char *cli_tok(const char *line, int field, char delimiter);
24
+char *cli_strtok(const char *line, int field, char *delim);
25 25
 
26 26
 #endif
... ...
@@ -89,12 +89,13 @@ zzip_file_saveoffset(ZZIP_FILE * fp)
89 89
     return 0;
90 90
 }
91 91
 
92
-# ifndef ZZIP_CHECK_BACKSLASH_DIRSEPARATOR           /* NOTE: also default */
93
-# define ZZIP_CHECK_BACKSLASH_DIRSEPARATOR 0         /* to "NO" on win32 ! */
94
-# endif
95 92
 
96 93
 # if !defined strcasecmp && !defined ZZIP_HAVE_STRCASECMP
97 94
 # define ZZIP_CHECK_BACKSLASH_DIRSEPARATOR 1
95
+# else
96
+# ifndef ZZIP_CHECK_BACKSLASH_DIRSEPARATOR           /* NOTE: also default */
97
+# define ZZIP_CHECK_BACKSLASH_DIRSEPARATOR 0         /* to "NO" on win32 ! */
98
+# endif
98 99
 # endif
99 100
 
100 101
 #if ! ZZIP_CHECK_BACKSLASH_DIRSEPARATOR+0
... ...
@@ -223,7 +223,7 @@ __zzip_find_disk_trailer(int fd, zzip_off_t filesize,
223 223
 	    mapped = fd_map; offset = mapoff;
224 224
 	    HINT3("mapped *%p len=%li", fd_map, (long) maplen);
225 225
         } else */ {
226
-        non_mmap:
226
+        /* non_mmap: */
227 227
 	    fd_map = 0; /* have no mmap */
228 228
 	    {
229 229
 		zzip_off_t pagesize = ZZIP_BUFSIZ;
... ...
@@ -398,7 +398,8 @@ __zzip_parse_root_directory(int fd,
398 398
         hdr->d_usize = ZZIP_GET32(d->z_usize); 
399 399
         hdr->d_off   = ZZIP_GET32(d->z_off);
400 400
         hdr->d_compr = (uint8_t)ZZIP_GET16(d->z_compr);
401
-        if (hdr->d_compr > 255) hdr->d_compr = 255;
401
+        /* bull: hdr->d_compr is uint8_t
402
+	 * if (hdr->d_compr > 255) hdr->d_compr = 255; */
402 403
 
403 404
 	if (offset+sizeof(*d) + u_namlen > u_rootsize)
404 405
 	{ /*FAIL2("%i's name stretches beyond root directory", entries);*/ break;}
... ...
@@ -31,11 +31,15 @@
31 31
 #include <netinet/in.h>
32 32
 #include <arpa/inet.h>
33 33
 #include <clamav.h>
34
+#include <sys/wait.h>
34 35
 
35 36
 #include "options.h"
36 37
 #include "others.h"
37 38
 #include "shared.h"
38 39
 #include "strings.h"
40
+#include "md5.h"
41
+#include "cvd.h"
42
+#include "str.h"
39 43
 
40 44
 #define LINE 1024
41 45
 
... ...
@@ -45,6 +49,8 @@
45 45
 void help(void);
46 46
 char *getdsig(const char *host, const char *user, const char *data);
47 47
 void cvdinfo(struct optstruct *opt);
48
+int build(struct optstruct *opt);
49
+int unpack(struct optstruct *opt);
48 50
 
49 51
 int scanfile(const char *cmd, const char *str, const char *file)
50 52
 {
... ...
@@ -119,7 +125,7 @@ char *cut(const char *file, long int start, long int end)
119 119
 char *change(const char *file, long int x)
120 120
 {
121 121
 	char *fname = NULL, buffer[FILEBUFF];
122
-	int bytes, size, sum, ch;
122
+	int bytes, ch;
123 123
 	FILE *rd, *wd;
124 124
 
125 125
 
... ...
@@ -210,7 +216,7 @@ void sigtool(struct optstruct *opt)
210 210
 	cvdinfo(opt);
211 211
 
212 212
     } else {
213
-	    int jmp, lastjmp, start, end, found = 0, exec = 0, pos, filesize,
213
+	    int jmp, lastjmp, end, found = 0, exec = 0, pos, filesize,
214 214
 		maxsize = 0, ret;
215 215
 	    char *c, *s, *f, *tmp, *signame, *bsigname, *f2;
216 216
 	    FILE *fd, *wd;
... ...
@@ -659,6 +665,7 @@ int build(struct optstruct *opt)
659 659
     mprintf("Database %s created.\n", pt);
660 660
 
661 661
     /* try to load final cvd */
662
+    return 0;
662 663
 }
663 664
 
664 665
 void cvdinfo(struct optstruct *opt)
... ...
@@ -725,7 +732,6 @@ char *getdsig(const char *host, const char *user, const char *data)
725 725
 {
726 726
 	char buff[300], cmd[100], *pass, *pt;
727 727
         struct sockaddr_in server;
728
-	struct cfgstruct *copt, *cpt;
729 728
 	int sockd, bread, len;
730 729
 
731 730
 
... ...
@@ -771,14 +777,16 @@ char *getdsig(const char *host, const char *user, const char *data)
771 771
     memset(pass, 0, strlen(pass));
772 772
 
773 773
     memset(buff, 0, sizeof(buff));
774
-    if((bread = read(sockd, buff, sizeof(buff))) > 0)
774
+    if((bread = read(sockd, buff, sizeof(buff))) > 0) {
775 775
 	if(!strstr(buff, "Signature:")) {
776 776
 	    mprintf("!Signature generation error.\n");
777 777
 	    mprintf("ClamAV SDaemon: %s.\n", buff);
778 778
 	    close(sockd);
779 779
 	    return NULL;
780
-	} else
780
+	} else {
781 781
 	    mprintf("Signature received (length = %d).\n", strlen(buff) - 10);
782
+	}
783
+    }
782 784
 
783 785
     close(sockd);
784 786
     pt = buff;
... ...
@@ -789,7 +797,6 @@ char *getdsig(const char *host, const char *user, const char *data)
789 789
 int unpack(struct optstruct *opt)
790 790
 {
791 791
 	FILE *fd;
792
-	struct cl_cvd *cvd;
793 792
 	char *name;
794 793
 
795 794
     if(optl(opt, "unpack-current")) {