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: head/lib/libarchive/archive_write_set_format_ustar.c 191579 2009-04-27 18:35:03Z kientzle $");
28
29
30#ifdef HAVE_ERRNO_H
31#include <errno.h>
32#endif
33#include <stdio.h>
34#ifdef HAVE_STDLIB_H
35#include <stdlib.h>
36#endif
37#ifdef HAVE_STRING_H
38#include <string.h>
39#endif
40
41#include "archive.h"
42#include "archive_entry.h"
43#include "archive_private.h"
44#include "archive_write_private.h"
45
46struct ustar {
47	uint64_t	entry_bytes_remaining;
48	uint64_t	entry_padding;
49};
50
51/*
52 * Define structure of POSIX 'ustar' tar header.
53 */
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
95
96/*
97 * A filled-in copy of the header for initialization.
98 */
99static 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,
104	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,
123	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
142};
143
144static ssize_t	archive_write_ustar_data(struct archive_write *a, const void *buff,
145		    size_t s);
146static int	archive_write_ustar_destroy(struct archive_write *);
147static int	archive_write_ustar_finish(struct archive_write *);
148static int	archive_write_ustar_finish_entry(struct archive_write *);
149static int	archive_write_ustar_header(struct archive_write *,
150		    struct archive_entry *entry);
151static int	format_256(int64_t, char *, int);
152static int	format_number(int64_t, char *, int size, int max, int strict);
153static int	format_octal(int64_t, char *, int);
154static int	write_nulls(struct archive_write *a, size_t);
155
156/*
157 * Set output format to 'ustar' format.
158 */
159int
160archive_write_set_format_ustar(struct archive *_a)
161{
162	struct archive_write *a = (struct archive_write *)_a;
163	struct ustar *ustar;
164
165	/* If someone else was already registered, unregister them. */
166	if (a->format_destroy != NULL)
167		(a->format_destroy)(a);
168
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);
173	}
174
175	ustar = (struct ustar *)malloc(sizeof(*ustar));
176	if (ustar == NULL) {
177		archive_set_error(&a->archive, ENOMEM, "Can't allocate ustar data");
178		return (ARCHIVE_FATAL);
179	}
180	memset(ustar, 0, sizeof(*ustar));
181	a->format_data = ustar;
182
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";
192	return (ARCHIVE_OK);
193}
194
195static int
196archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
197{
198	char buff[512];
199	int ret, ret2;
200	struct ustar *ustar;
201
202	ustar = (struct ustar *)a->format_data;
203
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);
209
210	if (AE_IFDIR == archive_entry_filetype(entry)) {
211		const char *p;
212		char *t;
213		/*
214		 * Ensure a trailing '/'.  Modify the entry so
215		 * the client sees the change.
216		 */
217		p = archive_entry_pathname(entry);
218		if (p[strlen(p) - 1] != '/') {
219			t = (char *)malloc(strlen(p) + 2);
220			if (t == NULL) {
221				archive_set_error(&a->archive, ENOMEM,
222				"Can't allocate ustar data");
223				return(ARCHIVE_FATAL);
224			}
225			strcpy(t, p);
226			strcat(t, "/");
227			archive_entry_copy_pathname(entry, t);
228			free(t);
229		}
230	}
231
232	ret = __archive_write_format_header_ustar(a, buff, entry, -1, 1);
233	if (ret < ARCHIVE_WARN)
234		return (ret);
235	ret2 = (a->compressor.write)(a, buff, 512);
236	if (ret2 < ARCHIVE_WARN)
237		return (ret2);
238	if (ret2 < ret)
239		ret = ret2;
240
241	ustar->entry_bytes_remaining = archive_entry_size(entry);
242	ustar->entry_padding = 0x1ff & (-(int64_t)ustar->entry_bytes_remaining);
243	return (ret);
244}
245
246/*
247 * Format a basic 512-byte "ustar" header.
248 *
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).
253 *
254 * This is exported so that other 'tar' formats can use it.
255 */
256int
257__archive_write_format_header_ustar(struct archive_write *a, char h[512],
258    struct archive_entry *entry, int tartype, int strict)
259{
260	unsigned int checksum;
261	int i, ret;
262	size_t copy_length;
263	const char *p, *pp;
264	int mytartype;
265
266	ret = 0;
267	mytartype = -1;
268	/*
269	 * The "template header" already includes the "ustar"
270	 * signature, various end-of-field markers and other required
271	 * elements.
272	 */
273	memcpy(h, &template_header, 512);
274
275	/*
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.
279	 */
280
281	pp = archive_entry_pathname(entry);
282	if (strlen(pp) <= USTAR_name_size)
283		memcpy(h + USTAR_name_offset, pp, strlen(pp));
284	else {
285		/* Store in two pieces, splitting at a '/'. */
286		p = strchr(pp + strlen(pp) - USTAR_name_size - 1, '/');
287		/*
288		 * Look for the next '/' if we chose the first character
289		 * as the separator.  (ustar format doesn't permit
290		 * an empty prefix.)
291		 */
292		if (p == pp)
293			p = strchr(p + 1, '/');
294		/* Fail if the name won't fit. */
295		if (!p) {
296			/* No separator. */
297			archive_set_error(&a->archive, ENAMETOOLONG,
298			    "Pathname too long");
299			ret = ARCHIVE_FAILED;
300		} else if (p[1] == '\0') {
301			/*
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.
306			 */
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;
315		} else {
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);
319		}
320	}
321
322	p = archive_entry_hardlink(entry);
323	if (p != NULL)
324		mytartype = '1';
325	else
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;
334		}
335		memcpy(h + USTAR_linkname_offset, p, copy_length);
336	}
337
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;
346		}
347		memcpy(h + USTAR_uname_offset, p, copy_length);
348	}
349
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;
358		}
359		memcpy(h + USTAR_gname_offset, p, copy_length);
360	}
361
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;
365	}
366
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;
370	}
371
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;
375	}
376
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;
380	}
381
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;
386	}
387
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;
395		}
396
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;
402		}
403	}
404
405	if (tartype >= 0) {
406		h[USTAR_typeflag_offset] = tartype;
407	} else if (mytartype >= 0) {
408		h[USTAR_typeflag_offset] = mytartype;
409	} else {
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;
417		case AE_IFSOCK:
418			archive_set_error(&a->archive,
419			    ARCHIVE_ERRNO_FILE_FORMAT,
420			    "tar format cannot archive socket");
421			return (ARCHIVE_FAILED);
422		default:
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;
428		}
429	}
430
431	checksum = 0;
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);
437	return (ret);
438}
439
440/*
441 * Format a number into a field, with some intelligence.
442 */
443static int
444format_number(int64_t v, char *p, int s, int maxsize, int strict)
445{
446	int64_t limit;
447
448	limit = ((int64_t)1 << (s*3));
449
450	/* "Strict" only permits octal values with proper termination. */
451	if (strict)
452		return (format_octal(v, p, s));
453
454	/*
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
458	 * problem.
459	 */
460	if (v >= 0) {
461		while (s <= maxsize) {
462			if (v < limit)
463				return (format_octal(v, p, s));
464			s++;
465			limit <<= 3;
466		}
467	}
468
469	/* Base-256 can handle any number, positive or negative. */
470	return (format_256(v, p, maxsize));
471}
472
473/*
474 * Format a number into the specified field using base-256.
475 */
476static int
477format_256(int64_t v, char *p, int s)
478{
479	p += s;
480	while (s-- > 0) {
481		*--p = (char)(v & 0xff);
482		v >>= 8;
483	}
484	*p |= 0x80; /* Set the base-256 marker bit. */
485	return (0);
486}
487
488/*
489 * Format a number into the specified field.
490 */
491static int
492format_octal(int64_t v, char *p, int s)
493{
494	int len;
495
496	len = s;
497
498	/* Octal values can't be negative, so use 0. */
499	if (v < 0) {
500		while (len-- > 0)
501			*p++ = '0';
502		return (-1);
503	}
504
505	p += s;		/* Start at the end and work backwards. */
506	while (s-- > 0) {
507		*--p = (char)('0' + (v & 7));
508		v >>= 3;
509	}
510
511	if (v == 0)
512		return (0);
513
514	/* If it overflowed, fill field with max value. */
515	while (len-- > 0)
516		*p++ = '7';
517
518	return (-1);
519}
520
521static int
522archive_write_ustar_finish(struct archive_write *a)
523{
524	int r;
525
526	if (a->compressor.write == NULL)
527		return (ARCHIVE_OK);
528
529	r = write_nulls(a, 512*2);
530	return (r);
531}
532
533static int
534archive_write_ustar_destroy(struct archive_write *a)
535{
536	struct ustar *ustar;
537
538	ustar = (struct ustar *)a->format_data;
539	free(ustar);
540	a->format_data = NULL;
541	return (ARCHIVE_OK);
542}
543
544static int
545archive_write_ustar_finish_entry(struct archive_write *a)
546{
547	struct ustar *ustar;
548	int ret;
549
550	ustar = (struct ustar *)a->format_data;
551	ret = write_nulls(a,
552	    ustar->entry_bytes_remaining + ustar->entry_padding);
553	ustar->entry_bytes_remaining = ustar->entry_padding = 0;
554	return (ret);
555}
556
557static int
558write_nulls(struct archive_write *a, size_t padding)
559{
560	int ret;
561	size_t to_write;
562
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)
567			return (ret);
568		padding -= to_write;
569	}
570	return (ARCHIVE_OK);
571}
572
573static ssize_t
574archive_write_ustar_data(struct archive_write *a, const void *buff, size_t s)
575{
576	struct ustar *ustar;
577	int ret;
578
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)
585		return (ret);
586	return (s);
587}
588