Browse code

libclamav, shared: minor cleanups; fix handling of long file names (bb#1349)

git-svn: trunk@4670

Tomasz Kojm authored on 2009/02/04 03:47:18
Showing 11 changed files
... ...
@@ -1,3 +1,7 @@
1
+Tue Feb  3 20:11:07 CET 2009 (tk)
2
+---------------------------------
3
+ * libclamav, shared: minor cleanups; fix handling of long file names (bb#1349)
4
+
1 5
 Fri Jan 30 09:13:15 CET 2009 (tk)
2 6
 ---------------------------------
3 7
  * shared/optparser.c: improve handling of short switches (bb#1374)
... ...
@@ -1221,7 +1221,7 @@ static int chdir_tmp(const char *dbname, const char *tmpdir)
1221 1221
 	    return -1;
1222 1222
 	}
1223 1223
 
1224
-	if(cvd_unpack(cvdfile, tmpdir) == -1) {
1224
+	if(cli_cvdunpack(cvdfile, tmpdir) == -1) {
1225 1225
 	    logg("!chdir_tmp: Can't unpack %s into %s\n", cvdfile, tmpdir);
1226 1226
 	    cli_rmdirs(tmpdir);
1227 1227
 	    return -1;
... ...
@@ -44,7 +44,11 @@
44 44
 
45 45
 #define TAR_BLOCKSIZE 512
46 46
 
47
-int cli_untgz(int fd, const char *destdir)
47
+#ifndef	O_BINARY
48
+#define	O_BINARY	0
49
+#endif
50
+
51
+static int cli_untgz(int fd, const char *destdir)
48 52
 {
49 53
 	char *path, osize[13], name[101], type;
50 54
 	char block[TAR_BLOCKSIZE];
... ...
@@ -576,3 +580,22 @@ int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigne
576 576
 	return ret;
577 577
     }
578 578
 }
579
+
580
+int cli_cvdunpack(const char *file, const char *dir)
581
+{
582
+	int fd, ret;
583
+
584
+
585
+    fd = open(file, O_RDONLY|O_BINARY);
586
+    if(fd == -1)
587
+	return -1;
588
+
589
+    if(lseek(fd, 512, SEEK_SET) < 0) {
590
+	close(fd);
591
+	return -1;
592
+    }
593
+
594
+    ret = cli_untgz(fd, dir);
595
+    close(fd);
596
+    return ret;
597
+}
... ...
@@ -32,6 +32,6 @@ struct cli_dbio {
32 32
 };
33 33
 
34 34
 int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int daily, unsigned int options, unsigned int cld);
35
-int cli_untgz(int fd, const char *destdir);
35
+int cli_cvdunpack(const char *file, const char *dir);
36 36
 
37 37
 #endif
... ...
@@ -28,7 +28,7 @@ CLAMAV_PUBLIC {
28 28
 CLAMAV_PRIVATE {
29 29
   global:
30 30
     cli_strtok;
31
-    cli_untgz;
31
+    cli_cvdunpack;
32 32
     cli_regcomp;
33 33
     cli_regexec;
34 34
     cli_regfree;
... ...
@@ -124,6 +124,7 @@ CLAMAV_PRIVATE {
124 124
     mp_read_radix;
125 125
     mp_clear;
126 126
     cli_versig;
127
+    cli_filecopy;
127 128
   local:
128 129
     *;
129 130
 };
... ...
@@ -774,99 +774,6 @@ int cli_rmdirs(const char *dirname)
774 774
 }
775 775
 #endif
776 776
 
777
-/* Function: readn
778
-        Try hard to read the requested number of bytes
779
-*/
780
-int cli_readn(int fd, void *buff, unsigned int count)
781
-{
782
-        int retval;
783
-        unsigned int todo;
784
-        unsigned char *current;
785
-
786
-
787
-        todo = count;
788
-        current = (unsigned char *) buff;
789
-
790
-        do {
791
-                retval = read(fd, current, todo);
792
-                if (retval == 0) {
793
-                        return (count - todo);
794
-                }
795
-                if (retval < 0) {
796
-			if (errno == EINTR) {
797
-				continue;
798
-			}
799
-			cli_errmsg("cli_readn: read error: %s\n", strerror(errno));
800
-                        return -1;
801
-                }
802
-                todo -= retval;
803
-                current += retval;
804
-        } while (todo > 0);
805
-
806
-
807
-        return count;
808
-}
809
-
810
-/* Function: writen
811
-        Try hard to write the specified number of bytes
812
-*/
813
-int cli_writen(int fd, const void *buff, unsigned int count)
814
-{
815
-        int retval;
816
-        unsigned int todo;
817
-        const unsigned char *current;
818
-
819
-
820
-        todo = count;
821
-        current = (const unsigned char *) buff;
822
-
823
-        do {
824
-                retval = write(fd, current, todo);
825
-                if (retval < 0) {
826
-			if (errno == EINTR) {
827
-				continue;
828
-			}
829
-			cli_errmsg("cli_writen: write error: %s\n", strerror(errno));
830
-                        return -1;
831
-                }
832
-                todo -= retval;
833
-                current += retval;
834
-        } while (todo > 0);
835
-
836
-
837
-        return count;
838
-}
839
-
840
-int cli_filecopy(const char *src, const char *dest)
841
-{
842
-	char *buffer;
843
-	int s, d, bytes;
844
-
845
-
846
-    if((s = open(src, O_RDONLY|O_BINARY)) == -1)
847
-	return -1;
848
-
849
-    if((d = open(dest, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, S_IRWXU)) == -1) {
850
-	close(s);
851
-	return -1;
852
-    }
853
-
854
-    if(!(buffer = cli_malloc(FILEBUFF))) {
855
-	close(s);
856
-	close(d);
857
-	return -1;
858
-    }
859
-
860
-    while((bytes = cli_readn(s, buffer, FILEBUFF)) > 0)
861
-	cli_writen(d, buffer, bytes);
862
-
863
-    free(buffer);
864
-    close(s);
865
-
866
-    return close(d);
867
-}
868
-
869
-
870 777
 /* Implement a generic bitset, trog@clamav.net */
871 778
 
872 779
 #define BITS_PER_CHAR (8)
... ...
@@ -66,6 +66,10 @@
66 66
 #include "ltdl.h"
67 67
 #include "matcher-ac.h"
68 68
 
69
+#ifndef	O_BINARY
70
+#define	O_BINARY	0
71
+#endif
72
+
69 73
 #ifdef CL_THREAD_SAFE
70 74
 #  include <pthread.h>
71 75
 
... ...
@@ -273,3 +277,94 @@ const char* cli_ctime(const time_t *timep, char *buf, const size_t bufsize)
273 273
 	return ret;
274 274
 }
275 275
 
276
+/* Function: readn
277
+        Try hard to read the requested number of bytes
278
+*/
279
+int cli_readn(int fd, void *buff, unsigned int count)
280
+{
281
+        int retval;
282
+        unsigned int todo;
283
+        unsigned char *current;
284
+
285
+
286
+        todo = count;
287
+        current = (unsigned char *) buff;
288
+
289
+        do {
290
+                retval = read(fd, current, todo);
291
+                if (retval == 0) {
292
+                        return (count - todo);
293
+                }
294
+                if (retval < 0) {
295
+			if (errno == EINTR) {
296
+				continue;
297
+			}
298
+			cli_errmsg("cli_readn: read error: %s\n", strerror(errno));
299
+                        return -1;
300
+                }
301
+                todo -= retval;
302
+                current += retval;
303
+        } while (todo > 0);
304
+
305
+
306
+        return count;
307
+}
308
+
309
+/* Function: writen
310
+        Try hard to write the specified number of bytes
311
+*/
312
+int cli_writen(int fd, const void *buff, unsigned int count)
313
+{
314
+        int retval;
315
+        unsigned int todo;
316
+        const unsigned char *current;
317
+
318
+
319
+        todo = count;
320
+        current = (const unsigned char *) buff;
321
+
322
+        do {
323
+                retval = write(fd, current, todo);
324
+                if (retval < 0) {
325
+			if (errno == EINTR) {
326
+				continue;
327
+			}
328
+			cli_errmsg("cli_writen: write error: %s\n", strerror(errno));
329
+                        return -1;
330
+                }
331
+                todo -= retval;
332
+                current += retval;
333
+        } while (todo > 0);
334
+
335
+
336
+        return count;
337
+}
338
+
339
+int cli_filecopy(const char *src, const char *dest)
340
+{
341
+	char *buffer;
342
+	int s, d, bytes;
343
+
344
+
345
+    if((s = open(src, O_RDONLY|O_BINARY)) == -1)
346
+	return -1;
347
+
348
+    if((d = open(dest, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, S_IRWXU)) == -1) {
349
+	close(s);
350
+	return -1;
351
+    }
352
+
353
+    if(!(buffer = cli_malloc(FILEBUFF))) {
354
+	close(s);
355
+	close(d);
356
+	return -1;
357
+    }
358
+
359
+    while((bytes = cli_readn(s, buffer, FILEBUFF)) > 0)
360
+	cli_writen(d, buffer, bytes);
361
+
362
+    free(buffer);
363
+    close(s);
364
+
365
+    return close(d);
366
+}
... ...
@@ -113,7 +113,6 @@ char *freshdbdir(void)
113 113
     return retdir;
114 114
 }
115 115
 
116
-
117 116
 void print_version(const char *dbdir)
118 117
 {
119 118
 	char *fdbdir, *path;
... ...
@@ -156,9 +155,9 @@ void print_version(const char *dbdir)
156 156
     free(path);
157 157
 }
158 158
 #endif
159
+
159 160
 int filecopy(const char *src, const char *dest)
160 161
 {
161
-
162 162
 #ifdef C_DARWIN
163 163
 	pid_t pid;
164 164
 
... ...
@@ -177,110 +176,11 @@ int filecopy(const char *src, const char *dest)
177 177
 
178 178
     return -1;
179 179
 
180
-#else
181
-	char buffer[FILEBUFF];
182
-	int s, d, bytes, ret;
183
-	struct stat sb;
184
-
185
-
186
-    if((s = open(src, O_RDONLY|O_BINARY)) == -1)
187
-	return -1;
188
-
189
-    if((d = open(dest, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, 0644)) == -1) {
190
-	close(s);
191
-	return -1;
192
-    }
193
-
194
-    while((bytes = read(s, buffer, FILEBUFF)) > 0)
195
-	if(write(d, buffer, bytes) < bytes) {
196
-	    close(s);
197
-	    close(d);
198
-	    return -1;
199
-	}
200
-
201
-    close(s);
202
-    /* njh@bandsman.co.uk: check result of close for NFS file */
203
-    ret = close(d);
204
-
205
-    stat(src, &sb);
206
-    chmod(dest, sb.st_mode);
207
-
208
-    return ret;
209
-
180
+#else /* C_DARWIN */
181
+    return cli_filecopy(src, dest);
210 182
 #endif
211
-
212 183
 }
213 184
 
214
-#ifndef CL_NOLIBCLAMAV
215
-int dircopy(const char *src, const char *dest)
216
-{
217
-	DIR *dd;
218
-	struct dirent *dent;
219
-	struct stat sb;
220
-	char spath[512], dpath[512];
221
-
222
-
223
-    if(stat(dest, &sb) == -1) {
224
-	if(mkdir(dest, 0755)) {
225
-	    /* mprintf("!dircopy: Can't create temporary directory %s\n", dest); */
226
-	    return -1;
227
-	}
228
-    }
229
-
230
-    if((dd = opendir(src)) == NULL) {
231
-        /* mprintf("!dircopy: Can't open directory %s\n", src); */
232
-        return -1;
233
-    }
234
-
235
-    while((dent = readdir(dd))) {
236
-#if (!defined(C_INTERIX)) && (!defined(C_WINDOWS))
237
-	if(dent->d_ino)
238
-#endif
239
-	{
240
-	    if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
241
-		continue;
242
-
243
-	    snprintf(spath, sizeof(spath), "%s/%s", src, dent->d_name);
244
-	    snprintf(dpath, sizeof(dpath), "%s/%s", dest, dent->d_name);
245
-
246
-	    if(filecopy(spath, dpath) == -1) {
247
-		/* mprintf("!dircopy: Can't copy %s to %s\n", spath, dpath); */
248
-		cli_rmdirs(dest);
249
-		closedir(dd);
250
-		return -1;
251
-	    }
252
-	}
253
-    }
254
-
255
-    closedir(dd);
256
-    return 0;
257
-}
258
-#endif
259
-
260
-#ifndef CL_NOLIBCLAMAV
261
-int cvd_unpack(const char *cvd, const char *destdir)
262
-{
263
-	int fd;
264
-
265
-
266
-    if((fd = open(cvd, O_RDONLY|O_BINARY)) == -1)
267
-	return -1;
268
-
269
-    if(lseek(fd, 512, SEEK_SET) == -1) {
270
-	close(fd);
271
-	return -1;
272
-    }
273
-
274
-    if(cli_untgz(fd, destdir) == -1) {
275
-	close(fd);
276
-	return -1;
277
-    }
278
-    close(fd);
279
-
280
-    return 0;
281
-}
282
-#endif
283
-
284 185
 int daemonize(void)
285 186
 {
286 187
 #if defined(C_OS2) || defined(C_WINDOWS)
... ...
@@ -33,8 +33,6 @@
33 33
 char *freshdbdir(void);
34 34
 void print_version(const char *dbdir);
35 35
 int filecopy(const char *src, const char *dest);
36
-int dircopy(const char *src, const char *dest);
37
-int cvd_unpack(const char *cvd, const char *destdir);
38 36
 int daemonize(void);
39 37
 const char *get_version(void);
40 38
 int match_regex(const char *filename, const char *pattern);
... ...
@@ -76,7 +76,7 @@ pthread_mutex_t logg_mutex = PTHREAD_MUTEX_INITIALIZER;
76 76
 
77 77
 #endif
78 78
 
79
-FILE *logg_fd = NULL;
79
+FILE *logg_fp = NULL;
80 80
 
81 81
 short int logg_verbose = 0, logg_nowarn = 0, logg_lock = 1, logg_time = 0, logg_foreground = 1;
82 82
 unsigned int logg_size = 0;
... ...
@@ -88,43 +88,89 @@ short logg_syslog;
88 88
 short int mprintf_disabled = 0, mprintf_verbose = 0, mprintf_quiet = 0,
89 89
 	  mprintf_stdout = 0, mprintf_nowarn = 0;
90 90
 
91
+#define ARGLEN(args, str, len)			    \
92
+{						    \
93
+	int arglen = 0, i;			    \
94
+	char *pt;				    \
95
+    va_start(args, str);			    \
96
+    len = strlen(str);				    \
97
+    for(i = 0; i < len - 1; i++) {		    \
98
+	if(str[i] == '%') {			    \
99
+	    switch(str[++i]) {			    \
100
+		case 's':			    \
101
+		    pt  = va_arg(args, char *);	    \
102
+		    if(pt)			    \
103
+			arglen += strlen(pt);	    \
104
+		    break;			    \
105
+		default:			    \
106
+		    va_arg(args, int);		    \
107
+		    arglen += 10;		    \
108
+		    break;			    \
109
+	    }					    \
110
+	}					    \
111
+    }						    \
112
+    va_end(args);				    \
113
+    len += arglen;				    \
114
+}
115
+
91 116
 int mdprintf(int desc, const char *str, ...)
92 117
 {
93 118
 	va_list args;
94
-	char buff[512];
95
-	int bytes;
96
-
119
+	char buffer[512], *abuffer = NULL, *buff;
120
+	int bytes, len, ret;
121
+
122
+
123
+    ARGLEN(args, str, len);
124
+    if(len <= sizeof(buffer)) {
125
+	len = sizeof(buffer);
126
+	buff = buffer;
127
+    } else {
128
+	abuffer = malloc(len);
129
+	if(!abuffer) {
130
+	    len = sizeof(buffer);
131
+	    buff = buffer;
132
+	} else {
133
+	    buff = abuffer;
134
+	}
135
+    }
97 136
     va_start(args, str);
98
-    bytes = vsnprintf(buff, sizeof(buff), str, args);
137
+    bytes = vsnprintf(buff, len, str, args);
99 138
     va_end(args);
139
+    buff[len - 1] = 0;
100 140
 
101
-    if(bytes == -1)
141
+    if(bytes < 0) {
142
+	if(len > sizeof(buffer))
143
+	    free(abuffer);
102 144
 	return bytes;
145
+    }
146
+    if((size_t) bytes >= len)
147
+	bytes = len - 1;
148
+
149
+    ret = send(desc, buff, bytes, 0);
103 150
 
104
-    if(bytes >= (int) sizeof(buff))
105
-	bytes = sizeof(buff) - 1;
151
+    if(len > sizeof(buffer))
152
+	free(abuffer);
106 153
 
107
-    return send(desc, buff, bytes, 0);
154
+    return bytes;
108 155
 }
109 156
 
110
-void logg_close(void) {
157
+void logg_close(void)
158
+{
159
+#if defined(USE_SYSLOG) && !defined(C_AIX)
160
+    if(logg_syslog)
161
+    	closelog();
162
+#endif
111 163
 
112 164
 #ifdef CL_THREAD_SAFE
113 165
     pthread_mutex_lock(&logg_mutex);
114 166
 #endif
115
-    if (logg_fd) {
116
-	fclose(logg_fd);
117
-	logg_fd = NULL;
167
+    if(logg_fp) {
168
+	fclose(logg_fp);
169
+	logg_fp = NULL;
118 170
     }
119 171
 #ifdef CL_THREAD_SAFE
120 172
     pthread_mutex_unlock(&logg_mutex);
121 173
 #endif
122
-
123
-#if defined(USE_SYSLOG) && !defined(C_AIX)
124
-    if(logg_syslog) {
125
-    	closelog();
126
-    }
127
-#endif
128 174
 }
129 175
 
130 176
 int logg(const char *str, ...)
... ...
@@ -133,29 +179,45 @@ int logg(const char *str, ...)
133 133
 #ifdef F_WRLCK
134 134
 	struct flock fl;
135 135
 #endif
136
-	char vbuff[1025];
136
+	char buffer[1025], *abuffer = NULL, *buff;
137 137
 	time_t currtime;
138 138
 	struct stat sb;
139 139
 	mode_t old_umask;
140
-
141
-
140
+	int len;
141
+
142
+
143
+    ARGLEN(args, str, len);
144
+    if(len <= sizeof(buffer)) {
145
+	len = sizeof(buffer);
146
+	buff = buffer;
147
+    } else {
148
+	abuffer = malloc(len);
149
+	if(!abuffer) {
150
+	    len = sizeof(buffer);
151
+	    buff = buffer;
152
+	} else {
153
+	    buff = abuffer;
154
+	}
155
+    }
142 156
     va_start(args, str);
143
-    vsnprintf(vbuff, sizeof(vbuff), str, args);
157
+    vsnprintf(buff, len, str, args);
144 158
     va_end(args);
145
-    vbuff[1024] = 0;
159
+    buff[len - 1] = 0;
146 160
 
147 161
 #ifdef CL_THREAD_SAFE
148 162
     pthread_mutex_lock(&logg_mutex);
149 163
 #endif
150 164
     if(logg_file) {
151
-	if(!logg_fd) {
165
+	if(!logg_fp) {
152 166
 	    old_umask = umask(0037);
153
-	    if((logg_fd = fopen(logg_file, "at")) == NULL) {
167
+	    if((logg_fp = fopen(logg_file, "at")) == NULL) {
154 168
 		umask(old_umask);
155 169
 #ifdef CL_THREAD_SAFE
156 170
 		pthread_mutex_unlock(&logg_mutex);
157 171
 #endif
158 172
 		printf("ERROR: Can't open %s in append mode (check permissions!).\n", logg_file);
173
+		if(len > sizeof(buffer))
174
+		    free(abuffer);
159 175
 		return -1;
160 176
 	    } else umask(old_umask);
161 177
 
... ...
@@ -163,11 +225,13 @@ int logg(const char *str, ...)
163 163
 	    if(logg_lock) {
164 164
 		memset(&fl, 0, sizeof(fl));
165 165
 		fl.l_type = F_WRLCK;
166
-		if(fcntl(fileno(logg_fd), F_SETLK, &fl) == -1) {
166
+		if(fcntl(fileno(logg_fp), F_SETLK, &fl) == -1) {
167 167
 #ifdef CL_THREAD_SAFE
168 168
 		    pthread_mutex_unlock(&logg_mutex);
169 169
 #endif
170 170
 		    printf("ERROR: %s is locked by another process\n", logg_file);
171
+		    if(len > sizeof(buffer))
172
+			free(abuffer);
171 173
 		    return -1;
172 174
 		}
173 175
 	    }
... ...
@@ -178,71 +242,73 @@ int logg(const char *str, ...)
178 178
 	    if(stat(logg_file, &sb) != -1) {
179 179
 		if((unsigned int) sb.st_size > logg_size) {
180 180
 		    logg_file = NULL;
181
-		    fprintf(logg_fd, "Log size = %u, max = %u\n", (unsigned int) sb.st_size, logg_size);
182
-		    fprintf(logg_fd, "LOGGING DISABLED (Maximal log file size exceeded).\n");
183
-		    fclose(logg_fd);
184
-		    logg_fd = NULL;
181
+		    fprintf(logg_fp, "Log size = %u, max = %u\n", (unsigned int) sb.st_size, logg_size);
182
+		    fprintf(logg_fp, "LOGGING DISABLED (Maximal log file size exceeded).\n");
183
+		    fclose(logg_fp);
184
+		    logg_fp = NULL;
185 185
 		}
186 186
 	    }
187 187
 	}
188 188
 
189
-	if(logg_fd) {
189
+	if(logg_fp) {
190 190
             /* Need to avoid logging time for verbose messages when logverbose
191 191
                is not set or we get a bunch of timestamps in the log without
192 192
                newlines... */
193
-	    if(logg_time && ((*vbuff != '*') || logg_verbose)) {
193
+	    if(logg_time && ((*buff != '*') || logg_verbose)) {
194 194
 	        char timestr[32];
195 195
 		time(&currtime);
196 196
 		cli_ctime(&currtime, timestr, sizeof(timestr));
197 197
 		/* cut trailing \n */
198 198
 		timestr[strlen(timestr)-1] = '\0';
199
-		fprintf(logg_fd, "%s -> ", timestr);
199
+		fprintf(logg_fp, "%s -> ", timestr);
200 200
 	    }
201 201
 
202
-	    if(*vbuff == '!') {
203
-		fprintf(logg_fd, "ERROR: %s", vbuff + 1);
204
-	    } else if(*vbuff == '^') {
202
+	    if(*buff == '!') {
203
+		fprintf(logg_fp, "ERROR: %s", buff + 1);
204
+	    } else if(*buff == '^') {
205 205
 		if(!logg_nowarn)
206
-		    fprintf(logg_fd, "WARNING: %s", vbuff + 1);
207
-	    } else if(*vbuff == '*') {
206
+		    fprintf(logg_fp, "WARNING: %s", buff + 1);
207
+	    } else if(*buff == '*') {
208 208
 		if(logg_verbose)
209
-		    fprintf(logg_fd, "%s", vbuff + 1);
210
-	    } else if(*vbuff == '#' || *vbuff == '~') {
211
-		fprintf(logg_fd, "%s", vbuff + 1);
209
+		    fprintf(logg_fp, "%s", buff + 1);
210
+	    } else if(*buff == '#' || *buff == '~') {
211
+		fprintf(logg_fp, "%s", buff + 1);
212 212
 	    } else
213
-		fprintf(logg_fd, "%s", vbuff);
213
+		fprintf(logg_fp, "%s", buff);
214 214
 
215
-	    fflush(logg_fd);
215
+	    fflush(logg_fp);
216 216
 	}
217 217
     }
218 218
 
219 219
 #if defined(USE_SYSLOG) && !defined(C_AIX)
220 220
     if(logg_syslog) {
221
-	if(vbuff[0] == '!') {
222
-	    syslog(LOG_ERR, "%s", vbuff + 1);
223
-	} else if(vbuff[0] == '^') {
221
+	if(buff[0] == '!') {
222
+	    syslog(LOG_ERR, "%s", buff + 1);
223
+	} else if(buff[0] == '^') {
224 224
 	    if(!logg_nowarn)
225
-		syslog(LOG_WARNING, "%s", vbuff + 1);
226
-	} else if(vbuff[0] == '*') {
225
+		syslog(LOG_WARNING, "%s", buff + 1);
226
+	} else if(buff[0] == '*') {
227 227
 	    if(logg_verbose) {
228
-		syslog(LOG_DEBUG, "%s", vbuff + 1);
228
+		syslog(LOG_DEBUG, "%s", buff + 1);
229 229
 	    }
230
-	} else if(vbuff[0] == '#' || vbuff[0] == '~') {
231
-	    syslog(LOG_INFO, "%s", vbuff + 1);
232
-	} else syslog(LOG_INFO, "%s", vbuff);
230
+	} else if(buff[0] == '#' || buff[0] == '~') {
231
+	    syslog(LOG_INFO, "%s", buff + 1);
232
+	} else syslog(LOG_INFO, "%s", buff);
233 233
 
234 234
     }
235 235
 #endif
236 236
 
237 237
     if(logg_foreground) {
238
-	if(vbuff[0] != '#')
239
-	    mprintf("%s", vbuff);
238
+	if(buff[0] != '#')
239
+	    mprintf("%s", buff);
240 240
     }
241 241
 
242 242
 #ifdef CL_THREAD_SAFE
243 243
     pthread_mutex_unlock(&logg_mutex);
244 244
 #endif
245 245
 
246
+    if(len > sizeof(buffer))
247
+	free(abuffer);
246 248
     return 0;
247 249
 }
248 250
 
... ...
@@ -250,7 +316,8 @@ void mprintf(const char *str, ...)
250 250
 {
251 251
 	va_list args;
252 252
 	FILE *fd;
253
-	char buff[512];
253
+	char buffer[512], *abuffer = NULL, *buff;
254
+	int len;
254 255
 
255 256
 
256 257
     if(mprintf_disabled) 
... ...
@@ -273,9 +340,23 @@ void mprintf(const char *str, ...)
273 273
  * quiet       stderr     no         no
274 274
  */
275 275
 
276
+    ARGLEN(args, str, len);
277
+    if(len <= sizeof(buffer)) {
278
+	len = sizeof(buffer);
279
+	buff = buffer;
280
+    } else {
281
+	abuffer = malloc(len);
282
+	if(!abuffer) {
283
+	    len = sizeof(buffer);
284
+	    buff = buffer;
285
+	} else {
286
+	    buff = abuffer;
287
+	}
288
+    }
276 289
     va_start(args, str);
277
-    vsnprintf(buff, sizeof(buff), str, args);
290
+    vsnprintf(buff, len, str, args);
278 291
     va_end(args);
292
+    buff[len - 1] = 0;
279 293
 
280 294
     if(buff[0] == '!') {
281 295
        if(!mprintf_stdout)
... ...
@@ -302,6 +383,9 @@ void mprintf(const char *str, ...)
302 302
 
303 303
     if(fd == stdout)
304 304
 	fflush(stdout);
305
+
306
+    if(len > sizeof(buffer))
307
+	free(abuffer);
305 308
 }
306 309
 
307 310
 struct facstruct {
... ...
@@ -812,7 +812,7 @@ static int build(const struct optstruct *opts)
812 812
 	return -1;
813 813
     }
814 814
 
815
-    if(cvd_unpack(olddb, pt) == -1) {
815
+    if(cli_cvdunpack(olddb, pt) == -1) {
816 816
 	mprintf("!build: Can't unpack CVD file %s\n", olddb);
817 817
 	cli_rmdirs(pt);
818 818
 	free(pt);
... ...
@@ -838,7 +838,7 @@ static int build(const struct optstruct *opts)
838 838
 	return -1;
839 839
     }
840 840
 
841
-    if(cvd_unpack(newcvd, pt) == -1) {
841
+    if(cli_cvdunpack(newcvd, pt) == -1) {
842 842
 	mprintf("!build: Can't unpack CVD file %s\n", newcvd);
843 843
 	cli_rmdirs(pt);
844 844
 	free(pt);
... ...
@@ -904,7 +904,7 @@ static int unpack(const struct optstruct *opts)
904 904
 	name[sizeof(name)-1]='\0';
905 905
     }
906 906
 
907
-    if(cvd_unpack(name, ".") == -1) {
907
+    if(cli_cvdunpack(name, ".") == -1) {
908 908
 	mprintf("!unpack: Can't unpack file %s\n", name);
909 909
 	return -1;
910 910
     }
... ...
@@ -1060,7 +1060,7 @@ static int listdb(const char *filename)
1060 1060
 	    return -1;
1061 1061
 	}
1062 1062
 
1063
-	if(cvd_unpack(filename, dir) == -1) {
1063
+	if(cli_cvdunpack(filename, dir) == -1) {
1064 1064
 	    mprintf("!listdb: Can't unpack CVD file %s\n", filename);
1065 1065
 	    cli_rmdirs(dir);
1066 1066
 	    free(dir);
... ...
@@ -1417,6 +1417,50 @@ static int compare(const char *oldpath, const char *newpath, FILE *diff)
1417 1417
     return 0;
1418 1418
 }
1419 1419
 
1420
+static int dircopy(const char *src, const char *dest)
1421
+{
1422
+	DIR *dd;
1423
+	struct dirent *dent;
1424
+	struct stat sb;
1425
+	char spath[512], dpath[512];
1426
+
1427
+
1428
+    if(stat(dest, &sb) == -1) {
1429
+	if(mkdir(dest, 0755)) {
1430
+	    /* mprintf("!dircopy: Can't create temporary directory %s\n", dest); */
1431
+	    return -1;
1432
+	}
1433
+    }
1434
+
1435
+    if((dd = opendir(src)) == NULL) {
1436
+        /* mprintf("!dircopy: Can't open directory %s\n", src); */
1437
+        return -1;
1438
+    }
1439
+
1440
+    while((dent = readdir(dd))) {
1441
+#if (!defined(C_INTERIX)) && (!defined(C_WINDOWS))
1442
+	if(dent->d_ino)
1443
+#endif
1444
+	{
1445
+	    if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
1446
+		continue;
1447
+
1448
+	    snprintf(spath, sizeof(spath), "%s/%s", src, dent->d_name);
1449
+	    snprintf(dpath, sizeof(dpath), "%s/%s", dest, dent->d_name);
1450
+
1451
+	    if(filecopy(spath, dpath) == -1) {
1452
+		/* mprintf("!dircopy: Can't copy %s to %s\n", spath, dpath); */
1453
+		cli_rmdirs(dest);
1454
+		closedir(dd);
1455
+		return -1;
1456
+	    }
1457
+	}
1458
+    }
1459
+
1460
+    closedir(dd);
1461
+    return 0;
1462
+}
1463
+
1420 1464
 static int verifydiff(const char *diff, const char *cvd, const char *incdir)
1421 1465
 {
1422 1466
 	char *tempdir, cwd[512];
... ...
@@ -1446,7 +1490,7 @@ static int verifydiff(const char *diff, const char *cvd, const char *incdir)
1446 1446
     }
1447 1447
 
1448 1448
     if(cvd) {
1449
-	if(cvd_unpack(cvd, tempdir) == -1) {
1449
+	if(cli_cvdunpack(cvd, tempdir) == -1) {
1450 1450
 	    mprintf("!verifydiff: Can't unpack CVD file %s\n", cvd);
1451 1451
 	    cli_rmdirs(tempdir);
1452 1452
 	    free(tempdir);
... ...
@@ -1634,7 +1678,7 @@ static int makediff(const struct optstruct *opts)
1634 1634
 	return -1;
1635 1635
     }
1636 1636
 
1637
-    if(cvd_unpack(optget(opts, "diff")->strarg, odir) == -1) {
1637
+    if(cli_cvdunpack(optget(opts, "diff")->strarg, odir) == -1) {
1638 1638
 	mprintf("!makediff: Can't unpack CVD file %s\n", optget(opts, "diff")->strarg);
1639 1639
 	cli_rmdirs(odir);
1640 1640
 	free(odir);
... ...
@@ -1657,7 +1701,7 @@ static int makediff(const struct optstruct *opts)
1657 1657
 	return -1;
1658 1658
     }
1659 1659
 
1660
-    if(cvd_unpack(opts->filename[0], ndir) == -1) {
1660
+    if(cli_cvdunpack(opts->filename[0], ndir) == -1) {
1661 1661
 	mprintf("!makediff: Can't unpack CVD file %s\n", opts->filename[0]);
1662 1662
 	cli_rmdirs(odir);
1663 1663
 	cli_rmdirs(ndir);