1 /*-
2  * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
3  * Author: Jonas Gastal <jgastal@profusion.mobi>
4  * Copyright (c) 2011 Michihiro NAKAJIMA
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "archive_platform.h"
30 __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_gnu_tar.c 191579 2009-04-27 18:35:03Z gastal $");
31 
32 
33 #ifdef HAVE_ERRNO_H
34 #include <errno.h>
35 #endif
36 #include <stdio.h>
37 #ifdef HAVE_STDLIB_H
38 #include <stdlib.h>
39 #endif
40 #ifdef HAVE_STRING_H
41 #include <string.h>
42 #endif
43 
44 #include "archive.h"
45 #include "archive_entry.h"
46 #include "archive_entry_locale.h"
47 #include "archive_private.h"
48 #include "archive_write_private.h"
49 
50 struct gnutar {
51 	uint64_t	entry_bytes_remaining;
52 	uint64_t	entry_padding;
53 	const char *	linkname;
54 	size_t		linkname_length;
55 	const char *	pathname;
56 	size_t		pathname_length;
57 	const char *	uname;
58 	size_t		uname_length;
59 	const char *	gname;
60 	size_t		gname_length;
61 	struct archive_string_conv *opt_sconv;
62 	struct archive_string_conv *sconv_default;
63 	int init_default_conversion;
64 };
65 
66 /*
67  * Define structure of GNU tar header.
68  */
69 #define	GNUTAR_name_offset 0
70 #define	GNUTAR_name_size 100
71 #define	GNUTAR_mode_offset 100
72 #define	GNUTAR_mode_size 7
73 #define	GNUTAR_mode_max_size 8
74 #define	GNUTAR_uid_offset 108
75 #define	GNUTAR_uid_size 7
76 #define	GNUTAR_uid_max_size 8
77 #define	GNUTAR_gid_offset 116
78 #define	GNUTAR_gid_size 7
79 #define	GNUTAR_gid_max_size 8
80 #define	GNUTAR_size_offset 124
81 #define	GNUTAR_size_size 11
82 #define	GNUTAR_size_max_size 12
83 #define	GNUTAR_mtime_offset 136
84 #define	GNUTAR_mtime_size 11
85 #define	GNUTAR_mtime_max_size 11
86 #define	GNUTAR_checksum_offset 148
87 #define	GNUTAR_checksum_size 8
88 #define	GNUTAR_typeflag_offset 156
89 #define	GNUTAR_typeflag_size 1
90 #define	GNUTAR_linkname_offset 157
91 #define	GNUTAR_linkname_size 100
92 #define	GNUTAR_magic_offset 257
93 #define	GNUTAR_magic_size 6
94 #define	GNUTAR_version_offset 263
95 #define	GNUTAR_version_size 2
96 #define	GNUTAR_uname_offset 265
97 #define	GNUTAR_uname_size 32
98 #define	GNUTAR_gname_offset 297
99 #define	GNUTAR_gname_size 32
100 #define	GNUTAR_rdevmajor_offset 329
101 #define	GNUTAR_rdevmajor_size 6
102 #define	GNUTAR_rdevmajor_max_size 8
103 #define	GNUTAR_rdevminor_offset 337
104 #define	GNUTAR_rdevminor_size 6
105 #define	GNUTAR_rdevminor_max_size 8
106 
107 /*
108  * A filled-in copy of the header for initialization.
109  */
110 static const char template_header[] = {
111 	/* name: 100 bytes */
112 	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
113 	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
114 	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
115 	0,0,0,0,
116 	/* Mode, null termination: 8 bytes */
117 	'0','0','0','0','0','0', '0','\0',
118 	/* uid, null termination: 8 bytes */
119 	'0','0','0','0','0','0', '0','\0',
120 	/* gid, null termination: 8 bytes */
121 	'0','0','0','0','0','0', '0','\0',
122 	/* size, space termation: 12 bytes */
123 	'0','0','0','0','0','0','0','0','0','0','0', '\0',
124 	/* mtime, space termation: 12 bytes */
125 	'0','0','0','0','0','0','0','0','0','0','0', '\0',
126 	/* Initial checksum value: 8 spaces */
127 	' ',' ',' ',' ',' ',' ',' ',' ',
128 	/* Typeflag: 1 byte */
129 	'0',			/* '0' = regular file */
130 	/* Linkname: 100 bytes */
131 	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
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 	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
134 	0,0,0,0,
135 	/* Magic: 8 bytes */
136 	'u','s','t','a','r',' ', ' ','\0',
137 	/* Uname: 32 bytes */
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 	/* Gname: 32 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 	/* rdevmajor + null padding: 8 bytes */
142 	'\0','\0','\0','\0','\0','\0', '\0','\0',
143 	/* rdevminor + null padding: 8 bytes */
144 	'\0','\0','\0','\0','\0','\0', '\0','\0',
145 	/* Padding: 167 bytes */
146 	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
147 	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
148 	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
149 	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
150 	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
151 	0,0,0,0,0,0,0
152 };
153 
154 static int      archive_write_gnutar_options(struct archive_write *,
155 		    const char *, const char *);
156 static int	archive_format_gnutar_header(struct archive_write *, char h[512],
157 		    struct archive_entry *, int tartype);
158 static int      archive_write_gnutar_header(struct archive_write *,
159 		    struct archive_entry *entry);
160 static ssize_t	archive_write_gnutar_data(struct archive_write *a, const void *buff,
161 		    size_t s);
162 static int	archive_write_gnutar_free(struct archive_write *);
163 static int	archive_write_gnutar_close(struct archive_write *);
164 static int	archive_write_gnutar_finish_entry(struct archive_write *);
165 static int	format_256(int64_t, char *, int);
166 static int	format_number(int64_t, char *, int size, int maxsize);
167 static int	format_octal(int64_t, char *, int);
168 
169 /*
170  * Set output format to 'GNU tar' format.
171  */
172 int
173 archive_write_set_format_gnutar(struct archive *_a)
174 {
175 	struct archive_write *a = (struct archive_write *)_a;
176 	struct gnutar *gnutar;
177 
178 	gnutar = (struct gnutar *)calloc(1, sizeof(*gnutar));
179 	if (gnutar == NULL) {
180 		archive_set_error(&a->archive, ENOMEM, "Can't allocate gnutar data");
181 		return (ARCHIVE_FATAL);
182 	}
183 	a->format_data = gnutar;
184 	a->format_name = "gnutar";
185 	a->format_options = archive_write_gnutar_options;
186 	a->format_write_header = archive_write_gnutar_header;
187 	a->format_write_data = archive_write_gnutar_data;
188 	a->format_close = archive_write_gnutar_close;
189 	a->format_free = archive_write_gnutar_free;
190 	a->format_finish_entry = archive_write_gnutar_finish_entry;
191 	a->archive.archive_format = ARCHIVE_FORMAT_TAR_GNUTAR;
192 	a->archive.archive_format_name = "GNU tar";
193 	return (ARCHIVE_OK);
194 }
195 
196 static int
197 archive_write_gnutar_options(struct archive_write *a, const char *key,
198     const char *val)
199 {
200 	struct gnutar *gnutar = (struct gnutar *)a->format_data;
201 	int ret = ARCHIVE_FAILED;
202 
203 	if (strcmp(key, "hdrcharset")  == 0) {
204 		if (val == NULL || val[0] == 0)
205 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
206 			    "%s: hdrcharset option needs a character-set name",
207 			    a->format_name);
208 		else {
209 			gnutar->opt_sconv = archive_string_conversion_to_charset(
210 			    &a->archive, val, 0);
211 			if (gnutar->opt_sconv != NULL)
212 				ret = ARCHIVE_OK;
213 			else
214 				ret = ARCHIVE_FATAL;
215 		}
216 	} else
217 		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
218 		    "%s: unknown keyword ``%s''", a->format_name, key);
219 
220 	return (ret);
221 }
222 
223 static int
224 archive_write_gnutar_close(struct archive_write *a)
225 {
226 	return (__archive_write_nulls(a, 512*2));
227 }
228 
229 static int
230 archive_write_gnutar_free(struct archive_write *a)
231 {
232 	struct gnutar *gnutar;
233 
234 	gnutar = (struct gnutar *)a->format_data;
235 	free(gnutar);
236 	a->format_data = NULL;
237 	return (ARCHIVE_OK);
238 }
239 
240 static int
241 archive_write_gnutar_finish_entry(struct archive_write *a)
242 {
243 	struct gnutar *gnutar;
244 	int ret;
245 
246 	gnutar = (struct gnutar *)a->format_data;
247 	ret = __archive_write_nulls(a,
248 	    gnutar->entry_bytes_remaining + gnutar->entry_padding);
249 	gnutar->entry_bytes_remaining = gnutar->entry_padding = 0;
250 	return (ret);
251 }
252 
253 static ssize_t
254 archive_write_gnutar_data(struct archive_write *a, const void *buff, size_t s)
255 {
256 	struct gnutar *gnutar;
257 	int ret;
258 
259 	gnutar = (struct gnutar *)a->format_data;
260 	if (s > gnutar->entry_bytes_remaining)
261 		s = gnutar->entry_bytes_remaining;
262 	ret = __archive_write_output(a, buff, s);
263 	gnutar->entry_bytes_remaining -= s;
264 	if (ret != ARCHIVE_OK)
265 		return (ret);
266 	return (s);
267 }
268 
269 static int
270 archive_write_gnutar_header(struct archive_write *a,
271      struct archive_entry *entry)
272 {
273 	char buff[512];
274 	int r, ret, ret2 = ARCHIVE_OK;
275 	int tartype;
276 	struct gnutar *gnutar;
277 	struct archive_string_conv *sconv;
278 
279 	gnutar = (struct gnutar *)a->format_data;
280 
281 	/* Setup default string conversion. */
282 	if (gnutar->opt_sconv == NULL) {
283 		if (!gnutar->init_default_conversion) {
284 			gnutar->sconv_default =
285 			    archive_string_default_conversion_for_write(
286 				&(a->archive));
287 			gnutar->init_default_conversion = 1;
288 		}
289 		sconv = gnutar->sconv_default;
290 	} else
291 		sconv = gnutar->opt_sconv;
292 
293 	/* Only regular files (not hardlinks) have data. */
294 	if (archive_entry_hardlink(entry) != NULL ||
295 	    archive_entry_symlink(entry) != NULL ||
296 	    !(archive_entry_filetype(entry) == AE_IFREG))
297 		archive_entry_set_size(entry, 0);
298 
299 	if (AE_IFDIR == archive_entry_filetype(entry)) {
300 		const char *p;
301 		char *t;
302 		/*
303 		 * Ensure a trailing '/'.  Modify the entry so
304 		 * the client sees the change.
305 		 */
306 		p = archive_entry_pathname(entry);
307 		if (p[strlen(p) - 1] != '/') {
308 			t = (char *)malloc(strlen(p) + 2);
309 			if (t == NULL) {
310 				archive_set_error(&a->archive, ENOMEM,
311 				"Can't allocate gnutar data");
312 				return(ARCHIVE_FATAL);
313 			}
314 			strcpy(t, p);
315 			strcat(t, "/");
316 			archive_entry_copy_pathname(entry, t);
317 			free(t);
318 		}
319 	}
320 
321 	r = archive_entry_pathname_l(entry, &(gnutar->pathname),
322 	    &(gnutar->pathname_length), sconv);
323 	if (r != 0) {
324 		if (errno == ENOMEM) {
325 			archive_set_error(&a->archive, ENOMEM,
326 			    "Can't allocate memory for Pathame");
327 			return (ARCHIVE_FATAL);
328 		}
329 		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
330 		    "Can't translate pathname '%s' to %s",
331 		    archive_entry_pathname(entry),
332 		    archive_string_conversion_charset_name(sconv));
333 		ret2 = ARCHIVE_WARN;
334 	}
335 	r = archive_entry_uname_l(entry, &(gnutar->uname),
336 	    &(gnutar->uname_length), sconv);
337 	if (r != 0) {
338 		if (errno == ENOMEM) {
339 			archive_set_error(&a->archive, ENOMEM,
340 			    "Can't allocate memory for Uname");
341 			return (ARCHIVE_FATAL);
342 		}
343 		archive_set_error(&a->archive,
344 		    ARCHIVE_ERRNO_FILE_FORMAT,
345 		    "Can't translate uname '%s' to %s",
346 		    archive_entry_uname(entry),
347 		    archive_string_conversion_charset_name(sconv));
348 		ret2 = ARCHIVE_WARN;
349 	}
350 	r = archive_entry_gname_l(entry, &(gnutar->gname),
351 	    &(gnutar->gname_length), sconv);
352 	if (r != 0) {
353 		if (errno == ENOMEM) {
354 			archive_set_error(&a->archive, ENOMEM,
355 			    "Can't allocate memory for Gname");
356 			return (ARCHIVE_FATAL);
357 		}
358 		archive_set_error(&a->archive,
359 		    ARCHIVE_ERRNO_FILE_FORMAT,
360 		    "Can't translate gname '%s' to %s",
361 		    archive_entry_gname(entry),
362 		    archive_string_conversion_charset_name(sconv));
363 		ret2 = ARCHIVE_WARN;
364 	}
365 
366 	/* If linkname is longer than 100 chars we need to add a 'K' header. */
367 	r = archive_entry_hardlink_l(entry, &(gnutar->linkname),
368 	    &(gnutar->linkname_length), sconv);
369 	if (r != 0) {
370 		if (errno == ENOMEM) {
371 			archive_set_error(&a->archive, ENOMEM,
372 			    "Can't allocate memory for Linkname");
373 			return (ARCHIVE_FATAL);
374 		}
375 		archive_set_error(&a->archive,
376 		    ARCHIVE_ERRNO_FILE_FORMAT,
377 		    "Can't translate linkname '%s' to %s",
378 		    archive_entry_hardlink(entry),
379 		    archive_string_conversion_charset_name(sconv));
380 		ret2 = ARCHIVE_WARN;
381 	}
382 	if (gnutar->linkname_length == 0) {
383 		r = archive_entry_symlink_l(entry, &(gnutar->linkname),
384 		    &(gnutar->linkname_length), sconv);
385 		if (r != 0) {
386 			if (errno == ENOMEM) {
387 				archive_set_error(&a->archive, ENOMEM,
388 				    "Can't allocate memory for Linkname");
389 				return (ARCHIVE_FATAL);
390 			}
391 			archive_set_error(&a->archive,
392 			    ARCHIVE_ERRNO_FILE_FORMAT,
393 			    "Can't translate linkname '%s' to %s",
394 			    archive_entry_hardlink(entry),
395 			    archive_string_conversion_charset_name(sconv));
396 			ret2 = ARCHIVE_WARN;
397 		}
398 	}
399 	if (gnutar->linkname_length > GNUTAR_linkname_size) {
400 		size_t todo = gnutar->linkname_length;
401 		struct archive_entry *temp = archive_entry_new2(&a->archive);
402 
403 		/* Uname/gname here don't really matter since no one reads them;
404 		 * these are the values that GNU tar happens to use on FreeBSD. */
405 		archive_entry_set_uname(temp, "root");
406 		archive_entry_set_gname(temp, "wheel");
407 
408 		archive_entry_set_pathname(temp, "././@LongLink");
409 		archive_entry_set_size(temp, gnutar->linkname_length + 1);
410 		ret = archive_format_gnutar_header(a, buff, temp, 'K');
411 		if (ret < ARCHIVE_WARN)
412 			return (ret);
413 		ret = __archive_write_output(a, buff, 512);
414 		if(ret < ARCHIVE_WARN)
415 			return (ret);
416 		archive_entry_free(temp);
417 		/* Write as many 512 bytes blocks as needed to write full name. */
418 		ret = __archive_write_output(a, gnutar->linkname, todo);
419 		if(ret < ARCHIVE_WARN)
420 			return (ret);
421 		ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)todo));
422 		if (ret < ARCHIVE_WARN)
423 			return (ret);
424 	}
425 
426 	/* If pathname is longer than 100 chars we need to add an 'L' header. */
427 	if (gnutar->pathname_length > GNUTAR_name_size) {
428 		const char *pathname = gnutar->pathname;
429 		size_t todo = gnutar->pathname_length;
430 		struct archive_entry *temp = archive_entry_new2(&a->archive);
431 
432 		/* Uname/gname here don't really matter since no one reads them;
433 		 * these are the values that GNU tar happens to use on FreeBSD. */
434 		archive_entry_set_uname(temp, "root");
435 		archive_entry_set_gname(temp, "wheel");
436 
437 		archive_entry_set_pathname(temp, "././@LongLink");
438 		archive_entry_set_size(temp, gnutar->pathname_length + 1);
439 		ret = archive_format_gnutar_header(a, buff, temp, 'L');
440 		if (ret < ARCHIVE_WARN)
441 			return (ret);
442 		ret = __archive_write_output(a, buff, 512);
443 		if(ret < ARCHIVE_WARN)
444 			return (ret);
445 		archive_entry_free(temp);
446 		/* Write as many 512 bytes blocks as needed to write full name. */
447 		ret = __archive_write_output(a, pathname, todo);
448 		if(ret < ARCHIVE_WARN)
449 			return (ret);
450 		ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)todo));
451 		if (ret < ARCHIVE_WARN)
452 			return (ret);
453 	}
454 
455 	if (archive_entry_hardlink(entry) != NULL) {
456 		tartype = '1';
457 	} else
458 		switch (archive_entry_filetype(entry)) {
459 		case AE_IFREG: tartype = '0' ; break;
460 		case AE_IFLNK: tartype = '2' ; break;
461 		case AE_IFCHR: tartype = '3' ; break;
462 		case AE_IFBLK: tartype = '4' ; break;
463 		case AE_IFDIR: tartype = '5' ; break;
464 		case AE_IFIFO: tartype = '6' ; break;
465 		case AE_IFSOCK:
466 			archive_set_error(&a->archive,
467 			    ARCHIVE_ERRNO_FILE_FORMAT,
468 			    "tar format cannot archive socket");
469 			return (ARCHIVE_FAILED);
470 		default:
471 			archive_set_error(&a->archive,
472 			    ARCHIVE_ERRNO_FILE_FORMAT,
473 			    "tar format cannot archive this (mode=0%lo)",
474 			    (unsigned long)archive_entry_mode(entry));
475 			return (ARCHIVE_FAILED);
476 		}
477 
478 	ret = archive_format_gnutar_header(a, buff, entry, tartype);
479 	if (ret < ARCHIVE_WARN)
480 		return (ret);
481 	if (ret2 < ret)
482 		ret = ret2;
483 	ret2 = __archive_write_output(a, buff, 512);
484 	if (ret2 < ARCHIVE_WARN)
485 		return (ret2);
486 	if (ret2 < ret)
487 		ret = ret2;
488 
489 	gnutar->entry_bytes_remaining = archive_entry_size(entry);
490 	gnutar->entry_padding = 0x1ff & (-(int64_t)gnutar->entry_bytes_remaining);
491 	return (ret);
492 }
493 
494 static int
495 archive_format_gnutar_header(struct archive_write *a, char h[512],
496     struct archive_entry *entry, int tartype)
497 {
498 	unsigned int checksum;
499 	int i, ret;
500 	size_t copy_length;
501 	const char *p;
502 	struct gnutar *gnutar;
503 
504 	gnutar = (struct gnutar *)a->format_data;
505 
506 	ret = 0;
507 
508 	/*
509 	 * The "template header" already includes the signature,
510 	 * various end-of-field markers, and other required elements.
511 	 */
512 	memcpy(h, &template_header, 512);
513 
514 	/*
515 	 * Because the block is already null-filled, and strings
516 	 * are allowed to exactly fill their destination (without null),
517 	 * I use memcpy(dest, src, strlen()) here a lot to copy strings.
518 	 */
519 
520 	if (tartype == 'K' || tartype == 'L') {
521 		p = archive_entry_pathname(entry);
522 		copy_length = strlen(p);
523 	} else {
524 		p = gnutar->pathname;
525 		copy_length = gnutar->pathname_length;
526 	}
527 	if (copy_length > GNUTAR_name_size)
528 		copy_length = GNUTAR_name_size;
529 	memcpy(h + GNUTAR_name_offset, p, copy_length);
530 
531 	if ((copy_length = gnutar->linkname_length) > 0) {
532 		if (copy_length > GNUTAR_linkname_size)
533 			copy_length = GNUTAR_linkname_size;
534 		memcpy(h + GNUTAR_linkname_offset, gnutar->linkname,
535 		    copy_length);
536 	}
537 
538 	/* TODO: How does GNU tar handle unames longer than GNUTAR_uname_size? */
539 	if (tartype == 'K' || tartype == 'L') {
540 		p = archive_entry_uname(entry);
541 		copy_length = strlen(p);
542 	} else {
543 		p = gnutar->uname;
544 		copy_length = gnutar->uname_length;
545 	}
546 	if (copy_length > 0) {
547 		if (copy_length > GNUTAR_uname_size)
548 			copy_length = GNUTAR_uname_size;
549 		memcpy(h + GNUTAR_uname_offset, p, copy_length);
550 	}
551 
552 	/* TODO: How does GNU tar handle gnames longer than GNUTAR_gname_size? */
553 	if (tartype == 'K' || tartype == 'L') {
554 		p = archive_entry_gname(entry);
555 		copy_length = strlen(p);
556 	} else {
557 		p = gnutar->gname;
558 		copy_length = gnutar->gname_length;
559 	}
560 	if (copy_length > 0) {
561 		if (strlen(p) > GNUTAR_gname_size)
562 			copy_length = GNUTAR_gname_size;
563 		memcpy(h + GNUTAR_gname_offset, p, copy_length);
564 	}
565 
566 	/* By truncating the mode here, we ensure it always fits. */
567 	format_octal(archive_entry_mode(entry) & 07777,
568 	    h + GNUTAR_mode_offset, GNUTAR_mode_size);
569 
570 	/* TODO: How does GNU tar handle large UIDs? */
571 	if (format_octal(archive_entry_uid(entry),
572 	    h + GNUTAR_uid_offset, GNUTAR_uid_size)) {
573 		archive_set_error(&a->archive, ERANGE,
574 		    "Numeric user ID %jd too large",
575 		    (intmax_t)archive_entry_uid(entry));
576 		ret = ARCHIVE_FAILED;
577 	}
578 
579 	/* TODO: How does GNU tar handle large GIDs? */
580 	if (format_octal(archive_entry_gid(entry),
581 	    h + GNUTAR_gid_offset, GNUTAR_gid_size)) {
582 		archive_set_error(&a->archive, ERANGE,
583 		    "Numeric group ID %jd too large",
584 		    (intmax_t)archive_entry_gid(entry));
585 		ret = ARCHIVE_FAILED;
586 	}
587 
588 	/* GNU tar supports base-256 here, so should never overflow. */
589 	if (format_number(archive_entry_size(entry), h + GNUTAR_size_offset,
590 		GNUTAR_size_size, GNUTAR_size_max_size)) {
591 		archive_set_error(&a->archive, ERANGE,
592 		    "File size out of range");
593 		ret = ARCHIVE_FAILED;
594 	}
595 
596 	/* Shouldn't overflow before 2106, since mtime field is 33 bits. */
597 	format_octal(archive_entry_mtime(entry),
598 	    h + GNUTAR_mtime_offset, GNUTAR_mtime_size);
599 
600 	if (archive_entry_filetype(entry) == AE_IFBLK
601 	    || archive_entry_filetype(entry) == AE_IFCHR) {
602 		if (format_octal(archive_entry_rdevmajor(entry),
603 		    h + GNUTAR_rdevmajor_offset,
604 			GNUTAR_rdevmajor_size)) {
605 			archive_set_error(&a->archive, ERANGE,
606 			    "Major device number too large");
607 			ret = ARCHIVE_FAILED;
608 		}
609 
610 		if (format_octal(archive_entry_rdevminor(entry),
611 		    h + GNUTAR_rdevminor_offset,
612 			GNUTAR_rdevminor_size)) {
613 			archive_set_error(&a->archive, ERANGE,
614 			    "Minor device number too large");
615 			ret = ARCHIVE_FAILED;
616 		}
617 	}
618 
619 	h[GNUTAR_typeflag_offset] = tartype;
620 
621 	checksum = 0;
622 	for (i = 0; i < 512; i++)
623 		checksum += 255 & (unsigned int)h[i];
624 	h[GNUTAR_checksum_offset + 6] = '\0'; /* Can't be pre-set in the template. */
625 	/* h[GNUTAR_checksum_offset + 7] = ' '; */ /* This is pre-set in the template. */
626 	format_octal(checksum, h + GNUTAR_checksum_offset, 6);
627 	return (ret);
628 }
629 
630 /*
631  * Format a number into a field, falling back to base-256 if necessary.
632  */
633 static int
634 format_number(int64_t v, char *p, int s, int maxsize)
635 {
636 	int64_t limit = ((int64_t)1 << (s*3));
637 
638 	if (v < limit)
639 		return (format_octal(v, p, s));
640 	return (format_256(v, p, maxsize));
641 }
642 
643 /*
644  * Format a number into the specified field using base-256.
645  */
646 static int
647 format_256(int64_t v, char *p, int s)
648 {
649 	p += s;
650 	while (s-- > 0) {
651 		*--p = (char)(v & 0xff);
652 		v >>= 8;
653 	}
654 	*p |= 0x80; /* Set the base-256 marker bit. */
655 	return (0);
656 }
657 
658 /*
659  * Format a number into the specified field using octal.
660  */
661 static int
662 format_octal(int64_t v, char *p, int s)
663 {
664 	int len = s;
665 
666 	/* Octal values can't be negative, so use 0. */
667 	if (v < 0)
668 		v = 0;
669 
670 	p += s;		/* Start at the end and work backwards. */
671 	while (s-- > 0) {
672 		*--p = (char)('0' + (v & 7));
673 		v >>= 3;
674 	}
675 
676 	if (v == 0)
677 		return (0);
678 
679 	/* If it overflowed, fill field with max value. */
680 	while (len-- > 0)
681 		*p++ = '7';
682 
683 	return (-1);
684 }
685