Import libarchive 2.2.1.
[dragonfly.git] / contrib / libarchive-2 / libarchive / archive_write_set_format_ustar.c
1 /*-
2  * Copyright (c) 2003-2007 Tim Kientzle
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
13  *
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.
24  */
25
26 #include "archive_platform.h"
27 __FBSDID("$FreeBSD: src/lib/libarchive/archive_write_set_format_ustar.c,v 1.21 2007/04/02 00:34:36 kientzle Exp $");
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_private.h"
43 #include "archive_write_private.h"
44
45 struct ustar {
46         uint64_t        entry_bytes_remaining;
47         uint64_t        entry_padding;
48 };
49
50 /*
51  * Define structure of POSIX 'ustar' tar header.
52  */
53 #define USTAR_name_offset 0
54 #define USTAR_name_size 100
55 #define USTAR_mode_offset 100
56 #define USTAR_mode_size 6
57 #define USTAR_mode_max_size 8
58 #define USTAR_uid_offset 108
59 #define USTAR_uid_size 6
60 #define USTAR_uid_max_size 8
61 #define USTAR_gid_offset 116
62 #define USTAR_gid_size 6
63 #define USTAR_gid_max_size 8
64 #define USTAR_size_offset 124
65 #define USTAR_size_size 11
66 #define USTAR_size_max_size 12
67 #define USTAR_mtime_offset 136
68 #define USTAR_mtime_size 11
69 #define USTAR_mtime_max_size 11
70 #define USTAR_checksum_offset 148
71 #define USTAR_checksum_size 8
72 #define USTAR_typeflag_offset 156
73 #define USTAR_typeflag_size 1
74 #define USTAR_linkname_offset 157
75 #define USTAR_linkname_size 100
76 #define USTAR_magic_offset 257
77 #define USTAR_magic_size 6
78 #define USTAR_version_offset 263
79 #define USTAR_version_size 2
80 #define USTAR_uname_offset 265
81 #define USTAR_uname_size 32
82 #define USTAR_gname_offset 297
83 #define USTAR_gname_size 32
84 #define USTAR_rdevmajor_offset 329
85 #define USTAR_rdevmajor_size 6
86 #define USTAR_rdevmajor_max_size 8
87 #define USTAR_rdevminor_offset 337
88 #define USTAR_rdevminor_size 6
89 #define USTAR_rdevminor_max_size 8
90 #define USTAR_prefix_offset 345
91 #define USTAR_prefix_size 155
92 #define USTAR_padding_offset 500
93 #define USTAR_padding_size 12
94
95 /*
96  * A filled-in copy of the header for initialization.
97  */
98 static const char template_header[] = {
99         /* name: 100 bytes */
100         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,
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,
104         /* Mode, space-null termination: 8 bytes */
105         '0','0','0','0','0','0', ' ','\0',
106         /* uid, space-null termination: 8 bytes */
107         '0','0','0','0','0','0', ' ','\0',
108         /* gid, space-null termination: 8 bytes */
109         '0','0','0','0','0','0', ' ','\0',
110         /* size, space termation: 12 bytes */
111         '0','0','0','0','0','0','0','0','0','0','0', ' ',
112         /* mtime, space termation: 12 bytes */
113         '0','0','0','0','0','0','0','0','0','0','0', ' ',
114         /* Initial checksum value: 8 spaces */
115         ' ',' ',' ',' ',' ',' ',' ',' ',
116         /* Typeflag: 1 byte */
117         '0',                    /* '0' = regular file */
118         /* Linkname: 100 bytes */
119         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,
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,
123         /* Magic: 6 bytes, Version: 2 bytes */
124         'u','s','t','a','r','\0', '0','0',
125         /* Uname: 32 bytes */
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         /* Gname: 32 bytes */
128         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,
129         /* rdevmajor + space/null padding: 8 bytes */
130         '0','0','0','0','0','0', ' ','\0',
131         /* rdevminor + space/null padding: 8 bytes */
132         '0','0','0','0','0','0', ' ','\0',
133         /* Prefix: 155 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         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,
139         /* Padding: 12 bytes */
140         0,0,0,0,0,0,0,0, 0,0,0,0
141 };
142
143 static ssize_t  archive_write_ustar_data(struct archive_write *a, const void *buff,
144                     size_t s);
145 static int      archive_write_ustar_destroy(struct archive_write *);
146 static int      archive_write_ustar_finish(struct archive_write *);
147 static int      archive_write_ustar_finish_entry(struct archive_write *);
148 static int      archive_write_ustar_header(struct archive_write *,
149                     struct archive_entry *entry);
150 static int      format_256(int64_t, char *, int);
151 static int      format_number(int64_t, char *, int size, int max, int strict);
152 static int      format_octal(int64_t, char *, int);
153 static int      write_nulls(struct archive_write *a, size_t);
154
155 /*
156  * Set output format to 'ustar' format.
157  */
158 int
159 archive_write_set_format_ustar(struct archive *_a)
160 {
161         struct archive_write *a = (struct archive_write *)_a;
162         struct ustar *ustar;
163
164         /* If someone else was already registered, unregister them. */
165         if (a->format_destroy != NULL)
166                 (a->format_destroy)(a);
167
168         /* Basic internal sanity test. */
169         if (sizeof(template_header) != 512) {
170                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Internal: template_header wrong size: %d should be 512", sizeof(template_header));
171                 return (ARCHIVE_FATAL);
172         }
173
174         ustar = (struct ustar *)malloc(sizeof(*ustar));
175         if (ustar == NULL) {
176                 archive_set_error(&a->archive, ENOMEM, "Can't allocate ustar data");
177                 return (ARCHIVE_FATAL);
178         }
179         memset(ustar, 0, sizeof(*ustar));
180         a->format_data = ustar;
181
182         a->pad_uncompressed = 1;        /* Mimic gtar in this respect. */
183         a->format_write_header = archive_write_ustar_header;
184         a->format_write_data = archive_write_ustar_data;
185         a->format_finish = archive_write_ustar_finish;
186         a->format_destroy = archive_write_ustar_destroy;
187         a->format_finish_entry = archive_write_ustar_finish_entry;
188         a->archive_format = ARCHIVE_FORMAT_TAR_USTAR;
189         a->archive_format_name = "POSIX ustar";
190         return (ARCHIVE_OK);
191 }
192
193 static int
194 archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
195 {
196         char buff[512];
197         int ret;
198         struct ustar *ustar;
199
200         ustar = (struct ustar *)a->format_data;
201
202         /* Only regular files (not hardlinks) have data. */
203         if (archive_entry_hardlink(entry) != NULL ||
204             archive_entry_symlink(entry) != NULL ||
205             !(archive_entry_filetype(entry) == AE_IFREG))
206                 archive_entry_set_size(entry, 0);
207
208         if (AE_IFDIR == archive_entry_mode(entry)) {
209                 const char *p;
210                 char *t;
211                 /*
212                  * Ensure a trailing '/'.  Modify the entry so
213                  * the client sees the change.
214                  */
215                 p = archive_entry_pathname(entry);
216                 if (p[strlen(p) - 1] != '/') {
217                         t = (char *)malloc(strlen(p) + 2);
218                         if (t != NULL) {
219                                 strcpy(t, p);
220                                 strcat(t, "/");
221                                 archive_entry_copy_pathname(entry, t);
222                                 free(t);
223                         }
224                 }
225         }
226
227         ret = __archive_write_format_header_ustar(a, buff, entry, -1, 1);
228         if (ret != ARCHIVE_OK)
229                 return (ret);
230         ret = (a->compressor.write)(a, buff, 512);
231         if (ret != ARCHIVE_OK)
232                 return (ret);
233
234         ustar->entry_bytes_remaining = archive_entry_size(entry);
235         ustar->entry_padding = 0x1ff & (-(int64_t)ustar->entry_bytes_remaining);
236         return (ARCHIVE_OK);
237 }
238
239 /*
240  * Format a basic 512-byte "ustar" header.
241  *
242  * Returns -1 if format failed (due to field overflow).
243  * Note that this always formats as much of the header as possible.
244  * If "strict" is set to zero, it will extend numeric fields as
245  * necessary (overwriting terminators or using base-256 extensions).
246  *
247  * This is exported so that other 'tar' formats can use it.
248  */
249 int
250 __archive_write_format_header_ustar(struct archive_write *a, char h[512],
251     struct archive_entry *entry, int tartype, int strict)
252 {
253         unsigned int checksum;
254         int i, ret;
255         size_t copy_length;
256         const char *p, *pp;
257         int mytartype;
258
259         ret = 0;
260         mytartype = -1;
261         /*
262          * The "template header" already includes the "ustar"
263          * signature, various end-of-field markers and other required
264          * elements.
265          */
266         memcpy(h, &template_header, 512);
267
268         /*
269          * Because the block is already null-filled, and strings
270          * are allowed to exactly fill their destination (without null),
271          * I use memcpy(dest, src, strlen()) here a lot to copy strings.
272          */
273
274         pp = archive_entry_pathname(entry);
275         if (strlen(pp) <= USTAR_name_size)
276                 memcpy(h + USTAR_name_offset, pp, strlen(pp));
277         else {
278                 /* Store in two pieces, splitting at a '/'. */
279                 p = strchr(pp + strlen(pp) - USTAR_name_size - 1, '/');
280                 /*
281                  * If there is no path separator, or the prefix or
282                  * remaining name are too large, return an error.
283                  */
284                 if (!p) {
285                         archive_set_error(&a->archive, ENAMETOOLONG,
286                             "Pathname too long");
287                         ret = ARCHIVE_WARN;
288                 } else if (p  > pp + USTAR_prefix_size) {
289                         archive_set_error(&a->archive, ENAMETOOLONG,
290                             "Pathname too long");
291                         ret = ARCHIVE_WARN;
292                 } else {
293                         /* Copy prefix and remainder to appropriate places */
294                         memcpy(h + USTAR_prefix_offset, pp, p - pp);
295                         memcpy(h + USTAR_name_offset, p + 1, pp + strlen(pp) - p - 1);
296                 }
297         }
298
299         p = archive_entry_hardlink(entry);
300         if (p != NULL)
301                 mytartype = '1';
302         else
303                 p = archive_entry_symlink(entry);
304         if (p != NULL && p[0] != '\0') {
305                 copy_length = strlen(p);
306                 if (copy_length > USTAR_linkname_size) {
307                         archive_set_error(&a->archive, ENAMETOOLONG,
308                             "Link contents too long");
309                         ret = ARCHIVE_WARN;
310                         copy_length = USTAR_linkname_size;
311                 }
312                 memcpy(h + USTAR_linkname_offset, p, copy_length);
313         }
314
315         p = archive_entry_uname(entry);
316         if (p != NULL && p[0] != '\0') {
317                 copy_length = strlen(p);
318                 if (copy_length > USTAR_uname_size) {
319                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
320                             "Username too long");
321                         ret = ARCHIVE_WARN;
322                         copy_length = USTAR_uname_size;
323                 }
324                 memcpy(h + USTAR_uname_offset, p, copy_length);
325         }
326
327         p = archive_entry_gname(entry);
328         if (p != NULL && p[0] != '\0') {
329                 copy_length = strlen(p);
330                 if (strlen(p) > USTAR_gname_size) {
331                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
332                             "Group name too long");
333                         ret = ARCHIVE_WARN;
334                         copy_length = USTAR_gname_size;
335                 }
336                 memcpy(h + USTAR_gname_offset, p, copy_length);
337         }
338
339         if (format_number(archive_entry_mode(entry) & 07777, h + USTAR_mode_offset, USTAR_mode_size, USTAR_mode_max_size, strict)) {
340                 archive_set_error(&a->archive, ERANGE, "Numeric mode too large");
341                 ret = ARCHIVE_WARN;
342         }
343
344         if (format_number(archive_entry_uid(entry), h + USTAR_uid_offset, USTAR_uid_size, USTAR_uid_max_size, strict)) {
345                 archive_set_error(&a->archive, ERANGE, "Numeric user ID too large");
346                 ret = ARCHIVE_WARN;
347         }
348
349         if (format_number(archive_entry_gid(entry), h + USTAR_gid_offset, USTAR_gid_size, USTAR_gid_max_size, strict)) {
350                 archive_set_error(&a->archive, ERANGE, "Numeric group ID too large");
351                 ret = ARCHIVE_WARN;
352         }
353
354         if (format_number(archive_entry_size(entry), h + USTAR_size_offset, USTAR_size_size, USTAR_size_max_size, strict)) {
355                 archive_set_error(&a->archive, ERANGE, "File size out of range");
356                 ret = ARCHIVE_WARN;
357         }
358
359         if (format_number(archive_entry_mtime(entry), h + USTAR_mtime_offset, USTAR_mtime_size, USTAR_mtime_max_size, strict)) {
360                 archive_set_error(&a->archive, ERANGE,
361                     "File modification time too large");
362                 ret = ARCHIVE_WARN;
363         }
364
365         if (archive_entry_filetype(entry) == AE_IFBLK
366             || archive_entry_filetype(entry) == AE_IFCHR) {
367                 if (format_number(archive_entry_rdevmajor(entry), h + USTAR_rdevmajor_offset,
368                         USTAR_rdevmajor_size, USTAR_rdevmajor_max_size, strict)) {
369                         archive_set_error(&a->archive, ERANGE,
370                             "Major device number too large");
371                         ret = ARCHIVE_WARN;
372                 }
373
374                 if (format_number(archive_entry_rdevminor(entry), h + USTAR_rdevminor_offset,
375                         USTAR_rdevminor_size, USTAR_rdevminor_max_size, strict)) {
376                         archive_set_error(&a->archive, ERANGE,
377                             "Minor device number too large");
378                         ret = ARCHIVE_WARN;
379                 }
380         }
381
382         if (tartype >= 0) {
383                 h[USTAR_typeflag_offset] = tartype;
384         } else if (mytartype >= 0) {
385                 h[USTAR_typeflag_offset] = mytartype;
386         } else {
387                 switch (archive_entry_filetype(entry)) {
388                 case AE_IFREG: h[USTAR_typeflag_offset] = '0' ; break;
389                 case AE_IFLNK: h[USTAR_typeflag_offset] = '2' ; break;
390                 case AE_IFCHR: h[USTAR_typeflag_offset] = '3' ; break;
391                 case AE_IFBLK: h[USTAR_typeflag_offset] = '4' ; break;
392                 case AE_IFDIR: h[USTAR_typeflag_offset] = '5' ; break;
393                 case AE_IFIFO: h[USTAR_typeflag_offset] = '6' ; break;
394                 default:
395                         archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
396                             "tar format cannot archive this (mode=0%lo)",
397                             (unsigned long)archive_entry_mode(entry));
398                         ret = ARCHIVE_WARN;
399                 }
400         }
401
402         checksum = 0;
403         for (i = 0; i < 512; i++)
404                 checksum += 255 & (unsigned int)h[i];
405         h[USTAR_checksum_offset + 6] = '\0'; /* Can't be pre-set in the template. */
406         /* h[USTAR_checksum_offset + 7] = ' '; */ /* This is pre-set in the template. */
407         format_octal(checksum, h + USTAR_checksum_offset, 6);
408         return (ret);
409 }
410
411 /*
412  * Format a number into a field, with some intelligence.
413  */
414 static int
415 format_number(int64_t v, char *p, int s, int maxsize, int strict)
416 {
417         int64_t limit;
418
419         limit = ((int64_t)1 << (s*3));
420
421         /* "Strict" only permits octal values with proper termination. */
422         if (strict)
423                 return (format_octal(v, p, s));
424
425         /*
426          * In non-strict mode, we allow the number to overwrite one or
427          * more bytes of the field termination.  Even old tar
428          * implementations should be able to handle this with no
429          * problem.
430          */
431         if (v >= 0) {
432                 while (s <= maxsize) {
433                         if (v < limit)
434                                 return (format_octal(v, p, s));
435                         s++;
436                         limit <<= 3;
437                 }
438         }
439
440         /* Base-256 can handle any number, positive or negative. */
441         return (format_256(v, p, maxsize));
442 }
443
444 /*
445  * Format a number into the specified field using base-256.
446  */
447 static int
448 format_256(int64_t v, char *p, int s)
449 {
450         p += s;
451         while (s-- > 0) {
452                 *--p = (char)(v & 0xff);
453                 v >>= 8;
454         }
455         *p |= 0x80; /* Set the base-256 marker bit. */
456         return (0);
457 }
458
459 /*
460  * Format a number into the specified field.
461  */
462 static int
463 format_octal(int64_t v, char *p, int s)
464 {
465         int len;
466
467         len = s;
468
469         /* Octal values can't be negative, so use 0. */
470         if (v < 0) {
471                 while (len-- > 0)
472                         *p++ = '0';
473                 return (-1);
474         }
475
476         p += s;         /* Start at the end and work backwards. */
477         while (s-- > 0) {
478                 *--p = (char)('0' + (v & 7));
479                 v >>= 3;
480         }
481
482         if (v == 0)
483                 return (0);
484
485         /* If it overflowed, fill field with max value. */
486         while (len-- > 0)
487                 *p++ = '7';
488
489         return (-1);
490 }
491
492 static int
493 archive_write_ustar_finish(struct archive_write *a)
494 {
495         int r;
496
497         if (a->compressor.write == NULL)
498                 return (ARCHIVE_OK);
499
500         r = write_nulls(a, 512*2);
501         return (r);
502 }
503
504 static int
505 archive_write_ustar_destroy(struct archive_write *a)
506 {
507         struct ustar *ustar;
508
509         ustar = (struct ustar *)a->format_data;
510         free(ustar);
511         a->format_data = NULL;
512         return (ARCHIVE_OK);
513 }
514
515 static int
516 archive_write_ustar_finish_entry(struct archive_write *a)
517 {
518         struct ustar *ustar;
519         int ret;
520
521         ustar = (struct ustar *)a->format_data;
522         ret = write_nulls(a,
523             ustar->entry_bytes_remaining + ustar->entry_padding);
524         ustar->entry_bytes_remaining = ustar->entry_padding = 0;
525         return (ret);
526 }
527
528 static int
529 write_nulls(struct archive_write *a, size_t padding)
530 {
531         int ret;
532         size_t to_write;
533
534         while (padding > 0) {
535                 to_write = padding < a->null_length ? padding : a->null_length;
536                 ret = (a->compressor.write)(a, a->nulls, to_write);
537                 if (ret != ARCHIVE_OK)
538                         return (ret);
539                 padding -= to_write;
540         }
541         return (ARCHIVE_OK);
542 }
543
544 static ssize_t
545 archive_write_ustar_data(struct archive_write *a, const void *buff, size_t s)
546 {
547         struct ustar *ustar;
548         int ret;
549
550         ustar = (struct ustar *)a->format_data;
551         if (s > ustar->entry_bytes_remaining)
552                 s = ustar->entry_bytes_remaining;
553         ret = (a->compressor.write)(a, buff, s);
554         ustar->entry_bytes_remaining -= s;
555         if (ret != ARCHIVE_OK)
556                 return (ret);
557         return (s);
558 }