git-svn: trunk@1713
Nigel Horne authored on 2005/09/02 06:06:09... | ... |
@@ -1,3 +1,10 @@ |
1 |
+Thu Sep 1 22:04:00 BST 2005 (njh) |
|
2 |
+---------------------------------- |
|
3 |
+ * libclamav/untar.c: Added support for various GNU extensions: volume |
|
4 |
+ headers, long file names and long names for |
|
5 |
+ symbolic links. Code by Daniel Fahlgren |
|
6 |
+ fahlgren <AT> ardendo.se |
|
7 |
+ |
|
1 | 8 |
Mon Aug 29 17:00:36 CEST 2005 (tk) |
2 | 9 |
---------------------------------- |
3 | 10 |
* libclamav: activate ELF code |
... | ... |
@@ -21,6 +21,9 @@ |
21 | 21 |
* |
22 | 22 |
* Change History: |
23 | 23 |
* $Log: untar.c,v $ |
24 |
+ * Revision 1.27 2005/09/01 21:03:46 nigelhorne |
|
25 |
+ * Added support for various GNU extensions |
|
26 |
+ * |
|
24 | 27 |
* Revision 1.26 2005/08/01 11:30:59 nigelhorne |
25 | 28 |
* Spelling fix |
26 | 29 |
* |
... | ... |
@@ -100,7 +103,7 @@ |
100 | 100 |
* First draft |
101 | 101 |
* |
102 | 102 |
*/ |
103 |
-static char const rcsid[] = "$Id: untar.c,v 1.26 2005/08/01 11:30:59 nigelhorne Exp $"; |
|
103 |
+static char const rcsid[] = "$Id: untar.c,v 1.27 2005/09/01 21:03:46 nigelhorne Exp $"; |
|
104 | 104 |
|
105 | 105 |
#include <stdio.h> |
106 | 106 |
#include <errno.h> |
... | ... |
@@ -159,7 +162,7 @@ cli_untar(const char *dir, int desc, unsigned int posix) |
159 | 159 |
char type; |
160 | 160 |
const char *suffix; |
161 | 161 |
size_t suffixLen = 0; |
162 |
- int fd, directory; |
|
162 |
+ int fd, directory, skipEntry = 0; |
|
163 | 163 |
char magic[7], name[101], osize[13]; |
164 | 164 |
|
165 | 165 |
if(outfile) { |
... | ... |
@@ -201,11 +204,18 @@ cli_untar(const char *dir, int desc, unsigned int posix) |
201 | 201 |
case '3': /* char device */ |
202 | 202 |
case '4': /* block device */ |
203 | 203 |
case '6': /* fifo special */ |
204 |
+ case 'V': /* Volume header */ |
|
204 | 205 |
directory = 1; |
205 | 206 |
break; |
206 |
- case 'L': /* GNU extension - ././@LongLink */ |
|
207 |
- cli_errmsg("cli_untar: only standard TAR files are currently supported\n", type); |
|
208 |
- return CL_EFORMAT; |
|
207 |
+ case 'K': |
|
208 |
+ case 'L': |
|
209 |
+ /* GNU extension - ././@LongLink |
|
210 |
+ * Discard the blocks with the extended filename, |
|
211 |
+ * the last header will contain parts of it anyway |
|
212 |
+ */ |
|
213 |
+ directory = 0; |
|
214 |
+ skipEntry = 1; |
|
215 |
+ break; |
|
209 | 216 |
default: |
210 | 217 |
/*cli_errmsg("cli_untar: unknown type flag %c\n", type); |
211 | 218 |
return CL_EFORMAT;*/ |
... | ... |
@@ -227,6 +237,23 @@ cli_untar(const char *dir, int desc, unsigned int posix) |
227 | 227 |
continue; |
228 | 228 |
} |
229 | 229 |
|
230 |
+ strncpy(osize, block+124, 12); |
|
231 |
+ osize[12] = '\0'; |
|
232 |
+ size = octal(osize); |
|
233 |
+ if(size < 0) { |
|
234 |
+ cli_errmsg("Invalid size in tar header\n"); |
|
235 |
+ fclose(outfile); |
|
236 |
+ return CL_EFORMAT; |
|
237 |
+ } |
|
238 |
+ cli_dbgmsg("cli_untar: size = %d\n", size); |
|
239 |
+ |
|
240 |
+ if(skipEntry) { |
|
241 |
+ const int nskip = (size % BLOCKSIZE || !size) ? size + BLOCKSIZE - (size % BLOCKSIZE) : size; |
|
242 |
+ cli_dbgmsg("cli_untar: GNU extension, skipping entry\n"); |
|
243 |
+ lseek(desc, nskip, SEEK_CUR); |
|
244 |
+ continue; |
|
245 |
+ } |
|
246 |
+ |
|
230 | 247 |
strncpy(name, block, 100); |
231 | 248 |
name[100] = '\0'; |
232 | 249 |
|
... | ... |
@@ -270,16 +297,6 @@ cli_untar(const char *dir, int desc, unsigned int posix) |
270 | 270 |
close(fd); |
271 | 271 |
return CL_ETMPFILE; |
272 | 272 |
} |
273 |
- |
|
274 |
- strncpy(osize, block+124, 12); |
|
275 |
- osize[12] = '\0'; |
|
276 |
- size = octal(osize); |
|
277 |
- if(size < 0) { |
|
278 |
- cli_errmsg("Invalid size in tar header\n"); |
|
279 |
- fclose(outfile); |
|
280 |
- return CL_EFORMAT; |
|
281 |
- } |
|
282 |
- cli_dbgmsg("cli_untar: size = %d\n", size); |
|
283 | 273 |
} else { /* write or continue writing file contents */ |
284 | 274 |
const int nbytes = size>512? 512:size; |
285 | 275 |
const int nwritten = fwrite(block, 1, (size_t)nbytes, outfile); |