git-svn: trunk@3631
aCaB authored on 2008/02/15 00:24:07... | ... |
@@ -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 |
} |