2
* Copyright (c) 2003-2007 Tim Kientzle
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
#include "archive_platform.h"
27
__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_ustar.c 191579 2009-04-27 18:35:03Z kientzle $");
42
#include "archive_entry.h"
43
#include "archive_private.h"
44
#include "archive_write_private.h"
47
uint64_t entry_bytes_remaining;
48
uint64_t entry_padding;
52
* Define structure of POSIX 'ustar' tar header.
54
#define USTAR_name_offset 0
55
#define USTAR_name_size 100
56
#define USTAR_mode_offset 100
57
#define USTAR_mode_size 6
58
#define USTAR_mode_max_size 8
59
#define USTAR_uid_offset 108
60
#define USTAR_uid_size 6
61
#define USTAR_uid_max_size 8
62
#define USTAR_gid_offset 116
63
#define USTAR_gid_size 6
64
#define USTAR_gid_max_size 8
65
#define USTAR_size_offset 124
66
#define USTAR_size_size 11
67
#define USTAR_size_max_size 12
68
#define USTAR_mtime_offset 136
69
#define USTAR_mtime_size 11
70
#define USTAR_mtime_max_size 11
71
#define USTAR_checksum_offset 148
72
#define USTAR_checksum_size 8
73
#define USTAR_typeflag_offset 156
74
#define USTAR_typeflag_size 1
75
#define USTAR_linkname_offset 157
76
#define USTAR_linkname_size 100
77
#define USTAR_magic_offset 257
78
#define USTAR_magic_size 6
79
#define USTAR_version_offset 263
80
#define USTAR_version_size 2
81
#define USTAR_uname_offset 265
82
#define USTAR_uname_size 32
83
#define USTAR_gname_offset 297
84
#define USTAR_gname_size 32
85
#define USTAR_rdevmajor_offset 329
86
#define USTAR_rdevmajor_size 6
87
#define USTAR_rdevmajor_max_size 8
88
#define USTAR_rdevminor_offset 337
89
#define USTAR_rdevminor_size 6
90
#define USTAR_rdevminor_max_size 8
91
#define USTAR_prefix_offset 345
92
#define USTAR_prefix_size 155
93
#define USTAR_padding_offset 500
94
#define USTAR_padding_size 12
97
* A filled-in copy of the header for initialization.
99
static const char template_header[] = {
100
/* name: 100 bytes */
101
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,
102
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,
103
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,
105
/* Mode, space-null termination: 8 bytes */
106
'0','0','0','0','0','0', ' ','\0',
107
/* uid, space-null termination: 8 bytes */
108
'0','0','0','0','0','0', ' ','\0',
109
/* gid, space-null termination: 8 bytes */
110
'0','0','0','0','0','0', ' ','\0',
111
/* size, space termation: 12 bytes */
112
'0','0','0','0','0','0','0','0','0','0','0', ' ',
113
/* mtime, space termation: 12 bytes */
114
'0','0','0','0','0','0','0','0','0','0','0', ' ',
115
/* Initial checksum value: 8 spaces */
116
' ',' ',' ',' ',' ',' ',' ',' ',
117
/* Typeflag: 1 byte */
118
'0', /* '0' = regular file */
119
/* Linkname: 100 bytes */
120
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,
121
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,
122
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,
124
/* Magic: 6 bytes, Version: 2 bytes */
125
'u','s','t','a','r','\0', '0','0',
126
/* Uname: 32 bytes */
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
/* Gname: 32 bytes */
129
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,
130
/* rdevmajor + space/null padding: 8 bytes */
131
'0','0','0','0','0','0', ' ','\0',
132
/* rdevminor + space/null padding: 8 bytes */
133
'0','0','0','0','0','0', ' ','\0',
134
/* Prefix: 155 bytes */
135
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,
136
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,
137
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,
138
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,
139
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,
140
/* Padding: 12 bytes */
141
0,0,0,0,0,0,0,0, 0,0,0,0
144
static ssize_t archive_write_ustar_data(struct archive_write *a, const void *buff,
146
static int archive_write_ustar_destroy(struct archive_write *);
147
static int archive_write_ustar_finish(struct archive_write *);
148
static int archive_write_ustar_finish_entry(struct archive_write *);
149
static int archive_write_ustar_header(struct archive_write *,
150
struct archive_entry *entry);
151
static int format_256(int64_t, char *, int);
152
static int format_number(int64_t, char *, int size, int max, int strict);
153
static int format_octal(int64_t, char *, int);
154
static int write_nulls(struct archive_write *a, size_t);
157
* Set output format to 'ustar' format.
160
archive_write_set_format_ustar(struct archive *_a)
162
struct archive_write *a = (struct archive_write *)_a;
165
/* If someone else was already registered, unregister them. */
166
if (a->format_destroy != NULL)
167
(a->format_destroy)(a);
169
/* Basic internal sanity test. */
170
if (sizeof(template_header) != 512) {
171
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Internal: template_header wrong size: %d should be 512", sizeof(template_header));
172
return (ARCHIVE_FATAL);
175
ustar = (struct ustar *)malloc(sizeof(*ustar));
177
archive_set_error(&a->archive, ENOMEM, "Can't allocate ustar data");
178
return (ARCHIVE_FATAL);
180
memset(ustar, 0, sizeof(*ustar));
181
a->format_data = ustar;
183
a->pad_uncompressed = 1; /* Mimic gtar in this respect. */
184
a->format_name = "ustar";
185
a->format_write_header = archive_write_ustar_header;
186
a->format_write_data = archive_write_ustar_data;
187
a->format_finish = archive_write_ustar_finish;
188
a->format_destroy = archive_write_ustar_destroy;
189
a->format_finish_entry = archive_write_ustar_finish_entry;
190
a->archive.archive_format = ARCHIVE_FORMAT_TAR_USTAR;
191
a->archive.archive_format_name = "POSIX ustar";
196
archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
202
ustar = (struct ustar *)a->format_data;
204
/* Only regular files (not hardlinks) have data. */
205
if (archive_entry_hardlink(entry) != NULL ||
206
archive_entry_symlink(entry) != NULL ||
207
!(archive_entry_filetype(entry) == AE_IFREG))
208
archive_entry_set_size(entry, 0);
210
if (AE_IFDIR == archive_entry_filetype(entry)) {
214
* Ensure a trailing '/'. Modify the entry so
215
* the client sees the change.
217
p = archive_entry_pathname(entry);
218
if (p[strlen(p) - 1] != '/') {
219
t = (char *)malloc(strlen(p) + 2);
221
archive_set_error(&a->archive, ENOMEM,
222
"Can't allocate ustar data");
223
return(ARCHIVE_FATAL);
227
archive_entry_copy_pathname(entry, t);
232
ret = __archive_write_format_header_ustar(a, buff, entry, -1, 1);
233
if (ret < ARCHIVE_WARN)
235
ret2 = (a->compressor.write)(a, buff, 512);
236
if (ret2 < ARCHIVE_WARN)
241
ustar->entry_bytes_remaining = archive_entry_size(entry);
242
ustar->entry_padding = 0x1ff & (-(int64_t)ustar->entry_bytes_remaining);
247
* Format a basic 512-byte "ustar" header.
249
* Returns -1 if format failed (due to field overflow).
250
* Note that this always formats as much of the header as possible.
251
* If "strict" is set to zero, it will extend numeric fields as
252
* necessary (overwriting terminators or using base-256 extensions).
254
* This is exported so that other 'tar' formats can use it.
257
__archive_write_format_header_ustar(struct archive_write *a, char h[512],
258
struct archive_entry *entry, int tartype, int strict)
260
unsigned int checksum;
269
* The "template header" already includes the "ustar"
270
* signature, various end-of-field markers and other required
273
memcpy(h, &template_header, 512);
276
* Because the block is already null-filled, and strings
277
* are allowed to exactly fill their destination (without null),
278
* I use memcpy(dest, src, strlen()) here a lot to copy strings.
281
pp = archive_entry_pathname(entry);
282
if (strlen(pp) <= USTAR_name_size)
283
memcpy(h + USTAR_name_offset, pp, strlen(pp));
285
/* Store in two pieces, splitting at a '/'. */
286
p = strchr(pp + strlen(pp) - USTAR_name_size - 1, '/');
288
* Look for the next '/' if we chose the first character
289
* as the separator. (ustar format doesn't permit
293
p = strchr(p + 1, '/');
294
/* Fail if the name won't fit. */
297
archive_set_error(&a->archive, ENAMETOOLONG,
298
"Pathname too long");
299
ret = ARCHIVE_FAILED;
300
} else if (p[1] == '\0') {
302
* The only feasible separator is a final '/';
303
* this would result in a non-empty prefix and
304
* an empty name, which POSIX doesn't
305
* explicity forbid, but it just feels wrong.
307
archive_set_error(&a->archive, ENAMETOOLONG,
308
"Pathname too long");
309
ret = ARCHIVE_FAILED;
310
} else if (p > pp + USTAR_prefix_size) {
311
/* Prefix is too long. */
312
archive_set_error(&a->archive, ENAMETOOLONG,
313
"Pathname too long");
314
ret = ARCHIVE_FAILED;
316
/* Copy prefix and remainder to appropriate places */
317
memcpy(h + USTAR_prefix_offset, pp, p - pp);
318
memcpy(h + USTAR_name_offset, p + 1, pp + strlen(pp) - p - 1);
322
p = archive_entry_hardlink(entry);
326
p = archive_entry_symlink(entry);
327
if (p != NULL && p[0] != '\0') {
328
copy_length = strlen(p);
329
if (copy_length > USTAR_linkname_size) {
330
archive_set_error(&a->archive, ENAMETOOLONG,
331
"Link contents too long");
332
ret = ARCHIVE_FAILED;
333
copy_length = USTAR_linkname_size;
335
memcpy(h + USTAR_linkname_offset, p, copy_length);
338
p = archive_entry_uname(entry);
339
if (p != NULL && p[0] != '\0') {
340
copy_length = strlen(p);
341
if (copy_length > USTAR_uname_size) {
342
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
343
"Username too long");
344
ret = ARCHIVE_FAILED;
345
copy_length = USTAR_uname_size;
347
memcpy(h + USTAR_uname_offset, p, copy_length);
350
p = archive_entry_gname(entry);
351
if (p != NULL && p[0] != '\0') {
352
copy_length = strlen(p);
353
if (strlen(p) > USTAR_gname_size) {
354
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
355
"Group name too long");
356
ret = ARCHIVE_FAILED;
357
copy_length = USTAR_gname_size;
359
memcpy(h + USTAR_gname_offset, p, copy_length);
362
if (format_number(archive_entry_mode(entry) & 07777, h + USTAR_mode_offset, USTAR_mode_size, USTAR_mode_max_size, strict)) {
363
archive_set_error(&a->archive, ERANGE, "Numeric mode too large");
364
ret = ARCHIVE_FAILED;
367
if (format_number(archive_entry_uid(entry), h + USTAR_uid_offset, USTAR_uid_size, USTAR_uid_max_size, strict)) {
368
archive_set_error(&a->archive, ERANGE, "Numeric user ID too large");
369
ret = ARCHIVE_FAILED;
372
if (format_number(archive_entry_gid(entry), h + USTAR_gid_offset, USTAR_gid_size, USTAR_gid_max_size, strict)) {
373
archive_set_error(&a->archive, ERANGE, "Numeric group ID too large");
374
ret = ARCHIVE_FAILED;
377
if (format_number(archive_entry_size(entry), h + USTAR_size_offset, USTAR_size_size, USTAR_size_max_size, strict)) {
378
archive_set_error(&a->archive, ERANGE, "File size out of range");
379
ret = ARCHIVE_FAILED;
382
if (format_number(archive_entry_mtime(entry), h + USTAR_mtime_offset, USTAR_mtime_size, USTAR_mtime_max_size, strict)) {
383
archive_set_error(&a->archive, ERANGE,
384
"File modification time too large");
385
ret = ARCHIVE_FAILED;
388
if (archive_entry_filetype(entry) == AE_IFBLK
389
|| archive_entry_filetype(entry) == AE_IFCHR) {
390
if (format_number(archive_entry_rdevmajor(entry), h + USTAR_rdevmajor_offset,
391
USTAR_rdevmajor_size, USTAR_rdevmajor_max_size, strict)) {
392
archive_set_error(&a->archive, ERANGE,
393
"Major device number too large");
394
ret = ARCHIVE_FAILED;
397
if (format_number(archive_entry_rdevminor(entry), h + USTAR_rdevminor_offset,
398
USTAR_rdevminor_size, USTAR_rdevminor_max_size, strict)) {
399
archive_set_error(&a->archive, ERANGE,
400
"Minor device number too large");
401
ret = ARCHIVE_FAILED;
406
h[USTAR_typeflag_offset] = tartype;
407
} else if (mytartype >= 0) {
408
h[USTAR_typeflag_offset] = mytartype;
410
switch (archive_entry_filetype(entry)) {
411
case AE_IFREG: h[USTAR_typeflag_offset] = '0' ; break;
412
case AE_IFLNK: h[USTAR_typeflag_offset] = '2' ; break;
413
case AE_IFCHR: h[USTAR_typeflag_offset] = '3' ; break;
414
case AE_IFBLK: h[USTAR_typeflag_offset] = '4' ; break;
415
case AE_IFDIR: h[USTAR_typeflag_offset] = '5' ; break;
416
case AE_IFIFO: h[USTAR_typeflag_offset] = '6' ; break;
418
archive_set_error(&a->archive,
419
ARCHIVE_ERRNO_FILE_FORMAT,
420
"tar format cannot archive socket");
421
return (ARCHIVE_FAILED);
423
archive_set_error(&a->archive,
424
ARCHIVE_ERRNO_FILE_FORMAT,
425
"tar format cannot archive this (mode=0%lo)",
426
(unsigned long)archive_entry_mode(entry));
427
ret = ARCHIVE_FAILED;
432
for (i = 0; i < 512; i++)
433
checksum += 255 & (unsigned int)h[i];
434
h[USTAR_checksum_offset + 6] = '\0'; /* Can't be pre-set in the template. */
435
/* h[USTAR_checksum_offset + 7] = ' '; */ /* This is pre-set in the template. */
436
format_octal(checksum, h + USTAR_checksum_offset, 6);
441
* Format a number into a field, with some intelligence.
444
format_number(int64_t v, char *p, int s, int maxsize, int strict)
448
limit = ((int64_t)1 << (s*3));
450
/* "Strict" only permits octal values with proper termination. */
452
return (format_octal(v, p, s));
455
* In non-strict mode, we allow the number to overwrite one or
456
* more bytes of the field termination. Even old tar
457
* implementations should be able to handle this with no
461
while (s <= maxsize) {
463
return (format_octal(v, p, s));
469
/* Base-256 can handle any number, positive or negative. */
470
return (format_256(v, p, maxsize));
474
* Format a number into the specified field using base-256.
477
format_256(int64_t v, char *p, int s)
481
*--p = (char)(v & 0xff);
484
*p |= 0x80; /* Set the base-256 marker bit. */
489
* Format a number into the specified field.
492
format_octal(int64_t v, char *p, int s)
498
/* Octal values can't be negative, so use 0. */
505
p += s; /* Start at the end and work backwards. */
507
*--p = (char)('0' + (v & 7));
514
/* If it overflowed, fill field with max value. */
522
archive_write_ustar_finish(struct archive_write *a)
526
if (a->compressor.write == NULL)
529
r = write_nulls(a, 512*2);
534
archive_write_ustar_destroy(struct archive_write *a)
538
ustar = (struct ustar *)a->format_data;
540
a->format_data = NULL;
545
archive_write_ustar_finish_entry(struct archive_write *a)
550
ustar = (struct ustar *)a->format_data;
552
ustar->entry_bytes_remaining + ustar->entry_padding);
553
ustar->entry_bytes_remaining = ustar->entry_padding = 0;
558
write_nulls(struct archive_write *a, size_t padding)
563
while (padding > 0) {
564
to_write = padding < a->null_length ? padding : a->null_length;
565
ret = (a->compressor.write)(a, a->nulls, to_write);
566
if (ret != ARCHIVE_OK)
574
archive_write_ustar_data(struct archive_write *a, const void *buff, size_t s)
579
ustar = (struct ustar *)a->format_data;
580
if (s > ustar->entry_bytes_remaining)
581
s = ustar->entry_bytes_remaining;
582
ret = (a->compressor.write)(a, buff, s);
583
ustar->entry_bytes_remaining -= s;
584
if (ret != ARCHIVE_OK)