1 /*-
2 * Copyright (c) 2003-2007 Tim Kientzle
3 * Copyright (c) 2011-2012 Michihiro NAKAJIMA
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include "archive_platform.h"
28
29 #ifdef HAVE_ERRNO_H
30 #include <errno.h>
31 #endif
32 #include <stdio.h>
33 #ifdef HAVE_STDLIB_H
34 #include <stdlib.h>
35 #endif
36 #ifdef HAVE_STRING_H
37 #include <string.h>
38 #endif
39
40 #include "archive.h"
41 #include "archive_entry.h"
42 #include "archive_entry_locale.h"
43 #include "archive_private.h"
44 #include "archive_write_private.h"
45 #include "archive_write_set_format_private.h"
46
47 struct ustar {
48 uint64_t entry_bytes_remaining;
49 uint64_t entry_padding;
50
51 struct archive_string_conv *opt_sconv;
52 struct archive_string_conv *sconv_default;
53 int init_default_conversion;
54 };
55
56 /*
57 * Define structure of POSIX 'ustar' tar header.
58 */
59 #define USTAR_name_offset 0
60 #define USTAR_name_size 100
61 #define USTAR_mode_offset 100
62 #define USTAR_mode_size 6
63 #define USTAR_mode_max_size 8
64 #define USTAR_uid_offset 108
65 #define USTAR_uid_size 6
66 #define USTAR_uid_max_size 8
67 #define USTAR_gid_offset 116
68 #define USTAR_gid_size 6
69 #define USTAR_gid_max_size 8
70 #define USTAR_size_offset 124
71 #define USTAR_size_size 11
72 #define USTAR_size_max_size 12
73 #define USTAR_mtime_offset 136
74 #define USTAR_mtime_size 11
75 #define USTAR_mtime_max_size 11
76 #define USTAR_checksum_offset 148
77 #define USTAR_checksum_size 8
78 #define USTAR_typeflag_offset 156
79 #define USTAR_typeflag_size 1
80 #define USTAR_linkname_offset 157
81 #define USTAR_linkname_size 100
82 #define USTAR_magic_offset 257
83 #define USTAR_magic_size 6
84 #define USTAR_version_offset 263
85 #define USTAR_version_size 2
86 #define USTAR_uname_offset 265
87 #define USTAR_uname_size 32
88 #define USTAR_gname_offset 297
89 #define USTAR_gname_size 32
90 #define USTAR_rdevmajor_offset 329
91 #define USTAR_rdevmajor_size 6
92 #define USTAR_rdevmajor_max_size 8
93 #define USTAR_rdevminor_offset 337
94 #define USTAR_rdevminor_size 6
95 #define USTAR_rdevminor_max_size 8
96 #define USTAR_prefix_offset 345
97 #define USTAR_prefix_size 155
98 #define USTAR_padding_offset 500
99 #define USTAR_padding_size 12
100
101 /*
102 * A filled-in copy of the header for initialization.
103 */
104 static const char template_header[] = {
105 /* name: 100 bytes */
106 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
107 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
108 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
109 0,0,0,0,
110 /* Mode, space-null termination: 8 bytes */
111 '0','0','0','0','0','0', ' ','\0',
112 /* uid, space-null termination: 8 bytes */
113 '0','0','0','0','0','0', ' ','\0',
114 /* gid, space-null termination: 8 bytes */
115 '0','0','0','0','0','0', ' ','\0',
116 /* size, space termination: 12 bytes */
117 '0','0','0','0','0','0','0','0','0','0','0', ' ',
118 /* mtime, space termination: 12 bytes */
119 '0','0','0','0','0','0','0','0','0','0','0', ' ',
120 /* Initial checksum value: 8 spaces */
121 ' ',' ',' ',' ',' ',' ',' ',' ',
122 /* Typeflag: 1 byte */
123 '0', /* '0' = regular file */
124 /* Linkname: 100 bytes */
125 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
126 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
127 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
128 0,0,0,0,
129 /* Magic: 6 bytes, Version: 2 bytes */
130 'u','s','t','a','r','\0', '0','0',
131 /* Uname: 32 bytes */
132 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
133 /* Gname: 32 bytes */
134 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
135 /* rdevmajor + space/null padding: 8 bytes */
136 '0','0','0','0','0','0', ' ','\0',
137 /* rdevminor + space/null padding: 8 bytes */
138 '0','0','0','0','0','0', ' ','\0',
139 /* Prefix: 155 bytes */
140 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
141 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
142 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
143 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
144 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,
145 /* Padding: 12 bytes */
146 0,0,0,0,0,0,0,0, 0,0,0,0
147 };
148
149 static ssize_t archive_write_ustar_data(struct archive_write *a, const void *buff,
150 size_t s);
151 static int archive_write_ustar_free(struct archive_write *);
152 static int archive_write_ustar_close(struct archive_write *);
153 static int archive_write_ustar_finish_entry(struct archive_write *);
154 static int archive_write_ustar_header(struct archive_write *,
155 struct archive_entry *entry);
156 static int archive_write_ustar_options(struct archive_write *,
157 const char *, const char *);
158 static int format_256(int64_t, char *, int);
159 static int format_number(int64_t, char *, int size, int max, int strict);
160 static int format_octal(int64_t, char *, int);
161
162 /*
163 * Set output format to 'ustar' format.
164 */
165 int
archive_write_set_format_ustar(struct archive * _a)166 archive_write_set_format_ustar(struct archive *_a)
167 {
168 struct archive_write *a = (struct archive_write *)_a;
169 struct ustar *ustar;
170
171 archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
172 ARCHIVE_STATE_NEW, "archive_write_set_format_ustar");
173
174 /* If someone else was already registered, unregister them. */
175 if (a->format_free != NULL)
176 (a->format_free)(a);
177
178 /* Basic internal sanity test. */
179 if (sizeof(template_header) != 512) {
180 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
181 "Internal: template_header wrong size: %zu should be 512",
182 sizeof(template_header));
183 return (ARCHIVE_FATAL);
184 }
185
186 ustar = (struct ustar *)calloc(1, sizeof(*ustar));
187 if (ustar == NULL) {
188 archive_set_error(&a->archive, ENOMEM,
189 "Can't allocate ustar data");
190 return (ARCHIVE_FATAL);
191 }
192 a->format_data = ustar;
193 a->format_name = "ustar";
194 a->format_options = archive_write_ustar_options;
195 a->format_write_header = archive_write_ustar_header;
196 a->format_write_data = archive_write_ustar_data;
197 a->format_close = archive_write_ustar_close;
198 a->format_free = archive_write_ustar_free;
199 a->format_finish_entry = archive_write_ustar_finish_entry;
200 a->archive.archive_format = ARCHIVE_FORMAT_TAR_USTAR;
201 a->archive.archive_format_name = "POSIX ustar";
202 return (ARCHIVE_OK);
203 }
204
205 static int
archive_write_ustar_options(struct archive_write * a,const char * key,const char * val)206 archive_write_ustar_options(struct archive_write *a, const char *key,
207 const char *val)
208 {
209 struct ustar *ustar = (struct ustar *)a->format_data;
210 int ret = ARCHIVE_FAILED;
211
212 if (strcmp(key, "hdrcharset") == 0) {
213 if (val == NULL || val[0] == 0)
214 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
215 "%s: hdrcharset option needs a character-set name",
216 a->format_name);
217 else {
218 ustar->opt_sconv = archive_string_conversion_to_charset(
219 &a->archive, val, 0);
220 if (ustar->opt_sconv != NULL)
221 ret = ARCHIVE_OK;
222 else
223 ret = ARCHIVE_FATAL;
224 }
225 return (ret);
226 }
227
228 /* Note: The "warn" return is just to inform the options
229 * supervisor that we didn't handle it. It will generate
230 * a suitable error if no one used this option. */
231 return (ARCHIVE_WARN);
232 }
233
234 static int
archive_write_ustar_header(struct archive_write * a,struct archive_entry * entry)235 archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
236 {
237 char buff[512];
238 int ret, ret2;
239 struct ustar *ustar;
240 struct archive_entry *entry_main;
241 struct archive_string_conv *sconv;
242
243 ustar = (struct ustar *)a->format_data;
244
245 /* Setup default string conversion. */
246 if (ustar->opt_sconv == NULL) {
247 if (!ustar->init_default_conversion) {
248 ustar->sconv_default =
249 archive_string_default_conversion_for_write(&(a->archive));
250 ustar->init_default_conversion = 1;
251 }
252 sconv = ustar->sconv_default;
253 } else
254 sconv = ustar->opt_sconv;
255
256 /* Sanity check. */
257 if (archive_entry_pathname(entry) == NULL) {
258 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
259 "Can't record entry in tar file without pathname");
260 return (ARCHIVE_FAILED);
261 }
262
263 /* Only regular files (not hardlinks) have data. */
264 if (archive_entry_hardlink(entry) != NULL ||
265 archive_entry_symlink(entry) != NULL ||
266 !(archive_entry_filetype(entry) == AE_IFREG))
267 archive_entry_set_size(entry, 0);
268
269 if (AE_IFDIR == archive_entry_filetype(entry)) {
270 const char *p;
271 size_t path_length;
272 /*
273 * Ensure a trailing '/'. Modify the entry so
274 * the client sees the change.
275 */
276 #if defined(_WIN32) && !defined(__CYGWIN__)
277 const wchar_t *wp;
278
279 wp = archive_entry_pathname_w(entry);
280 if (wp != NULL && wp[wcslen(wp) -1] != L'/') {
281 struct archive_wstring ws;
282
283 archive_string_init(&ws);
284 path_length = wcslen(wp);
285 if (archive_wstring_ensure(&ws,
286 path_length + 2) == NULL) {
287 archive_set_error(&a->archive, ENOMEM,
288 "Can't allocate ustar data");
289 archive_wstring_free(&ws);
290 return(ARCHIVE_FATAL);
291 }
292 /* Should we keep '\' ? */
293 if (wp[path_length -1] == L'\\')
294 path_length--;
295 archive_wstrncpy(&ws, wp, path_length);
296 archive_wstrappend_wchar(&ws, L'/');
297 archive_entry_copy_pathname_w(entry, ws.s);
298 archive_wstring_free(&ws);
299 p = NULL;
300 } else
301 #endif
302 p = archive_entry_pathname(entry);
303 /*
304 * On Windows, this is a backup operation just in
305 * case getting WCS failed. On POSIX, this is a
306 * normal operation.
307 */
308 if (p != NULL && p[0] != '\0' && p[strlen(p) - 1] != '/') {
309 struct archive_string as;
310
311 archive_string_init(&as);
312 path_length = strlen(p);
313 if (archive_string_ensure(&as,
314 path_length + 2) == NULL) {
315 archive_set_error(&a->archive, ENOMEM,
316 "Can't allocate ustar data");
317 archive_string_free(&as);
318 return(ARCHIVE_FATAL);
319 }
320 #if defined(_WIN32) && !defined(__CYGWIN__)
321 /* NOTE: This might break the pathname
322 * if the current code page is CP932 and
323 * the pathname includes a character '\'
324 * as a part of its multibyte pathname. */
325 if (p[strlen(p) -1] == '\\')
326 path_length--;
327 else
328 #endif
329 archive_strncpy(&as, p, path_length);
330 archive_strappend_char(&as, '/');
331 archive_entry_copy_pathname(entry, as.s);
332 archive_string_free(&as);
333 }
334 }
335
336 #if defined(_WIN32) && !defined(__CYGWIN__)
337 /* Make sure the path separators in pathname, hardlink and symlink
338 * are all slash '/', not the Windows path separator '\'. */
339 entry_main = __la_win_entry_in_posix_pathseparator(entry);
340 if (entry_main == NULL) {
341 archive_set_error(&a->archive, ENOMEM,
342 "Can't allocate ustar data");
343 return(ARCHIVE_FATAL);
344 }
345 if (entry != entry_main)
346 entry = entry_main;
347 else
348 entry_main = NULL;
349 #else
350 entry_main = NULL;
351 #endif
352 ret = __archive_write_format_header_ustar(a, buff, entry, -1, 1, sconv);
353 if (ret < ARCHIVE_WARN) {
354 archive_entry_free(entry_main);
355 return (ret);
356 }
357 ret2 = __archive_write_output(a, buff, 512);
358 if (ret2 < ARCHIVE_WARN) {
359 archive_entry_free(entry_main);
360 return (ret2);
361 }
362 if (ret2 < ret)
363 ret = ret2;
364
365 ustar->entry_bytes_remaining = archive_entry_size(entry);
366 ustar->entry_padding = 0x1ff & (-(int64_t)ustar->entry_bytes_remaining);
367 archive_entry_free(entry_main);
368 return (ret);
369 }
370
371 /*
372 * Format a basic 512-byte "ustar" header.
373 *
374 * Returns -1 if format failed (due to field overflow).
375 * Note that this always formats as much of the header as possible.
376 * If "strict" is set to zero, it will extend numeric fields as
377 * necessary (overwriting terminators or using base-256 extensions).
378 *
379 * This is exported so that other 'tar' formats can use it.
380 */
381 int
__archive_write_format_header_ustar(struct archive_write * a,char h[512],struct archive_entry * entry,int tartype,int strict,struct archive_string_conv * sconv)382 __archive_write_format_header_ustar(struct archive_write *a, char h[512],
383 struct archive_entry *entry, int tartype, int strict,
384 struct archive_string_conv *sconv)
385 {
386 unsigned int checksum;
387 int i, r, ret;
388 size_t copy_length;
389 const char *p, *pp;
390 int mytartype;
391
392 ret = 0;
393 mytartype = -1;
394 /*
395 * The "template header" already includes the "ustar"
396 * signature, various end-of-field markers and other required
397 * elements.
398 */
399 memcpy(h, &template_header, 512);
400
401 /*
402 * Because the block is already null-filled, and strings
403 * are allowed to exactly fill their destination (without null),
404 * I use memcpy(dest, src, strlen()) here a lot to copy strings.
405 */
406 r = archive_entry_pathname_l(entry, &pp, ©_length, sconv);
407 if (r != 0) {
408 if (errno == ENOMEM) {
409 archive_set_error(&a->archive, ENOMEM,
410 "Can't allocate memory for Pathname");
411 return (ARCHIVE_FATAL);
412 }
413 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
414 "Can't translate pathname '%s' to %s",
415 pp, archive_string_conversion_charset_name(sconv));
416 ret = ARCHIVE_WARN;
417 }
418 if (copy_length <= USTAR_name_size)
419 memcpy(h + USTAR_name_offset, pp, copy_length);
420 else {
421 /* Store in two pieces, splitting at a '/'. */
422 p = strchr(pp + copy_length - USTAR_name_size - 1, '/');
423 /*
424 * Look for the next '/' if we chose the first character
425 * as the separator. (ustar format doesn't permit
426 * an empty prefix.)
427 */
428 if (p == pp)
429 p = strchr(p + 1, '/');
430 /* Fail if the name won't fit. */
431 if (!p) {
432 /* No separator. */
433 archive_set_error(&a->archive, ENAMETOOLONG,
434 "Pathname too long");
435 ret = ARCHIVE_FAILED;
436 } else if (p[1] == '\0') {
437 /*
438 * The only feasible separator is a final '/';
439 * this would result in a non-empty prefix and
440 * an empty name, which POSIX doesn't
441 * explicitly forbid, but it just feels wrong.
442 */
443 archive_set_error(&a->archive, ENAMETOOLONG,
444 "Pathname too long");
445 ret = ARCHIVE_FAILED;
446 } else if (p > pp + USTAR_prefix_size) {
447 /* Prefix is too long. */
448 archive_set_error(&a->archive, ENAMETOOLONG,
449 "Pathname too long");
450 ret = ARCHIVE_FAILED;
451 } else {
452 /* Copy prefix and remainder to appropriate places */
453 memcpy(h + USTAR_prefix_offset, pp, p - pp);
454 memcpy(h + USTAR_name_offset, p + 1,
455 pp + copy_length - p - 1);
456 }
457 }
458
459 r = archive_entry_hardlink_l(entry, &p, ©_length, sconv);
460 if (r != 0) {
461 if (errno == ENOMEM) {
462 archive_set_error(&a->archive, ENOMEM,
463 "Can't allocate memory for Linkname");
464 return (ARCHIVE_FATAL);
465 }
466 archive_set_error(&a->archive,
467 ARCHIVE_ERRNO_FILE_FORMAT,
468 "Can't translate linkname '%s' to %s",
469 p, archive_string_conversion_charset_name(sconv));
470 ret = ARCHIVE_WARN;
471 }
472 if (copy_length > 0)
473 mytartype = '1';
474 else {
475 r = archive_entry_symlink_l(entry, &p, ©_length, sconv);
476 if (r != 0) {
477 if (errno == ENOMEM) {
478 archive_set_error(&a->archive, ENOMEM,
479 "Can't allocate memory for Linkname");
480 return (ARCHIVE_FATAL);
481 }
482 archive_set_error(&a->archive,
483 ARCHIVE_ERRNO_FILE_FORMAT,
484 "Can't translate linkname '%s' to %s",
485 p, archive_string_conversion_charset_name(sconv));
486 ret = ARCHIVE_WARN;
487 }
488 }
489 if (copy_length > 0) {
490 if (copy_length > USTAR_linkname_size) {
491 archive_set_error(&a->archive, ENAMETOOLONG,
492 "Link contents too long");
493 ret = ARCHIVE_FAILED;
494 copy_length = USTAR_linkname_size;
495 }
496 memcpy(h + USTAR_linkname_offset, p, copy_length);
497 }
498
499 r = archive_entry_uname_l(entry, &p, ©_length, sconv);
500 if (r != 0) {
501 if (errno == ENOMEM) {
502 archive_set_error(&a->archive, ENOMEM,
503 "Can't allocate memory for Uname");
504 return (ARCHIVE_FATAL);
505 }
506 archive_set_error(&a->archive,
507 ARCHIVE_ERRNO_FILE_FORMAT,
508 "Can't translate uname '%s' to %s",
509 p, archive_string_conversion_charset_name(sconv));
510 ret = ARCHIVE_WARN;
511 }
512 if (copy_length > 0) {
513 if (copy_length > USTAR_uname_size) {
514 if (tartype != 'x') {
515 archive_set_error(&a->archive,
516 ARCHIVE_ERRNO_MISC, "Username too long");
517 ret = ARCHIVE_FAILED;
518 }
519 copy_length = USTAR_uname_size;
520 }
521 memcpy(h + USTAR_uname_offset, p, copy_length);
522 }
523
524 r = archive_entry_gname_l(entry, &p, ©_length, sconv);
525 if (r != 0) {
526 if (errno == ENOMEM) {
527 archive_set_error(&a->archive, ENOMEM,
528 "Can't allocate memory for Gname");
529 return (ARCHIVE_FATAL);
530 }
531 archive_set_error(&a->archive,
532 ARCHIVE_ERRNO_FILE_FORMAT,
533 "Can't translate gname '%s' to %s",
534 p, archive_string_conversion_charset_name(sconv));
535 ret = ARCHIVE_WARN;
536 }
537 if (copy_length > 0) {
538 if (strlen(p) > USTAR_gname_size) {
539 if (tartype != 'x') {
540 archive_set_error(&a->archive,
541 ARCHIVE_ERRNO_MISC, "Group name too long");
542 ret = ARCHIVE_FAILED;
543 }
544 copy_length = USTAR_gname_size;
545 }
546 memcpy(h + USTAR_gname_offset, p, copy_length);
547 }
548
549 if (format_number(archive_entry_mode(entry) & 07777,
550 h + USTAR_mode_offset, USTAR_mode_size, USTAR_mode_max_size, strict)) {
551 archive_set_error(&a->archive, ERANGE,
552 "Numeric mode too large");
553 ret = ARCHIVE_FAILED;
554 }
555
556 if (format_number(archive_entry_uid(entry),
557 h + USTAR_uid_offset, USTAR_uid_size, USTAR_uid_max_size, strict)) {
558 archive_set_error(&a->archive, ERANGE,
559 "Numeric user ID too large");
560 ret = ARCHIVE_FAILED;
561 }
562
563 if (format_number(archive_entry_gid(entry),
564 h + USTAR_gid_offset, USTAR_gid_size, USTAR_gid_max_size, strict)) {
565 archive_set_error(&a->archive, ERANGE,
566 "Numeric group ID too large");
567 ret = ARCHIVE_FAILED;
568 }
569
570 if (format_number(archive_entry_size(entry),
571 h + USTAR_size_offset, USTAR_size_size, USTAR_size_max_size, strict)) {
572 archive_set_error(&a->archive, ERANGE,
573 "File size out of range");
574 ret = ARCHIVE_FAILED;
575 }
576
577 if (format_number(archive_entry_mtime(entry),
578 h + USTAR_mtime_offset, USTAR_mtime_size, USTAR_mtime_max_size, strict)) {
579 archive_set_error(&a->archive, ERANGE,
580 "File modification time too large");
581 ret = ARCHIVE_FAILED;
582 }
583
584 if (archive_entry_filetype(entry) == AE_IFBLK
585 || archive_entry_filetype(entry) == AE_IFCHR) {
586 if (format_number(archive_entry_rdevmajor(entry),
587 h + USTAR_rdevmajor_offset, USTAR_rdevmajor_size,
588 USTAR_rdevmajor_max_size, strict)) {
589 archive_set_error(&a->archive, ERANGE,
590 "Major device number too large");
591 ret = ARCHIVE_FAILED;
592 }
593
594 if (format_number(archive_entry_rdevminor(entry),
595 h + USTAR_rdevminor_offset, USTAR_rdevminor_size,
596 USTAR_rdevminor_max_size, strict)) {
597 archive_set_error(&a->archive, ERANGE,
598 "Minor device number too large");
599 ret = ARCHIVE_FAILED;
600 }
601 }
602
603 if (tartype >= 0) {
604 h[USTAR_typeflag_offset] = tartype;
605 } else if (mytartype >= 0) {
606 h[USTAR_typeflag_offset] = mytartype;
607 } else {
608 switch (archive_entry_filetype(entry)) {
609 case AE_IFREG: h[USTAR_typeflag_offset] = '0' ; break;
610 case AE_IFLNK: h[USTAR_typeflag_offset] = '2' ; break;
611 case AE_IFCHR: h[USTAR_typeflag_offset] = '3' ; break;
612 case AE_IFBLK: h[USTAR_typeflag_offset] = '4' ; break;
613 case AE_IFDIR: h[USTAR_typeflag_offset] = '5' ; break;
614 case AE_IFIFO: h[USTAR_typeflag_offset] = '6' ; break;
615 default: /* AE_IFSOCK and unknown */
616 __archive_write_entry_filetype_unsupported(
617 &a->archive, entry, "ustar");
618 ret = ARCHIVE_FAILED;
619 }
620 }
621
622 checksum = 0;
623 for (i = 0; i < 512; i++)
624 checksum += 255 & (unsigned int)h[i];
625 h[USTAR_checksum_offset + 6] = '\0'; /* Can't be pre-set in the template. */
626 /* h[USTAR_checksum_offset + 7] = ' '; */ /* This is pre-set in the template. */
627 format_octal(checksum, h + USTAR_checksum_offset, 6);
628 return (ret);
629 }
630
631 /*
632 * Format a number into a field, with some intelligence.
633 */
634 static int
format_number(int64_t v,char * p,int s,int maxsize,int strict)635 format_number(int64_t v, char *p, int s, int maxsize, int strict)
636 {
637 int64_t limit;
638
639 limit = ((int64_t)1 << (s*3));
640
641 /* "Strict" only permits octal values with proper termination. */
642 if (strict)
643 return (format_octal(v, p, s));
644
645 /*
646 * In non-strict mode, we allow the number to overwrite one or
647 * more bytes of the field termination. Even old tar
648 * implementations should be able to handle this with no
649 * problem.
650 */
651 if (v >= 0) {
652 while (s <= maxsize) {
653 if (v < limit)
654 return (format_octal(v, p, s));
655 s++;
656 limit <<= 3;
657 }
658 }
659
660 /* Base-256 can handle any number, positive or negative. */
661 return (format_256(v, p, maxsize));
662 }
663
664 /*
665 * Format a number into the specified field using base-256.
666 */
667 static int
format_256(int64_t v,char * p,int s)668 format_256(int64_t v, char *p, int s)
669 {
670 p += s;
671 while (s-- > 0) {
672 *--p = (char)(v & 0xff);
673 v >>= 8;
674 }
675 *p |= 0x80; /* Set the base-256 marker bit. */
676 return (0);
677 }
678
679 /*
680 * Format a number into the specified field.
681 */
682 static int
format_octal(int64_t v,char * p,int s)683 format_octal(int64_t v, char *p, int s)
684 {
685 int len;
686
687 len = s;
688
689 /* Octal values can't be negative, so use 0. */
690 if (v < 0) {
691 while (len-- > 0)
692 *p++ = '0';
693 return (-1);
694 }
695
696 p += s; /* Start at the end and work backwards. */
697 while (s-- > 0) {
698 *--p = (char)('0' + (v & 7));
699 v >>= 3;
700 }
701
702 if (v == 0)
703 return (0);
704
705 /* If it overflowed, fill field with max value. */
706 while (len-- > 0)
707 *p++ = '7';
708
709 return (-1);
710 }
711
712 static int
archive_write_ustar_close(struct archive_write * a)713 archive_write_ustar_close(struct archive_write *a)
714 {
715 return (__archive_write_nulls(a, 512*2));
716 }
717
718 static int
archive_write_ustar_free(struct archive_write * a)719 archive_write_ustar_free(struct archive_write *a)
720 {
721 struct ustar *ustar;
722
723 ustar = (struct ustar *)a->format_data;
724 free(ustar);
725 a->format_data = NULL;
726 return (ARCHIVE_OK);
727 }
728
729 static int
archive_write_ustar_finish_entry(struct archive_write * a)730 archive_write_ustar_finish_entry(struct archive_write *a)
731 {
732 struct ustar *ustar;
733 int ret;
734
735 ustar = (struct ustar *)a->format_data;
736 ret = __archive_write_nulls(a,
737 (size_t)(ustar->entry_bytes_remaining + ustar->entry_padding));
738 ustar->entry_bytes_remaining = ustar->entry_padding = 0;
739 return (ret);
740 }
741
742 static ssize_t
archive_write_ustar_data(struct archive_write * a,const void * buff,size_t s)743 archive_write_ustar_data(struct archive_write *a, const void *buff, size_t s)
744 {
745 struct ustar *ustar;
746 int ret;
747
748 ustar = (struct ustar *)a->format_data;
749 if (s > ustar->entry_bytes_remaining)
750 s = (size_t)ustar->entry_bytes_remaining;
751 ret = __archive_write_output(a, buff, s);
752 ustar->entry_bytes_remaining -= s;
753 if (ret != ARCHIVE_OK)
754 return (ret);
755 return (s);
756 }
757