Browse code

untar OTF

git-svn: trunk@3631

aCaB authored on 2008/02/15 00:24:07
Showing 4 changed files
... ...
@@ -1,3 +1,8 @@
1
+Thu Feb 14 15:33:22 CET 2008 (acab)
2
+-----------------------------------
3
+  * libclamav/untar: OTF scan
4
+  * libclamav/pdf: create RW tempfiles
5
+
1 6
 Thu Feb 14 02:53:28 CET 2008 (acab)
2 7
 -----------------------------------
3 8
   * libclamav/nsis: revert Nullsoft-bastardized zlibs
... ...
@@ -58,6 +58,10 @@ static	char	const	rcsid[] = "$Id: pdf.c,v 1.61 2007/02/12 20:46:09 njh Exp $";
58 58
 #include "pdf.h"
59 59
 #include "scanners.h"
60 60
 
61
+#ifndef	O_BINARY
62
+#define	O_BINARY	0
63
+#endif
64
+
61 65
 #ifdef	CL_DEBUG
62 66
 /*#define	SAVE_TMP	/* Save the file being worked on in tmp */
63 67
 #endif
... ...
@@ -369,28 +373,8 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx)
369 369
 			has_cr = 1;
370 370
 		} else
371 371
 			has_cr = 0;
372
-		snprintf(fullname, sizeof(fullname), "%s/pdfXXXXXX", dir);
373
-#if	defined(C_LINUX) || defined(C_BSD) || defined(HAVE_MKSTEMP) || defined(C_SOLARIS) || defined(C_CYGWIN)
374
-		fout = mkstemp(fullname);
375
-#elif	defined(C_WINDOWS)
376
-		if(_mktemp(fullname) == NULL) {
377
-			/* mktemp only allows 26 files */
378
-			char *name = cli_gentemp(dir);
379
-			if(name == NULL)
380
-				fout = -1;
381
-			else {
382
-				strcpy(fullname, name);
383
-				free(name);
384
-				fout = open(fullname,
385
-					O_WRONLY|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
386
-			}
387
-		} else
388
-			fout = open(fullname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
389
-#else
390
-		mktemp(fullname);
391
-		fout = open(fullname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
392
-#endif
393
-
372
+		snprintf(fullname, sizeof(fullname), "%s/pdf%02u", dir, files);
373
+		fout = open(fullname, O_RDWR|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
394 374
 		if(fout < 0) {
395 375
 			cli_errmsg("cli_pdf: can't create temporary file %s: %s\n", fullname, strerror(errno));
396 376
 			rc = CL_ETMPFILE;
... ...
@@ -490,7 +474,7 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx)
490 490
 		}
491 491
 
492 492
 		if (rc == CL_CLEAN) {
493
-			cli_dbgmsg("cli_pdf: extracted file %u to %s\n", ++files, fullname);
493
+			cli_dbgmsg("cli_pdf: extracted file %u to %s\n", files++, fullname);
494 494
 	
495 495
 			lseek(fout, 0, SEEK_SET);
496 496
 			md5digest = cli_md5digest(fout);
... ...
@@ -1152,10 +1152,7 @@ static int cli_scantar(int desc, cli_ctx *ctx, unsigned int posix)
1152 1152
 	return CL_ETMPDIR;
1153 1153
     }
1154 1154
 
1155
-    if((ret = cli_untar(dir, desc, posix, ctx)))
1156
-	cli_dbgmsg("Tar: %s\n", cl_strerror(ret));
1157
-    else
1158
-	ret = cli_scandir(dir, ctx, 0);
1155
+    ret = cli_untar(dir, desc, posix, ctx);
1159 1156
 
1160 1157
     if(!cli_leavetemps_flag)
1161 1158
 	cli_rmdirs(dir);
... ...
@@ -63,13 +63,12 @@ octal(const char *str)
63 63
 int
64 64
 cli_untar(const char *dir, int desc, unsigned int posix, cli_ctx *ctx)
65 65
 {
66
-	int size = 0, ret;
66
+	int size = 0, ret, fout=-1;
67 67
 	int in_block = 0;
68 68
 	unsigned int files = 0;
69 69
 	char fullname[NAME_MAX + 1];
70
-	FILE *outfile = NULL;
71 70
 
72
-	cli_dbgmsg("In untar(%s, %d)\n", dir ? dir : "", desc);
71
+	cli_dbgmsg("In untar(%s, %d)\n", dir, desc);
73 72
 
74 73
 	for(;;) {
75 74
 		char block[BLOCKSIZE];
... ...
@@ -79,26 +78,27 @@ cli_untar(const char *dir, int desc, unsigned int posix, cli_ctx *ctx)
79 79
 			break;
80 80
 
81 81
 		if(nread < 0) {
82
-			if(outfile)
83
-				fclose(outfile);
82
+			if(fout>=0)
83
+				close(fout);
84 84
 			cli_errmsg("cli_untar: block read error\n");
85 85
 			return CL_EIO;
86 86
 		}
87 87
 
88 88
 		if(!in_block) {
89 89
 			char type;
90
-			const char *suffix;
91
-			size_t suffixLen = 0;
92
-			int fd, directory, skipEntry = 0;
90
+			int directory, skipEntry = 0;
93 91
 			char magic[7], name[101], osize[13];
94 92
 
95
-			if(outfile) {
96
-				if(fclose(outfile)) {
97
-					cli_errmsg("cli_untar: cannot close file %s\n",
98
-						fullname);
99
-					return CL_EIO;
100
-				}
101
-				outfile = (FILE*)0;
93
+			if(fout>=0) {
94
+				int ret;
95
+				lseek(fout, 0, SEEK_SET);
96
+				ret = cli_magic_scandesc(fout, ctx);
97
+				close(fout);
98
+				if (!cli_leavetemps_flag)
99
+					unlink(fullname);
100
+				if (ret==CL_VIRUS)
101
+					return CL_VIRUS;
102
+				fout = -1;
102 103
 			}
103 104
 
104 105
 			if(block[0] == '\0')	/* We're done */
... ...
@@ -168,9 +168,9 @@ cli_untar(const char *dir, int desc, unsigned int posix, cli_ctx *ctx)
168 168
 			size = octal(osize);
169 169
 			if(size < 0) {
170 170
 				cli_errmsg("Invalid size in tar header\n");
171
-				if(outfile)
172
-					fclose(outfile);
173
-				return CL_EFORMAT;
171
+				if(fout)
172
+					close(fout);
173
+				return CL_CLEAN;
174 174
 			}
175 175
 			cli_dbgmsg("cli_untar: size = %d\n", size);
176 176
 			if((ret=cli_checklimits("cli_untar", ctx, size, 0, 0))!=CL_CLEAN) {
... ...
@@ -187,59 +187,26 @@ cli_untar(const char *dir, int desc, unsigned int posix, cli_ctx *ctx)
187 187
 
188 188
 			strncpy(name, block, 100);
189 189
 			name[100] = '\0';
190
+			snprintf(fullname, sizeof(fullname)-1, "%s/tar%02u", dir, files);
191
+			fullname[sizeof(fullname)-1] = '\0';
192
+			fout = open(fullname, O_RDWR|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
190 193
 
191
-			/*
192
-			 * see also fileblobSetFilename()
193
-			 * TODO: check if the suffix needs to be put back
194
-			 */
195
-			sanitiseName(name);
196
-			suffix = strrchr(name, '.');
197
-			if(suffix == NULL)
198
-				suffix = "";
199
-			else {
200
-				suffixLen = strlen(suffix);
201
-				if(suffixLen > 4) {
202
-					/* Found a full stop which isn't a suffix */
203
-					suffix = "";
204
-					suffixLen = 0;
205
-				}
206
-			}
207
-			snprintf(fullname, sizeof(fullname) - 1 - suffixLen, "%s/%.*sXXXXXX", dir,
208
-				(int)(sizeof(fullname) - 9 - suffixLen - strlen(dir)), name);
209
-#if	defined(C_LINUX) || defined(C_BSD) || defined(HAVE_MKSTEMP) || defined(C_SOLARIS) || defined(C_CYGWIN)
210
-			fd = mkstemp(fullname);
211
-#else
212
-			(void)mktemp(fullname);
213
-			fd = open(fullname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
214
-#endif
215
-
216
-			if(fd < 0) {
194
+			if(fout < 0) {
217 195
 				cli_errmsg("Can't create temporary file %s: %s\n", fullname, strerror(errno));
218
-				cli_dbgmsg("%lu %lu %lu\n",
219
-					(unsigned long)suffixLen,
220
-					(unsigned long)sizeof(fullname),
221
-					(unsigned long)strlen(fullname));
222 196
 				return CL_ETMPFILE;
223 197
 			}
224
-
225
-			cli_dbgmsg("cli_untar: extracting %s\n", fullname);
198
+			
199
+			cli_dbgmsg("cli_untar: extracting to %s\n", fullname);
226 200
 
227 201
 			in_block = 1;
228
-			if((outfile = fdopen(fd, "wb")) == NULL) {
229
-				cli_errmsg("cli_untar: cannot create file %s\n",
230
-					fullname);
231
-				close(fd);
232
-				return CL_ETMPFILE;
233
-			}
234 202
 		} else { /* write or continue writing file contents */
235 203
 			const int nbytes = size>512? 512:size;
236
-			const int nwritten = (int)fwrite(block, 1, (size_t)nbytes, outfile);
204
+			const int nwritten = (int)write(fout, block, (size_t)nbytes);
237 205
 
238 206
 			if(nwritten != nbytes) {
239 207
 				cli_errmsg("cli_untar: only wrote %d bytes to file %s (out of disc space?)\n",
240 208
 					nwritten, fullname);
241
-				if(outfile)
242
-					fclose(outfile);
209
+				close(fout);
243 210
 				return CL_EIO;
244 211
 			}
245 212
 			size -= nbytes;
... ...
@@ -247,8 +214,15 @@ cli_untar(const char *dir, int desc, unsigned int posix, cli_ctx *ctx)
247 247
 		if (size == 0)
248 248
 			in_block = 0;
249 249
         }	
250
-	if(outfile)
251
-		return fclose(outfile);
252
-
253
-	return 0;
250
+	if(fout>=0) {
251
+		int ret;
252
+		lseek(fout, 0, SEEK_SET);
253
+		ret = cli_magic_scandesc(fout, ctx);
254
+		close(fout);
255
+		if (!cli_leavetemps_flag)
256
+			unlink(fullname);
257
+		if (ret==CL_VIRUS)
258
+			return CL_VIRUS;
259
+	}
260
+	return CL_CLEAN;
254 261
 }