1 /* @(#)header.c	1.206 20/07/08 Copyright 1985, 1994-2020 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)header.c	1.206 20/07/08 Copyright 1985, 1994-2020 J. Schilling";
6 #endif
7 /*
8  *	Handling routines to read/write, parse/create
9  *	archive headers
10  *
11  *	Copyright (c) 1985, 1994-2020 J. Schilling
12  */
13 /*
14  * The contents of this file are subject to the terms of the
15  * Common Development and Distribution License, Version 1.0 only
16  * (the "License").  You may not use this file except in compliance
17  * with the License.
18  *
19  * See the file CDDL.Schily.txt in this distribution for details.
20  * A copy of the CDDL is also available via the Internet at
21  * http://www.opensource.org/licenses/cddl1.txt
22  *
23  * When distributing Covered Code, include this CDDL HEADER in each
24  * file and include the License file CDDL.Schily.txt from this distribution.
25  */
26 
27 #include <schily/stdio.h>
28 #include <schily/stdlib.h>
29 #include "star.h"
30 #include "props.h"
31 #include "table.h"
32 #include <schily/dirent.h>
33 #include <schily/standard.h>
34 #include <schily/string.h>
35 #define	__XDEV__	/* Needed to activate _dev_major()/_dev_minor() */
36 #include <schily/device.h>
37 #define	GT_COMERR		/* #define comerr gtcomerr */
38 #define	GT_ERROR		/* #define error gterror   */
39 #include <schily/schily.h>
40 #include <schily/idcache.h>
41 #include "starsubs.h"
42 #include "checkerr.h"
43 #include "fifo.h"
44 
45 	/* ustar */
46 LOCAL	char	magic[TMAGLEN] = TMAGIC;
47 	/* star */
48 LOCAL	char	stmagic[STMAGLEN] = STMAGIC;
49 	/* gnu tar */
50 LOCAL	char	gmagic[GMAGLEN] = GMAGIC;
51 
52 typedef struct {
53 	char	*h_name;
54 	char	*h_text;
55 	Int8_t	h_type;
56 	UInt8_t	h_flags;
57 } htab_t;
58 
59 #define	HF_RO	0x01	/* Read only entry - may not be set via cmd line */
60 
61 LOCAL	htab_t	htab[] = {
62 /* BEGIN CSTYLED */
63 /* 0 */	{ "UNDEFINED",	"Undefined archive",			H_UNDEF, HF_RO	},
64 /* 1 */	{ "unknown tar", "Unknown tar format", 			H_TAR,   HF_RO	},
65 /* 2 */	{ "v7tar",	"Old UNIX V7 tar format",		H_V7TAR,  0	},
66 /* 3 */	{ "tar",	"Old BSD tar format",			H_OTAR,  0	},
67 /* 4 */	{ "star",	"Old star format from 1985",		H_STAR,  0	},
68 /* 5 */	{ "gnutar",	"GNU tar format 1989 (violates POSIX)",	H_GNUTAR, 0	},
69 /* 6 */	{ "ustar",	"Standard POSIX.1-1988 tar format",	H_USTAR, 0	},
70 /* 7 */	{ "xstar",	"Extended standard tar (star 1994)",	H_XSTAR, 0	},
71 /* 8 */	{ "xustar",	"'xstar' format without tar signature",	H_XUSTAR, 0	},
72 /* 9 */	{ "exustar",	"'xustar' format - always x-header",	H_EXUSTAR, 0	},
73 /*10 */	{ "pax",	"Extended POSIX.1-2001 standard tar",	H_PAX,    0	},
74 /*11 */	{ "epax",	"Extended POSIX.1-2001 standard tar + x-header",	H_EPAX,    0	},
75 /*12 */	{ "suntar",	"Sun's extended pre-POSIX.1-2001",	H_SUNTAR, 0	},
76 
77 /*15 */	{ "bar",	"SunOS 4.x bar format",			H_BAR,    HF_RO	},
78 
79 /*16 */	{ "bin",	"cpio UNIX V7 binary format",		H_CPIO_BIN, 0	},
80 /*17 */	{ "cpio",	"cpio POSIX.1-1988 format",		H_CPIO_CHR, 0	},
81 /*18 */	{ "odc",	"cpio POSIX.1-1988 with SYSv compat",	H_CPIO_ODC, 0	},
82 /*19 */	{ "nbin",	"CPIO NBIN",				H_CPIO_NBIN, HF_RO	},
83 /*20 */	{ "crcbin",	"CPIO CRCBIN",				H_CPIO_CRC, HF_RO	},
84 /*21 */	{ "asc",	"SYSvr4 cpio ascii expanded device #",	H_CPIO_ASC, 0	},
85 /*22 */	{ "crc",	"'asc' format + CRC",			H_CPIO_ACRC, 0	},
86 
87 	{ NULL,		NULL, 					0, 0 },
88 };
89 /* END CSTYLED */
90 
91 /*
92  * Compression names
93  */
94 LOCAL	char	*cnames[] = {
95 	"unknown",		/*  0 C_NONE	*/
96 	"pack",			/*  1 C_PACK	*/
97 	"gzip",			/*  2 C_GZIP	*/
98 	"lzw",			/*  3 C_LZW	*/
99 	"freeze",		/*  4 C_FREEZE	*/
100 	"lzh",			/*  5 C_LZH	*/
101 	"pkzip",		/*  6 C_PKZIP	*/
102 	"bzip2",		/*  7 C_BZIP2	*/
103 	"lzo",			/*  8 C_LZO	*/
104 	"7z",			/*  9 C_7Z	*/
105 	"xz",			/* 10 C_XZ	*/
106 	"lzip",			/* 11 C_LZIP	*/
107 	"zstd",			/* 12 C_ZSTD	*/
108 	"lzma",			/* 13 C_LZMA	*/
109 	"freeze2",		/* 14 C_FREEZE2	*/
110 };
111 
112 extern	FILE	*tty;
113 extern	FILE	*vpr;
114 extern	const	char	*tarfiles[];	/* Cycle list of all archives	*/
115 extern	int	tarfindex;		/* Current index in list	*/
116 extern	BOOL	multivol;
117 extern	long	hdrtype;
118 extern	long	chdrtype;
119 extern	int	cmptype;
120 extern	int	version;
121 extern	int	swapflg;
122 extern	BOOL	print_artype;
123 extern	BOOL	debug;
124 extern	BOOL	numeric;
125 extern	int	verbose;
126 extern	BOOL	rflag;
127 extern	BOOL	uflag;
128 extern	BOOL	xflag;
129 extern	BOOL	nflag;
130 extern	BOOL	ignoreerr;
131 extern	BOOL	signedcksum;
132 extern	BOOL	nowarn;
133 extern	BOOL	nullout;
134 extern	BOOL	modebits;		/* -modebits more than 12 bits  */
135 extern	BOOL	linkdata;
136 
137 extern	Ullong	tsize;
138 
139 extern	char	*bigbuf;
140 extern	long	bigsize;
141 
142 LOCAL	Ulong	checksum	__PR((TCB *ptb));
143 LOCAL	Ulong	bar_checksum	__PR((TCB *ptb));
144 LOCAL	BOOL	signedtarsum	__PR((TCB *ptb, Ulong ocheck));
145 EXPORT	BOOL	tarsum_ok	__PR((TCB *ptb));
146 LOCAL	BOOL	isstmagic	__PR((char *s));
147 LOCAL	BOOL	isxmagic	__PR((TCB *ptb));
148 LOCAL	BOOL	ismagic		__PR((char *s));
149 LOCAL	BOOL	isgnumagic	__PR((char *s));
150 LOCAL	BOOL	strxneql	__PR((char *s1, char *s2, int l));
151 LOCAL	BOOL	istarnumber	__PR((char *s, int fieldw));
152 LOCAL	BOOL	ustmagcheck	__PR((TCB *ptb));
153 EXPORT	void	print_hdrtype	__PR((FILE *f, int type));
154 EXPORT	char	*hdr_name	__PR((int type));
155 EXPORT	char	*hdr_text	__PR((int type));
156 EXPORT	int	hdr_type	__PR((char *name));
157 EXPORT	void	hdr_usage	__PR((void));
158 EXPORT	int	get_hdrtype	__PR((TCB *ptb, BOOL isrecurse));
159 LOCAL	int	get_xhtype	__PR((TCB *ptb, int htype));
160 EXPORT	int	get_compression	__PR((TCB *ptb));
161 EXPORT	char	*get_cmpname	__PR((int type));
162 EXPORT	int	get_tcb		__PR((TCB *ptb));
163 EXPORT	void	put_tcb		__PR((TCB *ptb, FINFO *info));
164 EXPORT	void	write_tcb	__PR((TCB *ptb, FINFO *info));
165 EXPORT	void	info_to_tcb	__PR((FINFO *info, TCB *ptb));
166 LOCAL	void	info_to_star	__PR((FINFO *info, TCB *ptb));
167 LOCAL	void	info_to_ustar	__PR((FINFO *info, TCB *ptb));
168 LOCAL	void	info_to_xstar	__PR((FINFO *info, TCB *ptb));
169 LOCAL	void	info_to_gnutar	__PR((FINFO *info, TCB *ptb));
170 EXPORT	int	tcb_to_info	__PR((TCB *ptb, FINFO *info));
171 LOCAL	void	tar_to_info	__PR((TCB *ptb, FINFO *info));
172 LOCAL	void	star_to_info	__PR((TCB *ptb, FINFO *info));
173 LOCAL	void	ustar_to_info	__PR((TCB *ptb, FINFO *info));
174 LOCAL	void	xstar_to_info	__PR((TCB *ptb, FINFO *info));
175 LOCAL	void	gnutar_to_info	__PR((TCB *ptb, FINFO *info));
176 LOCAL	int	ustoxt		__PR((int ustype));
177 LOCAL	BOOL	checkeof	__PR((TCB *ptb));
178 LOCAL	BOOL	eofblock	__PR((TCB *ptb));
179 LOCAL	void	stoli		__PR((char *s, Ulong * l, int fieldw));
180 EXPORT	void	stolli		__PR((char *s, Ullong *ull));
181 LOCAL	void	litos		__PR((char *s, Ulong l, int fieldw));
182 EXPORT	void	llitos		__PR((char *s, Ullong ull, int fieldw));
183 LOCAL	void	stob		__PR((char *s, Ulong *l, int fieldw));
184 LOCAL	void	stollb		__PR((char *s, Ullong *ull, int fieldw));
185 LOCAL	void	btos		__PR((char *s, Ulong l, int fieldw));
186 LOCAL	void	llbtos		__PR((char *s, Ullong ull, int fieldw));
187 LOCAL	BOOL	nameascii	__PR((char *name));
188 LOCAL	void	print_hrange	__PR((char *type, Ullong ull));
189 EXPORT	void	dump_info	__PR((FINFO *info));
190 
191 /*
192  * XXX Hier sollte eine tar/bar universelle Checksummenfunktion sein!
193  */
194 #define	CHECKS	sizeof (ptb->ustar_dbuf.t_chksum)
195 /*
196  * We know, that sizeof (TCP) is 512 and therefore has no
197  * reminder when dividing by 8
198  *
199  * CHECKS is known to be 8 too, use loop unrolling.
200  */
201 #define	DO8(a)	a; a; a; a; a; a; a; a;
202 
203 LOCAL Ulong
checksum(ptb)204 checksum(ptb)
205 	register	TCB	*ptb;
206 {
207 	register	int	i;
208 	register	Ulong	sum = 0;
209 	register	Uchar	*us;
210 
211 	if (signedcksum) {
212 		register	char	*ss;
213 		register	long	ssum = 0;
214 
215 		ss = (char *)ptb;
216 		for (i = sizeof (*ptb)/8; --i >= 0; ) {
217 			DO8(ssum += *ss++);
218 		}
219 		if (ssum == 0L) {	/* Block containing 512 nul's? */
220 			signedcksum = FALSE;
221 			sum = checksum(ptb);
222 			signedcksum = TRUE;
223 			return (sum);
224 		}
225 
226 		ss = (char *)ptb->ustar_dbuf.t_chksum;
227 		DO8(ssum -= *ss++);
228 		ssum += CHECKS*' ';
229 		sum = ssum;
230 	} else {
231 		us = (Uchar *)ptb;
232 		for (i = sizeof (*ptb)/8; --i >= 0; ) {
233 			DO8(sum += *us++);
234 		}
235 		if (sum == 0L)		/* Block containing 512 nul's */
236 			return (sum);
237 
238 		us = (Uchar *)ptb->ustar_dbuf.t_chksum;
239 		DO8(sum -= *us++);
240 		sum += CHECKS*' ';
241 	}
242 	return (sum);
243 }
244 #undef	CHECKS
245 
246 #define	CHECKS	sizeof (ptb->bar_dbuf.t_chksum)
247 
248 LOCAL Ulong
bar_checksum(ptb)249 bar_checksum(ptb)
250 	register	TCB	*ptb;
251 {
252 	register	int	i;
253 	register	Ulong	sum = 0;
254 	register	Uchar	*us;
255 
256 	if (signedcksum) {
257 		register	char	*ss;
258 		register	long	ssum = 0;
259 
260 		ss = (char *)ptb;
261 		for (i = sizeof (*ptb); --i >= 0; )
262 			ssum += *ss++;
263 		if (ssum == 0L) {	/* Block containing 512 nul's? */
264 			signedcksum = FALSE;
265 			sum = bar_checksum(ptb);
266 			signedcksum = TRUE;
267 			return (sum);
268 		}
269 
270 		for (i = CHECKS, ss = (char *)ptb->bar_dbuf.t_chksum; --i >= 0; )
271 			ssum -= *ss++;
272 		ssum += CHECKS*' ';
273 		sum = ssum;
274 	} else {
275 		us = (Uchar *)ptb;
276 		for (i = sizeof (*ptb); --i >= 0; )
277 			sum += *us++;
278 		if (sum == 0L)		/* Block containing 512 nul's */
279 			return (sum);
280 
281 		for (i = CHECKS, us = (Uchar *)ptb->bar_dbuf.t_chksum; --i >= 0; )
282 			sum -= *us++;
283 		sum += CHECKS*' ';
284 	}
285 	return (sum);
286 }
287 #undef	CHECKS
288 
289 LOCAL BOOL
signedtarsum(ptb,ocheck)290 signedtarsum(ptb, ocheck)
291 	TCB	*ptb;
292 	Ulong	ocheck;
293 {
294 	BOOL	osigned = signedcksum;
295 	Ulong	check;
296 
297 	if (ocheck == 0)
298 		return (FALSE);
299 
300 	signedcksum = !signedcksum;
301 	check = checksum(ptb);
302 	if (ocheck == check) {
303 		errmsgno(EX_BAD, "WARNING: archive uses %s checksums.\n",
304 				signedcksum?"signed":"unsigned");
305 		return (TRUE);
306 	}
307 	signedcksum = osigned;
308 	return (FALSE);
309 }
310 
311 /*
312  * XXX Shouldn't we use this or something similar from get_tcb() too?
313  */
314 EXPORT BOOL
tarsum_ok(ptb)315 tarsum_ok(ptb)
316 	TCB	*ptb;
317 {
318 	Ulong	ocheck;
319 	Ulong	check;
320 
321 	/*
322 	 * We are currently only called with TAR type archives, so using 7 for
323 	 * fieldwidth is OK.
324 	 */
325 	stoli(ptb->dbuf.t_chksum, &ocheck, 7);
326 	if (ocheck == 0)
327 		return (FALSE);
328 	check = checksum(ptb);
329 	if (ocheck != check && !signedtarsum(ptb, ocheck))
330 		return (FALSE);
331 	return (TRUE);
332 }
333 
334 LOCAL BOOL
isstmagic(s)335 isstmagic(s)
336 	char	*s;
337 {
338 	return (strxneql(s, stmagic, STMAGLEN));
339 }
340 
341 /*
342  * Check for XSTAR / XUSTAR format.
343  *
344  * Since we use this function after we checked for the "tar" signature, it
345  * is only used as a XUSTAR check.
346  *
347  * This is star's upcoming new standard format. This format understands star's
348  * old extended POSIX format and in future will write POSIX.1-2001 extensions
349  * using 'x' headers.
350  * Star also detects the archive format from the value of
351  * the "SCHILY.archtype=" POSIX.1-2001 header tag.
352  */
353 LOCAL BOOL
isxmagic(ptb)354 isxmagic(ptb)
355 	TCB	*ptb;
356 {
357 	register int	i;
358 
359 	/*
360 	 * prefix[130] is is granted to be '\0' with 'xstar'.
361 	 */
362 	if (ptb->xstar_dbuf.t_prefix[130] == '\0') {
363 		/*
364 		 * True for all 'standard' TCBs except with typeflag 'M'
365 		 */
366 		/* EMPTY */
367 		;
368 	} else if (ptb->ustar_dbuf.t_typeflag == 'M') {
369 		/*
370 		 * We come only here if we try to read in a multivol archive
371 		 * starting past volume #0. If we start with volume #0, all
372 		 * multi volume headers are skiped by the low level multi
373 		 * volume handling code.
374 		 */
375 		if ((ptb->xstar_in_dbuf.t_offset[11] != ' ') &&
376 		    ((ptb->xstar_in_dbuf.t_offset[0] & 0x80) == 0))
377 			return (FALSE);
378 	} else {
379 		return (FALSE);
380 	}
381 
382 	/*
383 	 * If atime[0]...atime[10] or ctime[0]...ctime[10]
384 	 * is not a POSIX octal number it cannot be 'xstar'.
385 	 * With the octal representation we may store any date
386 	 * for 1970 +- 136 years (1834 ... 2106).
387 	 *
388 	 * After 2106 we will most likely always use POSIX.1-2001 'x'
389 	 * headers but still use base 256 numbers in the old tar header.
390 	 * We thus still need to check for base 256 numbers even though
391 	 * this is very unlikely since we create 'x' headers if nanoseconds
392 	 * are != 0 and then use a 0 time stamp for atime/ctime in the
393 	 * 'x' header.
394 	 */
395 	for (i = 0; i < 11; i++) {
396 		if ((ptb->xstar_dbuf.t_atime[0] & 0x80) == 0 &&
397 		    (ptb->xstar_dbuf.t_atime[i] < '0' ||
398 		    ptb->xstar_dbuf.t_atime[i] > '7'))
399 			return (FALSE);
400 		if (((ptb->xstar_dbuf.t_ctime[0] & 0x80) == 0) &&
401 		    (ptb->xstar_dbuf.t_ctime[i] < '0' ||
402 		    ptb->xstar_dbuf.t_ctime[i] > '7'))
403 			return (FALSE);
404 	}
405 
406 	/*
407 	 * Check for both POSIX compliant end of number characters
408 	 * if not using base 256.
409 	 */
410 	if ((ptb->xstar_dbuf.t_atime[0] & 0x80) == 0 &&
411 	    ptb->xstar_dbuf.t_atime[11] != ' ' &&
412 	    ptb->xstar_dbuf.t_atime[11]  != '\0')
413 		return (FALSE);
414 
415 	if ((ptb->xstar_dbuf.t_ctime[0] & 0x80) == 0 &&
416 	    ptb->xstar_dbuf.t_ctime[11] != ' ' &&
417 	    ptb->xstar_dbuf.t_ctime[11]  != '\0')
418 		return (FALSE);
419 
420 	return (TRUE);
421 }
422 
423 LOCAL BOOL
ismagic(s)424 ismagic(s)
425 	char	*s;
426 {
427 	return (strxneql(s, magic, TMAGLEN));
428 }
429 
430 LOCAL BOOL
isgnumagic(s)431 isgnumagic(s)
432 	char	*s;
433 {
434 	return (strxneql(s, gmagic, GMAGLEN));
435 }
436 
437 LOCAL BOOL
strxneql(s1,s2,l)438 strxneql(s1, s2, l)
439 	register char	*s1;
440 	register char	*s2;
441 	register int	l;
442 {
443 	while (--l >= 0)
444 		if (*s1++ != *s2++)
445 			return (FALSE);
446 	return (TRUE);
447 }
448 
449 /*
450  * Check whether a field looks like a TAR numeric field.
451  * This intentionally does not include a check for base-256 numbers.
452  */
453 LOCAL BOOL
istarnumber(s,fieldw)454 istarnumber(s, fieldw)
455 	char	*s;
456 	int	fieldw;
457 {
458 	register int	c;
459 
460 	while (*s == ' ' && --fieldw >= 0)
461 		s++;
462 
463 	/*
464 	 * We need at least one octal number, skip other octals numbers.
465 	 */
466 	c = *s;
467 	if (fieldw < 0 || !isoctal(c))
468 		return (FALSE);
469 	while ((c = *s) && --fieldw >= 0) {
470 		if (!isoctal(c))
471 			break;
472 		s++;
473 	}
474 
475 	/*
476 	 * All digits used within fieldw. This is the non-compliant case
477 	 * where the number is followed by the next one (starting with space
478 	 * or an octal digit. We are gracious and permit this case.
479 	 */
480 	c = *s;
481 	if ((c == ' ' || isoctal(c)) && fieldw == -1)
482 		return (TRUE);
483 
484 	/*
485 	 * Typical standard compliant end.
486 	 */
487 	if ((c == '\0' || c == ' ') && (fieldw <= 2 && fieldw >= 0))
488 		return (TRUE);
489 
490 	/*
491 	 * We either got a field separator too early or after
492 	 * fieldw was exhausted. This still may be tolerable.
493 	 */
494 	if (fieldw < 0 || !isoctal(c))
495 		return (FALSE);
496 
497 	return (TRUE);
498 }
499 
500 LOCAL BOOL
ustmagcheck(ptb)501 ustmagcheck(ptb)
502 	TCB	*ptb;
503 {
504 	if (ismagic(ptb->xstar_dbuf.t_magic) &&
505 				strxneql(ptb->xstar_dbuf.t_version, "00", 2))
506 		return (TRUE);
507 	return (FALSE);
508 }
509 
510 EXPORT void
print_hdrtype(f,type)511 print_hdrtype(f, type)
512 	FILE	*f;
513 	int	type;
514 {
515 		BOOL	isswapped = H_ISSWAPPED(type);
516 
517 	if (H_TYPE(type) > H_MAX_ARCH)
518 		type = H_UNDEF;
519 	type = H_TYPE(type);
520 
521 	fgtprintf(f, "%s%s archive.\n", isswapped?"swapped ":"", hdr_name(type));
522 }
523 
524 EXPORT char *
hdr_name(type)525 hdr_name(type)
526 	int	type;
527 {
528 	register htab_t	*htp = htab;
529 
530 	for (; htp->h_name; htp++) {
531 		if (htp->h_type == type)
532 			return (htp->h_name);
533 	}
534 	return (htab->h_name);
535 }
536 
537 EXPORT char *
hdr_text(type)538 hdr_text(type)
539 	int	type;
540 {
541 	register htab_t	*htp = htab;
542 
543 	for (; htp->h_name; htp++) {
544 		if (htp->h_type == type)
545 			return (htp->h_text);
546 	}
547 	return (htab->h_text);
548 }
549 
550 EXPORT int
hdr_type(name)551 hdr_type(name)
552 	char	*name;
553 {
554 	register htab_t	*htp = htab;
555 
556 	for (; htp->h_name; htp++) {
557 		if (htp->h_flags & HF_RO)
558 			continue;
559 		if (streql(name, htp->h_name))
560 			return (htp->h_type);
561 	}
562 	return (-1);
563 }
564 
565 EXPORT void
hdr_usage()566 hdr_usage()
567 {
568 	register htab_t	*htp = htab;
569 
570 	for (; htp->h_name; htp++) {
571 		if (htp->h_flags & HF_RO)
572 			continue;
573 		error("%s\t%s\t%s\n",
574 			hdrtype == htp->h_type ? "*":"",
575 			htp->h_name, htp->h_text);
576 	}
577 }
578 
579 EXPORT int
get_hdrtype(ptb,isrecurse)580 get_hdrtype(ptb, isrecurse)
581 	TCB	*ptb;
582 	BOOL	isrecurse;
583 {
584 	Ulong	check;
585 	Ulong	ocheck;
586 	int	ret = H_UNDEF;
587 
588 	/*
589 	 * We don't like to get "WARNING: Unterminated octal number at..."
590 	 * when we may have e.g. a CPIO archive to check.
591 	 * So enforce to null-terminate the TAR checksum field and use a
592 	 * fieldwidth of 8 as CPIO archives may have all characters from
593 	 * ptb->dbuf.t_chksum[] != 0.
594 	 */
595 	check = ptb->dbuf.t_linkflag;
596 	ptb->dbuf.t_linkflag = 0;
597 	stoli(ptb->dbuf.t_chksum, &ocheck, 8);
598 	ptb->dbuf.t_linkflag = check;		/* Restore old value */
599 	if (ocheck == 0)
600 		goto nottar;
601 	check = checksum(ptb);
602 	if (ocheck != check && !signedtarsum(ptb, ocheck)) {
603 		if (debug && !isrecurse) {
604 			errmsgno(EX_BAD,
605 				"Bad tar checksum at: %lld: 0%lo should be 0%lo.\n",
606 							tblocks(),
607 							ocheck, check);
608 		}
609 		goto nottar;
610 	}
611 
612 	/*
613 	 * t_mode never needs base-256, so this is a good place to check.
614 	 *
615 	 * Unfortunately, GNU tar does not fill in t_mode for 'V'holhdr,
616 	 * but only t_mtime.
617 	 * Unfortunately, GNU tar does not fill in t_mode for 'M'ultivol,
618 	 * but only t_size.
619 	 */
620 	if (!istarnumber(ptb->dbuf.t_mode, 8)) {
621 		/*
622 		 * A non standard compliant header was seen. Try to work around
623 		 * the deviations from GNU tar and permit GNU tar headers to be
624 		 * seen as OK.
625 		 */
626 		switch (ptb->ustar_dbuf.t_typeflag) {
627 
628 		case 'V':
629 			if (!(ptb->dbuf.t_mtime[0] & 0x80) &&
630 			    !istarnumber(ptb->dbuf.t_mtime, 12))
631 				goto nottar;
632 			break;
633 		case 'M':
634 			if (!(ptb->dbuf.t_size[0] & 0x80) &&
635 			    !istarnumber(ptb->dbuf.t_size, 12))
636 				goto nottar;
637 			break;
638 
639 		default:		/* Not a problematic GNU tar header */
640 			goto nottar;
641 		}
642 	}
643 
644 	if (isstmagic(ptb->dbuf.t_magic)) {	/* Check for 'tar\0' at end */
645 		if (ustmagcheck(ptb))
646 			ret = H_XSTAR;
647 		else
648 			ret = H_STAR;
649 		if (debug) print_hdrtype(stderr, ret);
650 		return (ret);
651 	}
652 	if (ustmagcheck(ptb)) {			/* 'ustar\000' POSIX magic */
653 		if (isxmagic(ptb)) {		/* Check for xustar	   */
654 #ifdef	__historic__
655 			/*
656 			 * H_EXUSTAR was introduced in August 2001 but since
657 			 * October 2003 we have SCHILY.archtype that is always
658 			 * used together with H_EXUSTAR. Determine the achive
659 			 * type from SCHILY.archtype in the 'g' header.
660 			 */
661 			if (ptb->ustar_dbuf.t_typeflag == 'g' ||
662 			    ptb->ustar_dbuf.t_typeflag == 'x')
663 				ret = H_EXUSTAR;
664 			else
665 #endif
666 				ret = H_XUSTAR;
667 		} else {
668 			if (ptb->ustar_dbuf.t_typeflag == 'g' ||
669 			    ptb->ustar_dbuf.t_typeflag == 'x')
670 				ret = H_PAX;
671 			else if (ptb->ustar_dbuf.t_typeflag == 'X')
672 				ret = H_SUNTAR;
673 			else
674 				ret = H_USTAR;
675 		}
676 		if (debug) print_hdrtype(stderr, ret);
677 		return (ret);
678 	}
679 	if (isgnumagic(ptb->ustar_dbuf.t_magic)) { /* 'ustar  ' GNU magic */
680 		ret = H_GNUTAR;
681 		if (debug) print_hdrtype(stderr, ret);
682 		return (ret);
683 	}
684 	if ((ptb->dbuf.t_mode[6] == ' ' && ptb->dbuf.t_mode[7] == '\0')) {
685 		ret = H_OTAR;
686 		if (debug) print_hdrtype(stderr, ret);
687 		return (ret);
688 	}
689 	if (ptb->ustar_dbuf.t_typeflag == LF_VOLHDR ||
690 			    ptb->ustar_dbuf.t_typeflag == LF_MULTIVOL) {
691 		/*
692 		 * Gnu volume headers & multi volume headers
693 		 * are no real tar headers.
694 		 */
695 		if (debug) error("gnutar buggy archive.\n");
696 		ret = H_GNUTAR;
697 		if (debug) print_hdrtype(stderr, ret);
698 		return (ret);
699 	}
700 	/*
701 	 * The only thing we know here is:
702 	 * we found a header with a correct tar checksum.
703 	 */
704 	ret = H_TAR;
705 	if (debug) print_hdrtype(stderr, ret);
706 	return (ret);
707 
708 nottar:
709 	if (ptb->bar_dbuf.bar_magic[0] == 'V') {
710 		/*
711 		 * We don't like "WARNING: Unterminated octal number at..."
712 		 * when we may have e.g. a CPIO archive to check.
713 		 * So enforce to null-terminate the BAR checksum field and use a
714 		 * fieldwidth of 8 as junk may have all characters from
715 		 * ptb->bar_dbuf.t_chksum[] != 0.
716 		 */
717 		check = ptb->bar_dbuf.rdev[0];
718 		stoli(ptb->bar_dbuf.t_chksum, &ocheck, 8);
719 		ptb->bar_dbuf.rdev[0] = check;
720 		check = bar_checksum(ptb);
721 
722 		if (ocheck == 0) {
723 			/* EMPTY */
724 			;
725 		} else if (ocheck == check) {
726 			ret = H_BAR;
727 			if (debug) print_hdrtype(stderr, ret);
728 			return (ret);
729 		} else if (debug && !isrecurse) {
730 			errmsgno(EX_BAD,
731 				"Bad bar checksum at: %lld: 0%lo should be 0%lo.\n",
732 							tblocks(),
733 							ocheck, check);
734 		}
735 
736 	}
737 	if (strxneql((char *)ptb, "070701", 6)) {
738 		/*
739 		 * CPIO ASCII hex header with expanded device numbers
740 		 */
741 		ret = H_CPIO_ASC;		/* cpio -c */
742 		if (debug) print_hdrtype(stderr, ret);
743 		return (ret);
744 	}
745 	if (strxneql((char *)ptb, "070702", 6)) {
746 		/*
747 		 * CPIO ASCII hex header with expanded device numbers and CRC
748 		 */
749 		ret = H_CPIO_ACRC;		/* cpio -Hcrc */
750 		if (debug) print_hdrtype(stderr, ret);
751 		return (ret);
752 	}
753 	if (strxneql((char *)ptb, "070707", 6)) {
754 		/*
755 		 * POSIX small (6 octal digit device numbers)
756 		 */
757 		ret = H_CPIO_CHR;		/* cpio -Hodc */
758 		if (debug) print_hdrtype(stderr, ret);
759 		return (ret);
760 
761 	}
762 	if (strxneql((char *)ptb, "\161\301", 2)) {
763 		/*
764 		 * 0161 0301 -> 0x71 0xC1 -> 070701
765 		 */
766 		ret = H_CPIO_NBIN;
767 		if (debug) print_hdrtype(stderr, ret);
768 		return (ret);
769 	}
770 	if (strxneql((char *)ptb, "\161\302", 2)) {
771 		/*
772 		 * 0161 0302 -> 0x71 0xC2 -> 070702
773 		 */
774 		ret = H_CPIO_CRC;
775 		if (debug) print_hdrtype(stderr, ret);
776 		return (ret);
777 	}
778 	if (strxneql((char *)ptb, "\161\307", 2) ||
779 	    strxneql((char *)ptb, "\307\161", 2)) {
780 		/*
781 		 * cpio default
782 		 * 0161 0307 -> 0x71 0xC7 -> 070707
783 		 * 0307 0161 -> 0xC7 0x71 -> 0143561
784 		 *
785 		 * Binary cpio archives may use any byte order for the numbers
786 		 * in the header so we cannot use the byte order in the header
787 		 * to detect swapped archives.
788 		 * Filenames with odd length result in a null byte inside the
789 		 * filename and this allows us to auto-detect byte swapped
790 		 * archives.
791 		 *
792 		 * If strlen(info->f_name) is odd, we may autodetect
793 		 * whether this archive has been swapped as whole.
794 		 * cpio_checkswab() returns either H_CPIO_BIN or
795 		 * H_SWAPPED(H_CPIO_BIN).
796 		 */
797 		ret = cpio_checkswab(ptb);
798 		if (debug) print_hdrtype(stderr, ret);
799 		return (ret);
800 	}
801 	if (debug) error("no tar archive??\n");
802 
803 	if (!isrecurse) {
804 		int	rret;
805 		swabbytes((char *)ptb, TBLOCK);
806 		rret = get_hdrtype(ptb, TRUE);
807 		swabbytes((char *)ptb, TBLOCK);
808 		rret = H_SWAPPED(rret);
809 		if (debug) print_hdrtype(stderr, rret);
810 		return (rret);
811 	}
812 
813 	if (debug) print_hdrtype(stderr, ret);
814 	return (ret);
815 }
816 
817 LOCAL int
get_xhtype(ptb,htype)818 get_xhtype(ptb, htype)
819 	TCB	*ptb;
820 	int	htype;
821 {
822 	FINFO	finfo;
823 	Ullong	ull;
824 	int	xhsiz = bigsize-TBLOCK;
825 	char	*xhp = &bigbuf[TBLOCK];
826 	BOOL	swapped;
827 	int	t;
828 	GINFO	gsav;
829 extern	GINFO	*grip;				/* Global read info pointer */
830 
831 	gsav = *grip;				/* Save old content */
832 
833 	t = H_TYPE(htype);
834 	if (t < H_TARMIN || t > H_TARMAX)
835 		return (htype);
836 
837 	swapped = H_ISSWAPPED(htype);
838 	/*
839 	 * Swap TCB & io buffer.
840 	 */
841 	if (swapped) {
842 		swabbytes(ptb, TBLOCK);
843 		swabbytes(bigbuf, bigsize);
844 	}
845 
846 	if (ptb->ustar_dbuf.t_typeflag != 'g' &&
847 	    ptb->ustar_dbuf.t_typeflag != 'x')
848 		goto out;
849 
850 	/*
851 	 * File size is strlen of extended header
852 	 */
853 	stolli(ptb->dbuf.t_size, &ull);
854 	finfo.f_size = ull;
855 	finfo.f_rsize = (off_t)finfo.f_size;
856 
857 	if (xhsiz > ull)
858 		xhsiz = ull;
859 
860 	/*
861 	 * Mark the path name and link name pointer uninitalized to avoid that
862 	 * xhparse() will try to copy a possible path= or lpath= entry in the
863 	 * first extended header to finfo->f_name & finfo->f_lname.
864 	 */
865 	finfo.f_name = NULL;
866 	finfo.f_lname = NULL;
867 	finfo.f_devminorbits = 0;
868 	finfo.f_xflags = 0;
869 
870 	grip->archtype = H_UNDEF;
871 	xhparse(&finfo, xhp, xhp+xhsiz);
872 	if (grip->archtype != H_UNDEF) {
873 		htype = grip->archtype;
874 		if (swapped)
875 			htype = H_SWAPPED(htype);
876 	}
877 	*grip = gsav;				/* Restore old content */
878 
879 out:
880 	/*
881 	 * Swap back TCB & io buffer.
882 	 */
883 	if (swapped) {
884 		swabbytes(ptb, TBLOCK);
885 		swabbytes(bigbuf, bigsize);
886 	}
887 	return (htype);
888 }
889 
890 EXPORT int
get_compression(ptb)891 get_compression(ptb)
892 	TCB	*ptb;
893 {
894 	char	*p = (char *)ptb;
895 
896 	if (p[0] == '\037') {
897 		if (p[1] == '\036')	/* Packed		*/
898 			return (C_PACK);
899 		if (p[1] == '\213')	/* Gzip compressed	*/
900 			return (C_GZIP);
901 		if (p[1] == '\235')	/* LZW compressed	*/
902 			return (C_LZW);
903 		if (p[1] == '\236')	/* Freezed		*/
904 			return (C_FREEZE);
905 		if (p[1] == '\237')	/* Freeze-2		*/
906 			return (C_FREEZE2);
907 		if (p[1] == '\240')	/* SCO LZH compressed	*/
908 			return (C_LZH);
909 	}
910 	if (p[0] == 'P' && p[1] == 'K' && p[2] == '\003' && p[3] == '\004')
911 		return (C_PKZIP);
912 	if (p[0] == 'B' && p[1] == 'Z' && p[2] == 'h')
913 		return (C_BZIP2);
914 	if (p[0] == '\211' && p[1] == 'L' && p[2] == 'Z' && p[3] == 'O')
915 		return (C_LZO);
916 
917 	/*
918 	 * p[6] && p[7] contain the version number
919 	 */
920 	if (p[0] == '7' && p[1] == 'z' && p[2] == '\274' && p[3] == '\257' &&
921 	    p[4] == '\047' && p[5] == '\034')
922 		return (C_7Z);
923 
924 	/*
925 	 * p[6] && p[7] contain the stream flags
926 	 */
927 	if (p[0] == '\375' &&
928 	    p[1] == '7' && p[2] == 'z' && p[3] == 'X' && p[4] == 'Z' &&
929 	    p[5] == '\0')
930 		return (C_XZ);
931 
932 	/*
933 	 * The lzip file format has four "magic bytes", followed by a version
934 	 * byte (0 or 1 currently), then the coded dictionary size. To reduce
935 	 * the number of false-positive detections, require the version byte
936 	 * be 0 or 1, and validate the dictionary size.
937 	 */
938 	if (p[0] == 'L' && p[1] == 'Z' && p[2] == 'I' && p[3] == 'P' &&
939 	    (p[4] == '\0' || p[4] == '\001') &&
940 	    ((p[5] & 0x1f) > 12 || (p[5] & 0x1f) == 0 || p[5] == 12))
941 		return (C_LZIP);
942 
943 	if (p[0] == (char) 0x28 && p[1] == (char) 0xB5 &&
944 	    p[2] == (char) 0x2F && p[3] == (char) 0xFD)
945 		return (C_ZSTD);
946 
947 	/*
948 	 * There is no grant that this is true, but it seems to be OK from the
949 	 * magic used by file(1) from Christos Zoulas <christos@zoulas.com>
950 	 */
951 	if (p[0] == ']' && p[1] == 0 && p[2] == 0)
952 		return (C_LZMA);
953 
954 	return (C_NONE);
955 }
956 
957 EXPORT char *
get_cmpname(type)958 get_cmpname(type)
959 	int	type;
960 {
961 	if (type < 0 || type > C_MAX)
962 		type = C_NONE;
963 
964 	/*
965 	 * Paranoia for incomplete cnames[] entries.
966 	 */
967 	if (type >= (sizeof (cnames) / sizeof (cnames[0])))
968 		type = C_NONE;
969 
970 	return (cnames[type]);
971 }
972 
973 EXPORT int
get_tcb(ptb)974 get_tcb(ptb)
975 	TCB	*ptb;
976 {
977 	Ulong	check;
978 	Ulong	ocheck;
979 	BOOL	eof = FALSE;
980 extern	long	iskip;
981 extern	Llong	mtskip;
982 extern	char	*bigptr;
983 extern	m_stats	*stats;
984 
985 	/*
986 	 * bei der Option -i wird ein genulltes File
987 	 * fehlerhaft als EOF Block erkannt !
988 	 * wenn nicht t_magic gesetzt ist.
989 	 */
990 	do {
991 		/*
992 		 * First tar control block
993 		 */
994 		if (swapflg < 0) {
995 			BOOL	swapped;
996 
997 			if (peekblock((char *)ptb, TBLOCK) == EOF) {
998 				/*
999 				 * The minimal size of a senseful TAR archive is
1000 				 * 3 blocks (1536).
1001 				 * The minimal size of a senseful CPIO archive is
1002 				 * 26+2 + 26+12 = 66 bytes for a BIN archive, but
1003 				 * a CPIO archive in whole needs to a multiple of
1004 				 * 512 bytes.
1005 				 */
1006 				errmsgno(EX_BAD,
1007 				"Hard EOF on input, first EOF block is missing at %lld.\n",
1008 				tblocks());
1009 #ifdef	FIFO_EOF_DEBUG
1010 				if (use_fifo)	/* Debug a rare EOF problem */
1011 					fifo_prmp(1);
1012 #endif
1013 				xstats.s_hardeof++;
1014 				return (EOF);
1015 			}
1016 			if (mtskip) {
1017 				int	nbl = stats->blocksize / TBLOCK;
1018 
1019 				iskip = mtskip % nbl;
1020 				iskip *= TBLOCK;
1021 			}
1022 			if (iskip) {
1023 				if (stats->blocksize >= (iskip+TBLOCK)) {
1024 					movetcb((TCB *)(bigptr+iskip), (TCB *)ptb);
1025 				}
1026 			}
1027 			hdrtype = get_hdrtype(ptb, FALSE);
1028 			hdrtype = get_xhtype(ptb, hdrtype);
1029 			if (print_artype) {
1030 				printf("%s: ", tarfiles[tarfindex]);
1031 				if (cmptype != C_NONE) {
1032 					gtprintf("%s compressed ",
1033 						get_cmpname(cmptype));
1034 				}
1035 				print_hdrtype(stdout, hdrtype);
1036 				exit(0);
1037 			}
1038 			swapped = H_ISSWAPPED(hdrtype);
1039 			if (chdrtype != H_UNDEF &&
1040 					swapped != H_ISSWAPPED(chdrtype)) {
1041 
1042 				swapped = H_ISSWAPPED(chdrtype);
1043 			}
1044 			if (swapped) {
1045 				swapflg = 1;
1046 				/*
1047 				 * We swap everything already read here.
1048 				 * We tell the input routines later (inside the
1049 				 * buf_resume() call) that further swapping is
1050 				 * needed.
1051 				 */
1052 				swabbytes((char *)ptb, TBLOCK);	/* copy of TCB */
1053 				swabbytes(bigbuf, bigsize);	/* io buffer  */
1054 			} else {
1055 				swapflg = 0;
1056 			}
1057 			if (H_TYPE(hdrtype) == H_BAR) {
1058 				comerrno(EX_BAD, "Can't handle bar archives (yet).\n");
1059 			}
1060 			if (H_TYPE(hdrtype) == H_UNDEF) {
1061 				int	t;
1062 
1063 				switch (t = get_compression(ptb)) {
1064 
1065 				case C_NONE:
1066 					break;
1067 				case C_PACK:
1068 				case C_GZIP:
1069 				case C_LZW:
1070 				case C_FREEZE:
1071 				case C_LZH:
1072 				case C_PKZIP:
1073 					comerrno(EX_BAD, "Archive is '%s' compressed, try to use the -z option.\n",
1074 							get_cmpname(t));
1075 					break;
1076 				case C_BZIP2:
1077 					comerrno(EX_BAD, "Archive is 'bzip2' compressed, try to use the -bz option.\n");
1078 					break;
1079 				case C_LZO:
1080 					comerrno(EX_BAD, "Archive is 'lzop' compressed, try to use the -bz option.\n");
1081 					break;
1082 				case C_7Z:
1083 					comerrno(EX_BAD, "Archive is '7z' compressed, try to use the -7z option.\n");
1084 					break;
1085 				case C_XZ:
1086 					comerrno(EX_BAD, "Archive is 'xz' compressed, try to use the -xz option.\n");
1087 					break;
1088 				case C_LZIP:
1089 					comerrno(EX_BAD, "Archive is 'lzip' compressed, try to use the -lzip option.\n");
1090 					break;
1091 				case C_ZSTD:
1092 					comerrno(EX_BAD, "Archive is 'zstd' compressed, try to use the -zstd option.\n");
1093 					break;
1094 				case C_LZMA:
1095 					comerrno(EX_BAD, "Archive is 'lzma' compressed, try to use the -lzma option.\n");
1096 					break;
1097 				case C_FREEZE2:
1098 					comerrno(EX_BAD, "Archive is 'freeze2' compressed, try to use the -freeze option.\n");
1099 					break;
1100 				default:
1101 					errmsgno(EX_BAD, "WARNING: Unknown compression type %d.\n", t);
1102 					break;
1103 				}
1104 				if (!ignoreerr) {
1105 					comerrno(EX_BAD,
1106 					"Unknown archive type (neither tar, nor bar/cpio).\n");
1107 				}
1108 			}
1109 			if ((chdrtype != H_UNDEF || (rflag || uflag)) &&
1110 			    chdrtype != hdrtype) {
1111 				errmsgno(EX_BAD, "Found: ");
1112 				print_hdrtype(stderr, hdrtype);
1113 				if (chdrtype == H_UNDEF) {
1114 					chdrtype = hdrtype;
1115 					if (rflag || uflag) {
1116 						setprops(hdrtype);
1117 						star_verifyopts();
1118 					}
1119 				} else {
1120 					errmsgno(EX_BAD,
1121 						"WARNING: extracting as ");
1122 					print_hdrtype(stderr, chdrtype);
1123 				}
1124 				hdrtype = chdrtype;
1125 			}
1126 			setprops(hdrtype);
1127 			/*
1128 			 * If the archive format contains extended headers, we
1129 			 * need to set up iconv().
1130 			 */
1131 			if (props.pr_flags & PR_XHDR) {
1132 				int	t = S_EXTRACT;
1133 
1134 				if (rflag || uflag)
1135 					t |= S_CREATE;
1136 				utf8_init(t);	/* iconv() setup for xhd */
1137 			}
1138 			/*
1139 			 * Wake up fifo (first block has been swapped above)
1140 			 * buf_resume() will trigger a shadow call to
1141 			 * setprops() in the fifo process to make sure that
1142 			 * the props structure is correct even in the second
1143 			 * process.
1144 			 */
1145 			buf_resume();
1146 			buf_rwake(props.pr_hdrsize); /* eat up archive header */
1147 			if (iskip)
1148 				buf_rwake(iskip);
1149 		} else {
1150 			if (readblock((char *)ptb, props.pr_hdrsize) == EOF) {
1151 				errmsgno(EX_BAD,
1152 				"Hard EOF on input, first EOF block is missing at %lld.\n",
1153 				tblocks());
1154 #ifdef	FIFO_EOF_DEBUG
1155 				if (use_fifo)	/* Debug a rare EOF problem */
1156 					fifo_prmp(1);
1157 #endif
1158 				xstats.s_hardeof++;
1159 				return (EOF);
1160 			}
1161 		}
1162 
1163 		if (H_TYPE(hdrtype) >= H_CPIO_BASE) {
1164 			/*
1165 			 * CPIO EOF check is currently in cpiotcb_to_info()
1166 			 * There is no checksum for the CPIO header.
1167 			 */
1168 			check = ocheck = 1;
1169 		} else {
1170 			/*
1171 			 * We have a TAR type archive.
1172 			 */
1173 			eof = (ptb->dbuf.t_name[0] == '\0') && checkeof(ptb);
1174 			if (eof && !ignoreerr) {
1175 				return (EOF);
1176 			}
1177 			/*
1178 			 * XXX Hier mu� eine Universalchecksummen�berpr�fung hin
1179 			 * XXX Shouldn't we use tarsum_ok() from here?
1180 			 */
1181 			stoli(ptb->dbuf.t_chksum, &ocheck, 7);
1182 			check = checksum(ptb);
1183 		}
1184 		/*
1185 		 * check == 0 : genullter Block.
1186 		 */
1187 		if (check != 0 && ocheck == check) {
1188 			char	*tmagic = ptb->ustar_dbuf.t_magic;
1189 
1190 			switch (H_TYPE(hdrtype)) {
1191 
1192 			case H_XUSTAR:
1193 			case H_EXUSTAR:
1194 				if (ismagic(tmagic) && isxmagic(ptb))
1195 					return (0);
1196 				/*
1197 				 * Both formats are equivalent.
1198 				 * Acept XSTAR too.
1199 				 */
1200 				/* FALLTHROUGH */
1201 			case H_XSTAR:
1202 				if (ismagic(tmagic) &&
1203 				    isstmagic(ptb->xstar_dbuf.t_xmagic))
1204 					return (0);
1205 				break;
1206 			case H_PAX:
1207 			case H_EPAX:
1208 			case H_USTAR:
1209 			case H_SUNTAR:
1210 				if (ismagic(tmagic))
1211 					return (0);
1212 				break;
1213 			case H_GNUTAR:
1214 				if (isgnumagic(tmagic))
1215 					return (0);
1216 				break;
1217 			case H_STAR:
1218 				tmagic = ptb->star_dbuf.t_magic;
1219 				if (ptb->dbuf.t_vers < STVERSION ||
1220 				    isstmagic(tmagic))
1221 				return (0);
1222 				break;
1223 			default:
1224 			case H_TAR:
1225 			case H_OTAR:
1226 				return (0);
1227 
1228 			case H_CPIO_CHR:		/* cpio -Hodc */
1229 				if (strxneql((char *)ptb, "070707", 6))
1230 					return (0);
1231 				break;
1232 			case H_CPIO_ASC:		/* cpio -c */
1233 				if (strxneql((char *)ptb, "070701", 6))
1234 					return (0);
1235 				break;
1236 			case H_CPIO_ACRC:		/* cpio -Hcrc */
1237 				if (strxneql((char *)ptb, "070702", 6))
1238 					return (0);
1239 				break;
1240 			case H_CPIO_NBIN:
1241 			case H_CPIO_CRC:
1242 				errmsgno(EX_BAD, "Unimplemented %ld cpio format.\n",
1243 					hdrtype);
1244 				break;
1245 			case H_CPIO_BIN:		/* cpio default */
1246 				if (strxneql((char *)ptb, "\161\307", 2))
1247 					return (0);
1248 				if (strxneql((char *)ptb, "\307\161", 2))
1249 					return (0);
1250 				break;
1251 			}
1252 			switch (H_TYPE(hdrtype)) {
1253 
1254 			case H_CPIO_CHR:		/* cpio -Hodc */
1255 			case H_CPIO_ASC:		/* cpio -c */
1256 			case H_CPIO_ACRC:		/* cpio -Hcrc */
1257 							/* First Block# is 0 */
1258 				errmsgno(EX_BAD, "Wrong magic at: %lld: '%.6s'.\n",
1259 						tblocks(), (char *)ptb);
1260 				break;
1261 			case H_CPIO_NBIN:
1262 			case H_CPIO_CRC:
1263 			case H_CPIO_BIN:		/* cpio default */
1264 							/* First Block# is 0 */
1265 				errmsgno(EX_BAD, "Wrong magic at: %lld: '0%6.6o'.\n",
1266 						tblocks(),
1267 						(((char *)ptb)[0] & 0xFF) * 256 +
1268 						(((char *)ptb)[1] & 0xFF));
1269 				break;
1270 			default:
1271 							/* First Block# is 0 */
1272 				errmsgno(EX_BAD, "Wrong magic at: %lld: '%.8s'.\n",
1273 						tblocks(), tmagic);
1274 			}
1275 			/*
1276 			 * Allow buggy gnu Volheaders & Multivolheaders to work
1277 			 */
1278 			if (H_TYPE(hdrtype) == H_GNUTAR)
1279 				return (0);
1280 
1281 		} else if (eof) {
1282 			errmsgno(EX_BAD, "EOF Block at: %lld ignored.\n",
1283 							tblocks());
1284 		} else {
1285 			if (signedtarsum(ptb, ocheck))
1286 				return (0);
1287 			errmsgno(EX_BAD, "Checksum error at: %lld: 0%lo should be 0%lo.\n",
1288 							tblocks(),
1289 							ocheck, check);
1290 		}
1291 		if (ignoreerr) {
1292 			if (H_TYPE(hdrtype) >= H_CPIO_BASE)
1293 				cpio_resync();
1294 		}
1295 	} while (ignoreerr);
1296 	exprstats(EX_BAD);
1297 	/* NOTREACHED */
1298 	return (EOF);		/* Keep lint happy */
1299 }
1300 
1301 EXPORT void
put_tcb(ptb,info)1302 put_tcb(ptb, info)
1303 	TCB	*ptb;
1304 	register FINFO	*info;
1305 {
1306 	TCB	tb;
1307 	int	x1 = 0;
1308 	int	x2 = 0;
1309 	BOOL	xhdr = FALSE;
1310 extern	BOOL	ghdr;
1311 
1312 	if ((props.pr_flags & PR_CPIO) != 0) {
1313 		put_cpioh(ptb, info);
1314 		return;
1315 	}
1316 
1317 	if (info->f_flags & (F_LONGNAME|F_LONGLINK))
1318 		x1++;
1319 	if (info->f_xflags & (XF_PATH|XF_LINKPATH))
1320 		x1++;
1321 
1322 /* XXX start alter code und Test */
1323 	if (((info->f_flags & F_ADDSLASH) ? 1:0 +
1324 	    info->f_namelen > props.pr_maxsname &&
1325 	    (ptb->dbuf.t_prefix[0] == '\0' || H_TYPE(hdrtype) == H_GNUTAR)) ||
1326 		    info->f_lnamelen > props.pr_maxslname)
1327 		x2++;
1328 
1329 	if ((x1 != x2) && info->f_xftype != XT_META) {
1330 error("type: %ld name: '%s' x1 %d x2 %d namelen: %ld prefix: '%s' lnamelen: %ld\n",
1331 info->f_filetype, info->f_name, x1, x2,
1332 info->f_namelen, ptb->dbuf.t_prefix, info->f_lnamelen);
1333 	}
1334 /* XXX ende alter code und Test */
1335 
1336 	if (props.pr_flags & PR_XHDR) {
1337 		if (!(info->f_xflags & XF_PATH)) {
1338 			if (info->f_name && !nameascii(info->f_name))
1339 				info->f_xflags |= XF_PATH;
1340 		}
1341 		if (!(info->f_xflags & XF_LINKPATH) && info->f_lnamelen) {
1342 			if (info->f_lname && !nameascii(info->f_lname))
1343 				info->f_xflags |= XF_LINKPATH;
1344 		}
1345 	}
1346 
1347 	if (x1 || x2 || (info->f_xflags != 0) || ghdr)
1348 		xhdr = TRUE;
1349 
1350 	if (!multivol && tsize > 0) {
1351 		Llong	left;
1352 		off_t	size = info->f_rsize;
1353 
1354 		left = tsize - tblocks();
1355 		if (xhdr)
1356 			left -= 6;	/* Extimated for Longname/Longlink */
1357 
1358 		if (is_link(info))
1359 			size = 0L;
1360 						/* file + tcb + EOF */
1361 		if (left < (tarblocks(size)+1+2)) {
1362 			if ((info->f_flags & F_TCB_BUF) != 0) {
1363 				movetcb(ptb, &tb);
1364 				ptb = &tb;
1365 				info->f_flags &= ~F_TCB_BUF;
1366 			}
1367 			nextotape();
1368 			newvolhdr((char *)NULL, 0, use_fifo);
1369 		}
1370 	}
1371 
1372 	if (xhdr) {
1373 		if ((info->f_flags & F_TCB_BUF) != 0) {	/* TCB is on buffer */
1374 			movetcb(ptb, &tb);
1375 			ptb = &tb;
1376 			info->f_flags &= ~F_TCB_BUF;
1377 		}
1378 		if ((info->f_xflags != 0) || ghdr) {
1379 			info_to_xhdr(info, ptb);
1380 		} else {
1381 			write_longnames(info);
1382 		}
1383 	}
1384 	write_tcb(ptb, info);
1385 }
1386 
1387 EXPORT void
write_tcb(ptb,info)1388 write_tcb(ptb, info)
1389 	TCB	*ptb;
1390 	register FINFO	*info;
1391 {
1392 	char	*addr;
1393 
1394 	if (!nullout) {				/* 17 (> 16) Bit !!! */
1395 		if (props.pr_fillc == '0')
1396 			litos(ptb->dbuf.t_chksum, checksum(ptb) & 0x1FFFF, 7);
1397 		else
1398 			litos(ptb->dbuf.t_chksum, checksum(ptb) & 0x1FFFF, 6);
1399 	}
1400 	if ((info->f_flags & F_TCB_BUF) != 0) {	/* TCB is on buffer */
1401 		addr = (char *)ptb;
1402 		put_block(TBLOCK);
1403 	} else {
1404 		addr = writeblock((char *)ptb);
1405 	}
1406 	marktcb(addr);
1407 }
1408 
1409 EXPORT void
info_to_tcb(info,ptb)1410 info_to_tcb(info, ptb)
1411 	register FINFO	*info;
1412 	register TCB	*ptb;
1413 {
1414 	if (nullout)
1415 		return;
1416 
1417 	if (H_TYPE(hdrtype) >= H_CPIO_BASE) {
1418 		cpioinfo_to_tcb(info, ptb);
1419 		return;
1420 	}
1421 
1422 	if (props.pr_fillc == '0') {
1423 		/*
1424 		 * This is a POSIX compliant header, it is allowed to use
1425 		 * 7 bytes from 8 byte headers as POSIX only requires a ' ' or
1426 		 * '\0' as last char.
1427 		 */
1428 		if (modebits)
1429 			litos(ptb->dbuf.t_mode, (Ulong)(info->f_mode|info->f_type) & 0xFFFF, 7);
1430 		else
1431 			litos(ptb->dbuf.t_mode, (Ulong)info->f_mode & 0xFFFF, 7);
1432 
1433 		if (info->f_uid > MAXOCTAL7) {
1434 			if (props.pr_flags & PR_XHDR)
1435 				info->f_xflags |= XF_UID;
1436 
1437 			if (props.pr_flags & PR_BASE256) {
1438 #if	SIZEOF_UID_T > SIZEOF_UNSIGNED_LONG_INT
1439 				if (!(info->f_uid <= ULONG_MAX))
1440 					llbtos(ptb->dbuf.t_uid, (Ullong)info->f_uid, 7);
1441 				else
1442 #endif
1443 					btos(ptb->dbuf.t_uid, info->f_uid, 7);
1444 			} else {
1445 				/*
1446 				 * Use uid_nobody?
1447 				 */
1448 				litos(ptb->dbuf.t_uid, (Ulong)0, 7);
1449 				if ((info->f_xflags & XF_UID) == 0 &&
1450 				    !errhidden(E_ID, info->f_name)) {
1451 					if (!errwarnonly(E_ID, info->f_name))
1452 						xstats.s_id++;
1453 					errmsgno(EX_BAD,
1454 						"Uid %lld for '%s' out of range.\n",
1455 						(Ullong)info->f_uid, info->f_name);
1456 					(void) errabort(E_ID, info->f_name, TRUE);
1457 				}
1458 			}
1459 		} else {
1460 			litos(ptb->dbuf.t_uid, info->f_uid, 7);
1461 		}
1462 
1463 		if (info->f_gid > MAXOCTAL7) {
1464 			if (props.pr_flags & PR_XHDR)
1465 				info->f_xflags |= XF_GID;
1466 
1467 			if (props.pr_flags & PR_BASE256) {
1468 #if	SIZEOF_GID_T > SIZEOF_UNSIGNED_LONG_INT
1469 				if (!(info->f_gid <= ULONG_MAX))
1470 					llbtos(ptb->dbuf.t_gid, (Ullong)info->f_gid, 7);
1471 				else
1472 #endif
1473 					btos(ptb->dbuf.t_gid, info->f_gid, 7);
1474 			} else {
1475 				/*
1476 				 * Use gid_nobody?
1477 				 */
1478 				litos(ptb->dbuf.t_gid, (Ulong)0, 7);
1479 				if ((info->f_xflags & XF_GID) == 0 &&
1480 				    !errhidden(E_ID, info->f_name)) {
1481 					if (!errwarnonly(E_ID, info->f_name))
1482 						xstats.s_id++;
1483 					errmsgno(EX_BAD,
1484 						"Gid %lld for '%s' out of range.\n",
1485 						(Ullong)info->f_gid, info->f_name);
1486 					(void) errabort(E_ID, info->f_name, TRUE);
1487 				}
1488 			}
1489 		} else {
1490 			litos(ptb->dbuf.t_gid, info->f_gid, 7);
1491 		}
1492 	} else {
1493 		/*
1494 		 * This is a pre POSIX header, it is only allowed to use
1495 		 * 6 bytes from 8 byte headers as historic TAR requires a ' '
1496 		 * and a '\0' as last char.
1497 		 */
1498 		if (modebits)
1499 			litos(ptb->dbuf.t_mode, (Ulong)(info->f_mode|info->f_type) & 0xFFFF, 6);
1500 		else
1501 			litos(ptb->dbuf.t_mode, (Ulong)info->f_mode & 0xFFFF, 6);
1502 
1503 		if (info->f_uid > MAXOCTAL6) {
1504 			if (props.pr_flags & PR_XHDR)
1505 				info->f_xflags |= XF_UID;
1506 
1507 			if (props.pr_flags & PR_BASE256) {
1508 #if	SIZEOF_UID_T > SIZEOF_UNSIGNED_LONG_INT
1509 				if (!(info->f_uid <= ULONG_MAX))
1510 					llbtos(ptb->dbuf.t_uid, (Ullong)info->f_uid, 7);
1511 				else
1512 #endif
1513 					btos(ptb->dbuf.t_uid, info->f_uid, 7);
1514 			} else {
1515 				/*
1516 				 * Use uid_nobody?
1517 				 */
1518 				litos(ptb->dbuf.t_uid, (Ulong)0, 6);
1519 				if ((info->f_xflags & XF_UID) == 0 &&
1520 				    !errhidden(E_ID, info->f_name)) {
1521 					if (!errwarnonly(E_ID, info->f_name))
1522 						xstats.s_id++;
1523 					errmsgno(EX_BAD,
1524 						"Uid %lld for '%s' out of range.\n",
1525 						(Ullong)info->f_uid, info->f_name);
1526 					(void) errabort(E_ID, info->f_name, TRUE);
1527 				}
1528 			}
1529 		} else {
1530 			litos(ptb->dbuf.t_uid, info->f_uid, 6);
1531 		}
1532 
1533 		if (info->f_gid > MAXOCTAL6) {
1534 			if (props.pr_flags & PR_XHDR)
1535 				info->f_xflags |= XF_GID;
1536 
1537 			if (props.pr_flags & PR_BASE256) {
1538 #if	SIZEOF_GID_T > SIZEOF_UNSIGNED_LONG_INT
1539 				if (!(info->f_gid <= ULONG_MAX))
1540 					llbtos(ptb->dbuf.t_gid, (Ullong)info->f_gid, 7);
1541 				else
1542 #endif
1543 					btos(ptb->dbuf.t_gid, info->f_gid, 7);
1544 			} else {
1545 				/*
1546 				 * Use gid_nobody?
1547 				 */
1548 				litos(ptb->dbuf.t_gid, (Ulong)0, 6);
1549 				if ((info->f_xflags & XF_GID) == 0 &&
1550 				    !errhidden(E_ID, info->f_name)) {
1551 					if (!errwarnonly(E_ID, info->f_name))
1552 						xstats.s_id++;
1553 					errmsgno(EX_BAD,
1554 						"Gid %lld for '%s' out of range.\n",
1555 						(Ullong)info->f_gid, info->f_name);
1556 					(void) errabort(E_ID, info->f_name, TRUE);
1557 				}
1558 			}
1559 		} else {
1560 			litos(ptb->dbuf.t_gid, info->f_gid, 6);
1561 		}
1562 	}
1563 
1564 	if (info->f_rsize > MAXOCTAL11 && (props.pr_flags & PR_XHDR)) {
1565 		info->f_xflags |= XF_SIZE;
1566 	}
1567 /* XXX */
1568 	if (info->f_rsize <= MAXINT32) {
1569 		litos(ptb->dbuf.t_size, (Ulong)info->f_rsize, 11);
1570 	} else {
1571 		if (info->f_rsize > MAXOCTAL11 &&
1572 		    (props.pr_flags & PR_BASE256) == 0) {
1573 			litos(ptb->dbuf.t_size, (Ulong)0, 11);
1574 		} else {
1575 			llitos(ptb->dbuf.t_size, (Ullong)info->f_rsize, 11);
1576 		}
1577 	}
1578 
1579 	if (info->f_mtime < 0 || info->f_mtime > MAXOCTAL11) {
1580 		if (props.pr_flags & PR_XHDR)
1581 			info->f_xflags |= XF_ATIME|XF_MTIME|XF_CTIME;
1582 
1583 		if (props.pr_flags & PR_BASE256) {
1584 			if (info->f_mtime <= ULONG_MAX)
1585 				btos(ptb->dbuf.t_mtime, info->f_mtime, 11);
1586 			else
1587 				llbtos(ptb->dbuf.t_mtime, (Ullong)info->f_mtime, 11);
1588 		} else {
1589 			litos(ptb->dbuf.t_mtime, (Ulong)info->f_mtime, 11);
1590 			if ((info->f_xflags & XF_MTIME) == 0 &&
1591 			    !errhidden(E_TIME, info->f_name)) {
1592 				if (!errwarnonly(E_TIME, info->f_name))
1593 					xstats.s_time++;
1594 				errmsgno(EX_BAD,
1595 					"Time %lld for '%s' out of range.\n",
1596 					(Ullong)info->f_mtime, info->f_name);
1597 				(void) errabort(E_TIME, info->f_name, TRUE);
1598 			}
1599 		}
1600 	} else {
1601 		if (props.pr_flags & PR_XHDR) {
1602 			if (info->f_mnsec != 0)
1603 				info->f_xflags |= XF_ATIME|XF_MTIME|XF_CTIME;
1604 		}
1605 		litos(ptb->dbuf.t_mtime, (Ulong)info->f_mtime, 11);
1606 	}
1607 
1608 	ptb->dbuf.t_linkflag = XTTOUS(info->f_xftype);
1609 
1610 	if (H_TYPE(hdrtype) == H_USTAR) {
1611 		info_to_ustar(info, ptb);
1612 	} else if (H_TYPE(hdrtype) == H_PAX) {
1613 		info_to_ustar(info, ptb);
1614 	} else if (H_TYPE(hdrtype) == H_EPAX) {
1615 		info_to_ustar(info, ptb);
1616 	} else if (H_TYPE(hdrtype) == H_SUNTAR) {
1617 		info_to_ustar(info, ptb);
1618 	} else if (H_TYPE(hdrtype) == H_XSTAR) {
1619 		info_to_xstar(info, ptb);
1620 	} else if (H_TYPE(hdrtype) == H_XUSTAR) {
1621 		info_to_xstar(info, ptb);
1622 	} else if (H_TYPE(hdrtype) == H_EXUSTAR) {
1623 		info_to_xstar(info, ptb);
1624 	} else if (H_TYPE(hdrtype) == H_GNUTAR) {
1625 		info_to_gnutar(info, ptb);
1626 	} else if (H_TYPE(hdrtype) == H_STAR) {
1627 		info_to_star(info, ptb);
1628 	}
1629 }
1630 
1631 /*
1632  * Used to create old star format header.
1633  */
1634 LOCAL void
info_to_star(info,ptb)1635 info_to_star(info, ptb)
1636 	register FINFO	*info;
1637 	register TCB	*ptb;
1638 {
1639 	ptb->dbuf.t_vers = STVERSION;
1640 	litos(ptb->dbuf.t_filetype, info->f_filetype & 0xFFFF, 6);	/* XXX -> 7 ??? */
1641 	litos(ptb->dbuf.t_type, (Ulong)info->f_type & 0xFFFF, 11);
1642 #ifdef	needed
1643 	/* XXX we need to do something if st_rdev is > 32 bits */
1644 	if ((info->f_rdevmaj > MAXOCTAL7 || info->f_rdevmin > MAXOCTAL7) &&
1645 	    (props.pr_flags & PR_XHDR)) {
1646 		info->f_xflags |= XF_DEVMAJOR|XF_DEVMINOR;
1647 	}
1648 #endif
1649 
1650 #if	(SIZEOF_DEV_T > SIZEOF_UNSIGNED_LONG_INT) || (SIZEOF_DEV_T > 4)
1651 	if (info->f_rdev > MAXOCTAL11) {
1652 		if (info->f_rdev <= ULONG_MAX)
1653 			btos(ptb->dbuf.t_rdev, info->f_rdev, 10);
1654 		else
1655 			llbtos(ptb->dbuf.t_rdev, (Ullong)info->f_rdev, 10);
1656 	} else
1657 #endif
1658 		litos(ptb->dbuf.t_rdev, info->f_rdev, 11);
1659 
1660 #ifdef	DEV_MINOR_NONCONTIG
1661 	ptb->dbuf.t_devminorbits = '@';
1662 	if (props.pr_flags & PR_XHDR) {
1663 		info->f_xflags |= XF_DEVMAJOR|XF_DEVMINOR;
1664 	}
1665 #else
1666 	ptb->dbuf.t_devminorbits = '@' + minorbits;
1667 #endif
1668 
1669 	if (info->f_atime < 0 || info->f_atime > MAXOCTAL11) {
1670 		if (info->f_atime <= ULONG_MAX)
1671 			btos(ptb->dbuf.t_atime, info->f_atime, 11);
1672 		else
1673 			llbtos(ptb->dbuf.t_atime, (Ullong)info->f_atime, 11);
1674 	} else {
1675 		litos(ptb->dbuf.t_atime, (Ulong)info->f_atime, 11);
1676 	}
1677 	if (info->f_ctime < 0 || info->f_ctime > MAXOCTAL11) {
1678 		if (info->f_ctime <= ULONG_MAX)
1679 			btos(ptb->dbuf.t_ctime, info->f_ctime, 11);
1680 		else
1681 			llbtos(ptb->dbuf.t_ctime, (Ullong)info->f_ctime, 11);
1682 	} else {
1683 		litos(ptb->dbuf.t_ctime, (Ulong)info->f_ctime, 11);
1684 	}
1685 	ptb->dbuf.t_magic[0] = 't';
1686 	ptb->dbuf.t_magic[1] = 'a';
1687 	ptb->dbuf.t_magic[2] = 'r';
1688 	if (!numeric) {
1689 		char	opfx0 = ptb->dbuf.t_prefix[0];
1690 
1691 		if (ic_nameuid(ptb->dbuf.t_uname, STUNMLEN+1, info->f_uid) >
1692 									TRUE) {
1693 			if (props.pr_flags & PR_XHDR)
1694 				info->f_xflags |= XF_UNAME;
1695 		}
1696 		/* XXX Korrektes overflowchecking */
1697 		if (ptb->dbuf.t_uname[STUNMLEN-1] != '\0' &&
1698 		    props.pr_flags & PR_XHDR) {
1699 			info->f_xflags |= XF_UNAME;
1700 		}
1701 		if (ic_namegid(ptb->dbuf.t_gname, STGNMLEN+1, info->f_gid) >
1702 									TRUE) {
1703 			if (props.pr_flags & PR_XHDR)
1704 				info->f_xflags |= XF_GNAME;
1705 		}
1706 		/* XXX Korrektes overflowchecking */
1707 		if (ptb->dbuf.t_gname[STGNMLEN-1] != '\0' &&
1708 		    props.pr_flags & PR_XHDR) {
1709 			info->f_xflags |= XF_GNAME;
1710 		}
1711 		if (*ptb->dbuf.t_uname) {
1712 			info->f_uname = ptb->dbuf.t_uname;
1713 			info->f_umaxlen = STUNMLEN;
1714 		}
1715 		if (*ptb->dbuf.t_gname) {
1716 			info->f_gname = ptb->dbuf.t_gname;
1717 			info->f_gmaxlen = STGNMLEN;
1718 		}
1719 		ptb->dbuf.t_prefix[0] = opfx0;	/* Overwritten by strlcpy() */
1720 	}
1721 
1722 	if (is_sparse(info) || is_multivol(info)) {
1723 		if (info->f_size > MAXOCTAL11 && (props.pr_flags & PR_XHDR)) {
1724 			info->f_xflags |= XF_REALSIZE;
1725 		}
1726 		/* XXX Korrektes overflowchecking fuer xhdr */
1727 		if (info->f_size <= MAXINT32) {
1728 			litos(ptb->xstar_in_dbuf.t_realsize, (Ulong)info->f_size, 11);
1729 		} else {
1730 			llitos(ptb->xstar_in_dbuf.t_realsize, (Ullong)info->f_size, 11);
1731 		}
1732 	}
1733 	if (is_multivol(info)) {
1734 		if (info->f_contoffset > MAXOCTAL11 && (props.pr_flags & PR_XHDR)) {
1735 			info->f_xflags |= XF_OFFSET;
1736 		}
1737 		if ((info->f_xflags & XF_OFFSET) == 0) {
1738 			/*
1739 			 * Don't fill out contoffset if we have a xheader.
1740 			 */
1741 			if (info->f_contoffset <= MAXINT32) {
1742 				litos(ptb->xstar_in_dbuf.t_offset,
1743 					(Ulong)info->f_contoffset, 11);
1744 			} else {
1745 				llitos(ptb->xstar_in_dbuf.t_offset,
1746 					(Ullong)info->f_contoffset, 11);
1747 			}
1748 		}
1749 	}
1750 }
1751 
1752 /*
1753  * Used to create USTAR, PAX, SunTAR format header.
1754  */
1755 LOCAL void
info_to_ustar(info,ptb)1756 info_to_ustar(info, ptb)
1757 	register FINFO	*info;
1758 	register TCB	*ptb;
1759 {
1760 	ptb->ustar_dbuf.t_magic[0] = 'u';
1761 	ptb->ustar_dbuf.t_magic[1] = 's';
1762 	ptb->ustar_dbuf.t_magic[2] = 't';
1763 	ptb->ustar_dbuf.t_magic[3] = 'a';
1764 	ptb->ustar_dbuf.t_magic[4] = 'r';
1765 
1766 	/*
1767 	 * strncpy is slow: use handcrafted replacement.
1768 	 */
1769 	ptb->ustar_dbuf.t_version[0] = '0';
1770 	ptb->ustar_dbuf.t_version[1] = '0';
1771 
1772 	if (!numeric) {
1773 		/* XXX Korrektes overflowchecking fuer xhdr */
1774 		if (ic_nameuid(ptb->ustar_dbuf.t_uname, TUNMLEN, info->f_uid) >
1775 									TRUE) {
1776 			if (props.pr_flags & PR_XHDR)
1777 				info->f_xflags |= XF_UNAME;
1778 		}
1779 		/* XXX Korrektes overflowchecking fuer xhdr */
1780 		if (ic_namegid(ptb->ustar_dbuf.t_gname, TGNMLEN, info->f_gid) >
1781 									TRUE) {
1782 			if (props.pr_flags & PR_XHDR)
1783 				info->f_xflags |= XF_GNAME;
1784 		}
1785 		if (*ptb->ustar_dbuf.t_uname) {
1786 			info->f_uname = ptb->ustar_dbuf.t_uname;
1787 			info->f_umaxlen = TUNMLEN;
1788 		}
1789 		if (*ptb->ustar_dbuf.t_gname) {
1790 			info->f_gname = ptb->ustar_dbuf.t_gname;
1791 			info->f_gmaxlen = TGNMLEN;
1792 		}
1793 	}
1794 	if (info->f_rdevmaj > MAXOCTAL7) {
1795 		if (props.pr_flags & PR_XHDR)
1796 			info->f_xflags |= XF_DEVMAJOR;
1797 		/*
1798 		 * XXX If we ever need to write more than a long into
1799 		 * XXX devmajor, we need to change llitos() to check
1800 		 * XXX for 7 char limits too.
1801 		 */
1802 /* XXX */
1803 		btos(ptb->ustar_dbuf.t_devmajor, info->f_rdevmaj, 7);
1804 	} else {
1805 		litos(ptb->ustar_dbuf.t_devmajor, info->f_rdevmaj, 7);
1806 	}
1807 #if	DEV_MINOR_BITS > 21		/* XXX */
1808 	/*
1809 	 * XXX The DEV_MINOR_BITS autoconf macro is only tested with 32 bit
1810 	 * XXX ints but this does not matter as it is sufficient to know that
1811 	 * XXX it will not fit into a 7 digit octal number.
1812 	 */
1813 	if (info->f_rdevmin > MAXOCTAL7) {
1814 		extern	BOOL	hpdev;
1815 
1816 		if (props.pr_flags & PR_XHDR) {
1817 			info->f_xflags |= XF_DEVMINOR;
1818 		}
1819 		if ((info->f_rdevmin <= MAXOCTAL8) && hpdev) {
1820 			char	c;
1821 
1822 			/*
1823 			 * Implement the method from HP-UX that allows 24 bit
1824 			 * for the device minor number. Note that this method
1825 			 * violates the POSIX specs.
1826 			 */
1827 			c = ptb->ustar_dbuf.t_prefix[0];
1828 			litos(ptb->ustar_dbuf.t_devminor, info->f_rdevmin, 8);
1829 			ptb->ustar_dbuf.t_prefix[0] = c;
1830 		} else {
1831 			/*
1832 			 * XXX If we ever need to write more than a long into
1833 			 * XXX devmainor, we need to change llitos() to check
1834 			 * XXX for 7 char limits too.
1835 			 */
1836 /* XXX */
1837 			btos(ptb->ustar_dbuf.t_devminor, info->f_rdevmin, 7);
1838 		}
1839 	} else
1840 #endif
1841 		{
1842 		litos(ptb->ustar_dbuf.t_devminor, info->f_rdevmin, 7);
1843 	}
1844 }
1845 
1846 /*
1847  * Used to create XSTAR, XUSTAR, EXUSTAR format header.
1848  */
1849 LOCAL void
info_to_xstar(info,ptb)1850 info_to_xstar(info, ptb)
1851 	register FINFO	*info;
1852 	register TCB	*ptb;
1853 {
1854 	info_to_ustar(info, ptb);
1855 
1856 	if (info->f_atime < 0 || info->f_atime > MAXOCTAL11) {
1857 		if (info->f_atime <= ULONG_MAX)
1858 			btos(ptb->xstar_dbuf.t_atime, (Ulong)info->f_atime, 11);
1859 		else
1860 			llbtos(ptb->xstar_dbuf.t_atime, (Ullong)info->f_atime, 11);
1861 	} else {
1862 		litos(ptb->xstar_dbuf.t_atime, (Ulong)info->f_atime, 11);
1863 	}
1864 	if (info->f_ctime < 0 || info->f_ctime > MAXOCTAL11) {
1865 		if (info->f_ctime <= ULONG_MAX)
1866 			btos(ptb->xstar_dbuf.t_ctime, (Ulong)info->f_ctime, 11);
1867 		else
1868 			llbtos(ptb->xstar_dbuf.t_ctime, (Ullong)info->f_ctime, 11);
1869 	} else {
1870 		litos(ptb->xstar_dbuf.t_ctime, (Ulong)info->f_ctime, 11);
1871 	}
1872 
1873 	/*
1874 	 * Help recognition in isxmagic(), make sure that prefix[130] is null.
1875 	 */
1876 	ptb->xstar_dbuf.t_prefix[130] = '\0';
1877 
1878 	if (H_TYPE(hdrtype) == H_XSTAR) {
1879 		ptb->xstar_dbuf.t_xmagic[0] = 't';
1880 		ptb->xstar_dbuf.t_xmagic[1] = 'a';
1881 		ptb->xstar_dbuf.t_xmagic[2] = 'r';
1882 	}
1883 	if (is_sparse(info) || is_multivol(info)) {
1884 		if (info->f_size > MAXOCTAL11 && (props.pr_flags & PR_XHDR)) {
1885 			info->f_xflags |= XF_REALSIZE;
1886 		}
1887 		/* XXX Korrektes overflowchecking fuer xhdr */
1888 		if (info->f_size <= MAXINT32) {
1889 			litos(ptb->xstar_in_dbuf.t_realsize, (Ulong)info->f_size, 11);
1890 		} else {
1891 			llitos(ptb->xstar_in_dbuf.t_realsize, (Ullong)info->f_size, 11);
1892 		}
1893 	}
1894 	if (is_multivol(info)) {
1895 		if (info->f_contoffset > MAXOCTAL11 && (props.pr_flags & PR_XHDR)) {
1896 			info->f_xflags |= XF_OFFSET;
1897 		}
1898 		if ((info->f_xflags & XF_OFFSET) == 0) {
1899 			/*
1900 			 * Don't fill out contoffset if we have a xheader.
1901 			 */
1902 			if (info->f_contoffset <= MAXINT32) {
1903 				litos(ptb->xstar_in_dbuf.t_offset,
1904 					(Ulong)info->f_contoffset, 11);
1905 			} else {
1906 				llitos(ptb->xstar_in_dbuf.t_offset,
1907 					(Ullong)info->f_contoffset, 11);
1908 			}
1909 		}
1910 	}
1911 }
1912 
1913 /*
1914  * Used to create GNU tar format header.
1915  */
1916 LOCAL void
info_to_gnutar(info,ptb)1917 info_to_gnutar(info, ptb)
1918 	register FINFO	*info;
1919 	register TCB	*ptb;
1920 {
1921 	strcpy(ptb->gnu_dbuf.t_magic, gmagic);
1922 
1923 	if (!numeric) {
1924 		if (ic_nameuid(ptb->ustar_dbuf.t_uname, TUNMLEN, info->f_uid) >
1925 									TRUE) {
1926 			if (props.pr_flags & PR_XHDR)
1927 				info->f_xflags |= XF_UNAME;
1928 		}
1929 		if (ic_namegid(ptb->ustar_dbuf.t_gname, TGNMLEN, info->f_gid) >
1930 									TRUE) {
1931 			if (props.pr_flags & PR_XHDR)
1932 				info->f_xflags |= XF_GNAME;
1933 		}
1934 		if (*ptb->ustar_dbuf.t_uname) {
1935 			info->f_uname = ptb->ustar_dbuf.t_uname;
1936 			info->f_umaxlen = TUNMLEN;
1937 		}
1938 		if (*ptb->ustar_dbuf.t_gname) {
1939 			info->f_gname = ptb->ustar_dbuf.t_gname;
1940 			info->f_gmaxlen = TGNMLEN;
1941 		}
1942 	}
1943 	if (info->f_xftype == XT_CHR || info->f_xftype == XT_BLK) {
1944 		if (info->f_rdevmaj > MAXOCTAL7) {
1945 			btos(ptb->ustar_dbuf.t_devmajor, info->f_rdevmaj, 7);
1946 		} else {
1947 			litos(ptb->ustar_dbuf.t_devmajor, info->f_rdevmaj, 7);
1948 		}
1949 		if (info->f_rdevmin > MAXOCTAL7) {
1950 			btos(ptb->ustar_dbuf.t_devminor, info->f_rdevmin, 7);
1951 		} else {
1952 			litos(ptb->ustar_dbuf.t_devminor, info->f_rdevmin, 7);
1953 		}
1954 	}
1955 
1956 	/*
1957 	 * XXX GNU tar only fill this if doing a gnudump.
1958 	 */
1959 	if (info->f_atime < 0 || info->f_atime > MAXOCTAL11) {
1960 		if (info->f_atime <= ULONG_MAX)
1961 			btos(ptb->gnu_dbuf.t_atime, (Ulong)info->f_atime, 11);
1962 		else
1963 			llbtos(ptb->gnu_dbuf.t_atime, (Ullong)info->f_atime, 11);
1964 	} else {
1965 		litos(ptb->gnu_dbuf.t_atime, (Ulong)info->f_atime, 11);
1966 	}
1967 	if (info->f_ctime < 0 || info->f_ctime > MAXOCTAL11) {
1968 		if (info->f_ctime <= ULONG_MAX)
1969 			btos(ptb->gnu_dbuf.t_ctime, (Ulong)info->f_ctime, 11);
1970 		else
1971 			llbtos(ptb->gnu_dbuf.t_ctime, (Ullong)info->f_ctime, 11);
1972 	} else {
1973 		litos(ptb->gnu_dbuf.t_ctime, (Ulong)info->f_ctime, 11);
1974 	}
1975 
1976 	if (is_sparse(info)) {
1977 		if (info->f_size <= MAXINT32) {
1978 			litos(ptb->gnu_in_dbuf.t_realsize, (Ulong)info->f_size, 11);
1979 		} else {
1980 			llitos(ptb->gnu_in_dbuf.t_realsize, (Ullong)info->f_size, 11);
1981 		}
1982 	}
1983 }
1984 
1985 EXPORT int
tcb_to_info(ptb,info)1986 tcb_to_info(ptb, info)
1987 	register TCB	*ptb;
1988 	register FINFO	*info;
1989 {
1990 	int	ret = 0;
1991 	char	xname;
1992 	char	xlink;
1993 	char	xpfx;
1994 	Ulong	ul;
1995 	Ullong	ull;
1996 	int	xt = XT_BAD;
1997 	int	rxt = XT_BAD;
1998 static	BOOL	posixwarn = FALSE;
1999 static	BOOL	namewarn = FALSE;
2000 static	BOOL	modewarn = FALSE;
2001 
2002 	/*
2003 	 * F_HAS_NAME is only used from list.c when the -listnew option is
2004 	 * present. Keep f_lname and f_name, don't read LF_LONGLINK/LF_LONGNAME
2005 	 * in this case.
2006 	 */
2007 	info->f_namelen = info->f_lnamelen = 0;
2008 	info->f_uname = info->f_gname = NULL;
2009 	info->f_umaxlen = info->f_gmaxlen = 0L;
2010 	info->f_xftype = XT_BAD;
2011 	info->f_rxftype = XT_BAD;
2012 	info->f_xflags = 0;
2013 	info->f_contoffset = (off_t)0;
2014 	info->f_flags &= F_HAS_NAME;
2015 	info->f_timeres = 1L;
2016 	info->f_fflags = 0L;
2017 	info->f_nlink = 0;
2018 	info->f_dir = NULL;
2019 	info->f_dirinos = NULL;
2020 	info->f_dirents = 0;
2021 	info->f_llsize = 0;
2022 	info->f_devminorbits = 0;
2023 
2024 	tcb_to_xhdr_reset();	/* Falsch wenn wir mehr als @ in list wollen */
2025 
2026 	if (H_TYPE(hdrtype) >= H_CPIO_BASE)
2027 		return (cpiotcb_to_info(ptb, info));
2028 
2029 	while (pr_isxheader(ptb->dbuf.t_linkflag)) {
2030 		/*
2031 		 * Handle POSIX.1-2001 extensions.
2032 		 */
2033 		if ((ptb->dbuf.t_linkflag == LF_XHDR ||
2034 				    ptb->dbuf.t_linkflag == LF_GHDR ||
2035 				    ptb->dbuf.t_linkflag == LF_VU_XHDR)) {
2036 			ret = tcb_to_xhdr(ptb, info);
2037 			info->f_flags &= ~F_DATA_SKIPPED;
2038 			if (ret != 0)
2039 				return (ret);
2040 
2041 			xt  = info->f_xftype;
2042 			rxt = info->f_rxftype;
2043 		}
2044 		/*
2045 		 * Handle very long names the old (star & gnutar) way.
2046 		 */
2047 		if ((info->f_flags & F_HAS_NAME) == 0 &&
2048 					props.pr_nflags & PR_LONG_NAMES) {
2049 			while (ret == 0 &&
2050 				    (ptb->dbuf.t_linkflag == LF_LONGLINK ||
2051 				    ptb->dbuf.t_linkflag == LF_LONGNAME)) {
2052 				ret = tcb_to_longname(ptb, info);
2053 				info->f_flags &= ~F_DATA_SKIPPED;
2054 			}
2055 			if (ret)
2056 				return (ret);
2057 		}
2058 	}
2059 	if (!pr_validtype(ptb->dbuf.t_linkflag)) {
2060 		errmsgno(EX_BAD,
2061 		"WARNING: Archive contains unknown typeflag '%c' (0x%02X) at %lld.\n",
2062 			ptb->dbuf.t_linkflag, ptb->dbuf.t_linkflag, tblocks());
2063 	}
2064 
2065 	if (ptb->ndbuf.t_name[NAMSIZ] == '\0') { /* "ndbuf" is NAMSIZE+1 */
2066 		if (ptb->dbuf.t_name[NAMSIZ-1] == '\0') {
2067 			if (!nowarn && !modewarn) {
2068 				errmsgno(EX_BAD,
2069 				"WARNING: Archive violates POSIX 1003.1 (mode field starts with null byte).\n");
2070 				modewarn = TRUE;
2071 			}
2072 		} else if (!nowarn && !namewarn) {
2073 			errmsgno(EX_BAD,
2074 			"WARNING: Archive violates POSIX 1003.1 (100 char filename is null terminated).\n");
2075 			namewarn = TRUE;
2076 		}
2077 		ptb->ndbuf.t_name[NAMSIZ] = ' ';
2078 	}
2079 	stoli(ptb->dbuf.t_mode, &ul, 7);
2080 	info->f_mode = ul;
2081 	if (info->f_mode & ~07777) {
2082 		if (!nowarn && !modebits && H_TYPE(hdrtype) == H_USTAR && !posixwarn) {
2083 			errmsgno(EX_BAD,
2084 			"WARNING: Archive violates POSIX 1003.1 (too many bits in mode field).\n");
2085 			posixwarn = TRUE;
2086 		}
2087 		info->f_mode &= 07777;
2088 	}
2089 	if ((info->f_xflags & XF_UID) == 0) {
2090 		if (ptb->dbuf.t_uid[0] & 0x80)
2091 			stob(ptb->dbuf.t_uid, &ul, 7);
2092 		else
2093 			stoli(ptb->dbuf.t_uid, &ul, 7);
2094 		info->f_uid = ul;
2095 		if (info->f_uid != ul) {
2096 			print_hrange("uid", (Ullong)ul);
2097 			info->f_flags |= F_BAD_UID;
2098 			info->f_uid = ic_uid_nobody();
2099 		}
2100 	}
2101 	if ((info->f_xflags & XF_UID) == 0) {
2102 		if (ptb->dbuf.t_gid[0] & 0x80)
2103 			stob(ptb->dbuf.t_gid, &ul, 7);
2104 		else
2105 			stoli(ptb->dbuf.t_gid, &ul, 7);
2106 		info->f_gid = ul;
2107 		if (info->f_gid != ul) {
2108 			print_hrange("gid", (Ullong)ul);
2109 			info->f_flags |= F_BAD_GID;
2110 			info->f_gid = ic_gid_nobody();
2111 		}
2112 	}
2113 
2114 	/*
2115 	 * Possible flags from extended header:
2116 	 * XF_SIZE|XF_REALSIZE	Found either	"size" or
2117 	 *					"SCHILY.realsize" and "size"
2118 	 * XF_REALSIZE		Found only	"SCHILY.realsize"
2119 	 * 0			Found neither	"SCHILY.realsize" nor "size"
2120 	 */
2121 	if ((info->f_xflags & XF_SIZE) == 0) {
2122 		stolli(ptb->dbuf.t_size, &ull);
2123 		if ((info->f_xflags & XF_SIZE) == 0) {
2124 			info->f_rsize = info->f_llsize = ull;
2125 			if (info->f_rsize != ull) {
2126 				print_hrange("size", ull);
2127 				info->f_rsize = 0,
2128 				info->f_flags |= (F_BAD_META | F_BAD_SIZE);
2129 			}
2130 		}
2131 		if ((info->f_xflags & XF_REALSIZE) == 0)
2132 			info->f_size = ull;
2133 	}
2134 
2135 	switch (ptb->dbuf.t_linkflag) {
2136 
2137 	case LNKTYPE:
2138 		if (linkdata)
2139 			break;
2140 		if (props.pr_flags & PR_LINK_DATA)
2141 			break;
2142 		/* FALLTHROUGH */
2143 	case DIRTYPE:
2144 	case CHRTYPE:
2145 	case BLKTYPE:
2146 	case FIFOTYPE:
2147 	case LF_META:
2148 		info->f_rsize = 0L;
2149 		info->f_llsize = 0L;
2150 		break;
2151 
2152 	default:
2153 		/*
2154 		 * Nothing to do here, we did handle this already above the
2155 		 * switch statement.
2156 		 */
2157 		break;
2158 	}
2159 
2160 	if ((info->f_xflags & XF_MTIME) == 0) {
2161 		if (ptb->dbuf.t_mtime[0] & 0x80)
2162 			stob(ptb->dbuf.t_mtime, &ul, 11);
2163 		else
2164 			stoli(ptb->dbuf.t_mtime, &ul, 11);
2165 		info->f_mtime = (time_t)ul;
2166 		info->f_mnsec = 0L;
2167 		if (info->f_mtime != ul) {
2168 			print_hrange("time", (Ullong)ul);
2169 			info->f_mtime = 0;
2170 		}
2171 	}
2172 
2173 	info->f_typeflag = ptb->ustar_dbuf.t_typeflag;
2174 
2175 	switch (H_TYPE(hdrtype)) {
2176 
2177 	default:
2178 	case H_TAR:
2179 	case H_OTAR:
2180 		tar_to_info(ptb, info);
2181 		break;
2182 	case H_PAX:
2183 	case H_EPAX:
2184 	case H_USTAR:
2185 	case H_SUNTAR:
2186 		ustar_to_info(ptb, info);
2187 		break;
2188 	case H_XSTAR:
2189 	case H_XUSTAR:
2190 	case H_EXUSTAR:
2191 		xstar_to_info(ptb, info);
2192 		break;
2193 	case H_GNUTAR:
2194 		gnutar_to_info(ptb, info);
2195 		break;
2196 	case H_STAR:
2197 		star_to_info(ptb, info);
2198 		break;
2199 	}
2200 	info->f_rxftype = info->f_xftype;
2201 	if (rxt != XT_BAD) {
2202 		info->f_rxftype = rxt;
2203 		info->f_filetype = XTTOST(info->f_rxftype);
2204 		info->f_type = XTTOIF(info->f_rxftype);
2205 		/*
2206 		 * XT_LINK may be any 'real' file type,
2207 		 * XT_META may be either a regular file or a contigouos file.
2208 		 */
2209 		if (info->f_xftype != XT_LINK && info->f_xftype != XT_META)
2210 			info->f_xftype = info->f_rxftype;
2211 	}
2212 	if (xt != XT_BAD) {
2213 		info->f_xftype = xt;
2214 	}
2215 
2216 	/*
2217 	 * Hack for list module (option -newest) ...
2218 	 * Save and restore t_name[NAMSIZ] & t_linkname[NAMSIZ]
2219 	 * Use "ndbuf" to permit NAMESIZE as index.
2220 	 */
2221 	xname = ptb->ndbuf.t_name[NAMSIZ];
2222 	ptb->ndbuf.t_name[NAMSIZ] = '\0';	/* allow 100 chars in name */
2223 	xlink = ptb->ndbuf.t_linkname[NAMSIZ];
2224 	ptb->ndbuf.t_linkname[NAMSIZ] = '\0'; /* allow 100 chars in linkname */
2225 	xpfx = ptb->ndbuf.t_prefix[PFXSIZ];
2226 	ptb->ndbuf.t_prefix[PFXSIZ] = '\0';	/* allow 155 chars in prefix */
2227 
2228 	/*
2229 	 * Handle long name in posix split form now.
2230 	 * Also copy ptb->dbuf.t_linkname[] if namelen is == 100.
2231 	 */
2232 	tcb_to_name(ptb, info);
2233 
2234 	ptb->ndbuf.t_name[NAMSIZ] = xname;	/* restore remembered value */
2235 	ptb->ndbuf.t_linkname[NAMSIZ] = xlink;	/* restore remembered value */
2236 	ptb->ndbuf.t_prefix[PFXSIZ] = xpfx;	/* restore remembered value */
2237 
2238 	if (info->f_flags & F_BAD_UID)
2239 		info->f_mode &= ~TSUID;
2240 	if (info->f_flags & F_BAD_GID)
2241 		info->f_mode &= ~TSGID;
2242 
2243 	return (ret);
2244 }
2245 
2246 /*
2247  * Used to convert from old tar format header.
2248  */
2249 LOCAL void
tar_to_info(ptb,info)2250 tar_to_info(ptb, info)
2251 	register TCB	*ptb;
2252 	register FINFO	*info;
2253 {
2254 	register int	typeflag = ptb->ustar_dbuf.t_typeflag;
2255 		char	xname;
2256 
2257 	xname = ptb->ndbuf.t_name[NAMSIZ];
2258 	ptb->ndbuf.t_name[NAMSIZ] = '\0';	/* allow 100 chars in name */
2259 
2260 	if (ptb->ndbuf.t_name[0] != '\0' &&
2261 	    ptb->ndbuf.t_name[strlen(ptb->ndbuf.t_name) - 1] == '/') {
2262 		typeflag = DIRTYPE;
2263 		info->f_filetype = F_DIR;
2264 		info->f_rsize = (off_t)0;	/* XXX hier?? siehe oben */
2265 	} else if (typeflag == SYMTYPE) {
2266 		info->f_filetype = F_SLINK;
2267 	} else if (typeflag != DIRTYPE) {
2268 		info->f_filetype = F_FILE;
2269 	}
2270 	ptb->ndbuf.t_name[NAMSIZ] = xname;	/* restore remembered value */
2271 
2272 	info->f_xftype = USTOXT(typeflag);
2273 	info->f_type = XTTOIF(info->f_xftype);
2274 	info->f_rdevmaj = info->f_rdevmin = info->f_rdev = 0;
2275 	info->f_ctime = info->f_atime = info->f_mtime;
2276 	info->f_cnsec = info->f_ansec = 0L;
2277 }
2278 
2279 /*
2280  * Used to convert from old star format header.
2281  */
2282 LOCAL void
star_to_info(ptb,info)2283 star_to_info(ptb, info)
2284 	register TCB	*ptb;
2285 	register FINFO	*info;
2286 {
2287 	Ulong	id;
2288 	uid_t	uid;
2289 	gid_t	gid;
2290 	Ullong	ull;
2291 	int	mbits;
2292 
2293 	version = ptb->dbuf.t_vers;
2294 	if (ptb->dbuf.t_vers < STVERSION) {
2295 		tar_to_info(ptb, info);
2296 		return;
2297 	}
2298 	stoli(ptb->dbuf.t_filetype, &info->f_filetype, 7);
2299 	stoli(ptb->dbuf.t_type, &id, 11);
2300 	info->f_type = id;
2301 	/*
2302 	 * star Erweiterungen sind wieder ANSI kompatibel, d.h. linkflag
2303 	 * h�lt den echten Dateityp (LONKLINK, LONGNAME, SPARSE ...)
2304 	 */
2305 	if (ptb->dbuf.t_linkflag < '1')
2306 		info->f_xftype = IFTOXT(info->f_type);
2307 	else
2308 		info->f_xftype = USTOXT(ptb->ustar_dbuf.t_typeflag);
2309 
2310 	if (ptb->dbuf.t_rdev[0] & 0x80)
2311 		stob(ptb->dbuf.t_rdev, &id, 10); /* Last c is t_devminorbits */
2312 	else
2313 		stoli(ptb->dbuf.t_rdev, &id, 11);
2314 	info->f_rdev = id;
2315 	if ((info->f_rdev != id) && is_dev(info)) {
2316 		print_hrange("rdev", (Ullong)id);
2317 		info->f_flags |= F_BAD_META;
2318 	}
2319 	if ((info->f_xflags & (XF_DEVMAJOR|XF_DEVMINOR)) !=
2320 						(XF_DEVMAJOR|XF_DEVMINOR)) {
2321 		mbits = ptb->dbuf.t_devminorbits - '@';
2322 		if (((mbits + CHAR_BIT-1) / CHAR_BIT) > sizeof (info->f_rdev)) {
2323 			errmsgno(EX_BAD,
2324 			"WARNING: Too many (%d) minor bits in header at %lld.\n",
2325 				mbits,
2326 				tblocks());
2327 			mbits = -1;
2328 		}
2329 		if (mbits == 0) {
2330 			static	BOOL	dwarned = FALSE;
2331 			if (!dwarned && is_dev(info)) {	/* Only warn for devices */
2332 #ifdef	DEV_MINOR_NONCONTIG
2333 				errmsgno(EX_BAD,
2334 				"WARNING: Minor device numbers are non contiguous.\n");
2335 				errmsgno(EX_BAD,
2336 				"WARNING: Devices may not be extracted correctly.\n");
2337 #else
2338 				errmsgno(EX_BAD,
2339 				"WARNING: The archiving system used non contiguous minor numbers.\n");
2340 				errmsgno(EX_BAD,
2341 				"WARNING: Cannot extract devices correctly.\n");
2342 #endif
2343 				dwarned = TRUE;
2344 			}
2345 			/*
2346 			 * Let us hope that both, the archiving and the
2347 			 * extracting system use the same major()/minor()
2348 			 * mapping.
2349 			 */
2350 			info->f_rdevmaj	= major(info->f_rdev);
2351 			info->f_rdevmin	= minor(info->f_rdev);
2352 		} else {
2353 			/*
2354 			 * Convert from remote major()/minor() mapping to
2355 			 * local major()/minor() mapping.
2356 			 */
2357 			if (mbits < 0)		/* Old star format */
2358 				mbits = 8;
2359 			info->f_rdevmaj	= _dev_major(mbits, info->f_rdev);
2360 			info->f_rdevmin	= _dev_minor(mbits, info->f_rdev);
2361 			info->f_rdev = makedev(info->f_rdevmaj, info->f_rdevmin);
2362 		}
2363 	}
2364 
2365 	if ((info->f_xflags & XF_ATIME) == 0) {
2366 		if (ptb->dbuf.t_atime[0] & 0x80)
2367 			stob(ptb->dbuf.t_atime, &id, 11);
2368 		else
2369 			stoli(ptb->dbuf.t_atime, &id, 11);
2370 		info->f_atime = (time_t)id;
2371 		info->f_ansec = 0L;
2372 	}
2373 	if ((info->f_xflags & XF_CTIME) == 0) {
2374 		if (ptb->dbuf.t_ctime[0] & 0x80)
2375 			stob(ptb->dbuf.t_ctime, &id, 11);
2376 		else
2377 			stoli(ptb->dbuf.t_ctime, &id, 11);
2378 		info->f_ctime = (time_t)id;
2379 		info->f_cnsec = 0L;
2380 	}
2381 
2382 	if ((info->f_xflags & XF_UNAME) == 0) {
2383 		if (*ptb->dbuf.t_uname) {
2384 			info->f_uname = ptb->dbuf.t_uname;
2385 			info->f_umaxlen = STUNMLEN;
2386 		}
2387 	}
2388 	if (info->f_uname) {
2389 		char	xname;
2390 
2391 		xname = ptb->dbuf.t_gname[0];
2392 		ptb->dbuf.t_gname[0] = '\0';
2393 		if (!numeric && ic_uidname(info->f_uname, info->f_umaxlen, &uid)) {
2394 			info->f_flags &= ~F_BAD_UID;
2395 			info->f_uid = uid;
2396 		}
2397 		ptb->dbuf.t_gname[0] = xname;
2398 	}
2399 	if ((info->f_xflags & XF_GNAME) == 0) {
2400 		if (*ptb->dbuf.t_gname) {
2401 			info->f_gname = ptb->dbuf.t_gname;
2402 			info->f_gmaxlen = STGNMLEN;
2403 		}
2404 	}
2405 	if (info->f_gname) {
2406 		char	xname;
2407 
2408 		xname = ptb->dbuf.t_prefix[0];
2409 		ptb->dbuf.t_prefix[0] = '\0';
2410 		if (!numeric && ic_gidname(info->f_gname, info->f_gmaxlen, &gid)) {
2411 			info->f_flags &= ~F_BAD_GID;
2412 			info->f_gid = gid;
2413 		}
2414 		ptb->dbuf.t_prefix[0] = xname;
2415 	}
2416 
2417 	if (is_sparse(info) || is_multivol(info)) {
2418 		if ((info->f_xflags & XF_REALSIZE) == 0) {
2419 			stolli(ptb->xstar_in_dbuf.t_realsize, &ull);
2420 			info->f_size = ull;
2421 		}
2422 	}
2423 	if (is_multivol(info)) {
2424 		if ((info->f_xflags & XF_OFFSET) == 0) {
2425 			stolli(ptb->xstar_in_dbuf.t_offset, &ull);
2426 			info->f_contoffset = ull;
2427 		}
2428 	}
2429 }
2430 
2431 /*
2432  * Used to convert from USTAR, PAX, SunTAR format header.
2433  */
2434 LOCAL void
ustar_to_info(ptb,info)2435 ustar_to_info(ptb, info)
2436 	register TCB	*ptb;
2437 	register FINFO	*info;
2438 {
2439 	uid_t	uid;
2440 	gid_t	gid;
2441 	dev_t	d;
2442 	Ulong	ul;
2443 	char	c;
2444 
2445 	info->f_xftype = USTOXT(ptb->ustar_dbuf.t_typeflag);
2446 	info->f_filetype = XTTOST(info->f_xftype);
2447 	info->f_type = XTTOIF(info->f_xftype);
2448 
2449 	if ((info->f_xflags & XF_UNAME) == 0) {
2450 		if (*ptb->ustar_dbuf.t_uname) {
2451 			info->f_uname = ptb->ustar_dbuf.t_uname;
2452 			info->f_umaxlen = TUNMLEN;
2453 		}
2454 	}
2455 	if (info->f_uname) {
2456 		char	xname;
2457 
2458 		xname = ptb->ustar_dbuf.t_gname[0];
2459 		ptb->ustar_dbuf.t_gname[0] = '\0';
2460 		if (!numeric && ic_uidname(info->f_uname, info->f_umaxlen, &uid)) {
2461 			info->f_flags &= ~F_BAD_UID;
2462 			info->f_uid = uid;
2463 		}
2464 		ptb->ustar_dbuf.t_gname[0] = xname;
2465 	}
2466 	if ((info->f_xflags & XF_GNAME) == 0) {
2467 		if (*ptb->ustar_dbuf.t_gname) {
2468 			info->f_gname = ptb->ustar_dbuf.t_gname;
2469 			info->f_gmaxlen = TGNMLEN;
2470 		}
2471 	}
2472 	if (info->f_gname) {
2473 		char	xname;
2474 
2475 		xname = ptb->ustar_dbuf.t_devmajor[0];
2476 		ptb->ustar_dbuf.t_devmajor[0] = '\0';
2477 		if (!numeric && ic_gidname(info->f_gname, info->f_gmaxlen, &gid)) {
2478 			info->f_flags &= ~F_BAD_GID;
2479 			info->f_gid = gid;
2480 		}
2481 		ptb->ustar_dbuf.t_devmajor[0] = xname;
2482 	}
2483 
2484 	if ((info->f_xflags & XF_DEVMAJOR) == 0) {
2485 		if (ptb->ustar_dbuf.t_devmajor[0] & 0x80)
2486 			stob(ptb->ustar_dbuf.t_devmajor, &ul, 7);
2487 		else
2488 			stoli(ptb->ustar_dbuf.t_devmajor, &ul, 7);
2489 		info->f_rdevmaj = ul;
2490 		d = makedev(info->f_rdevmaj, 0);
2491 		d = major(d);
2492 		if ((d != ul) && is_dev(info)) {
2493 			print_hrange("rdevmajor", (Ullong)ul);
2494 			info->f_flags |= F_BAD_META;
2495 		}
2496 	}
2497 
2498 	if ((info->f_xflags & XF_DEVMINOR) == 0) {
2499 		if (ptb->ustar_dbuf.t_devminor[0] & 0x80) {
2500 			stob(ptb->ustar_dbuf.t_devminor, &ul, 7);
2501 		} else {
2502 			/*
2503 			 * The 'tar' that comes with HP-UX writes illegal tar
2504 			 * archives. It includes 8 characters in the minor
2505 			 * field and allows to archive 24 bits for the minor
2506 			 * device which are used by HP-UX. As we like to be
2507 			 * able to read these archives, we need to convert
2508 			 * the number carefully by temporarily writing a NULL
2509 			 * to the next character and restoring the right
2510 			 * content afterwards.
2511 			 */
2512 			c = ptb->ustar_dbuf.t_prefix[0];
2513 			ptb->ustar_dbuf.t_prefix[0] = '\0';
2514 			stoli(ptb->ustar_dbuf.t_devminor, &ul, 8);
2515 			ptb->ustar_dbuf.t_prefix[0] = c;
2516 		}
2517 		info->f_rdevmin = ul;
2518 		d = makedev(0, info->f_rdevmin);
2519 		d = minor(d);
2520 		if ((d != ul) && is_dev(info)) {
2521 			print_hrange("rdevminor", (Ullong)ul);
2522 			info->f_flags |= F_BAD_META;
2523 		}
2524 	}
2525 
2526 	info->f_rdev = makedev(info->f_rdevmaj, info->f_rdevmin);
2527 
2528 	/*
2529 	 * ANSI Tar hat keine atime & ctime im Header!
2530 	 */
2531 	if ((info->f_xflags & XF_ATIME) == 0) {
2532 		info->f_atime = info->f_mtime;
2533 		info->f_ansec = 0L;
2534 	}
2535 	if ((info->f_xflags & XF_CTIME) == 0) {
2536 		info->f_ctime = info->f_mtime;
2537 		info->f_cnsec = 0L;
2538 	}
2539 }
2540 
2541 /*
2542  * Used to convert from XSTAR, XUSTAR, EXUSTAR format header.
2543  */
2544 LOCAL void
xstar_to_info(ptb,info)2545 xstar_to_info(ptb, info)
2546 	register TCB	*ptb;
2547 	register FINFO	*info;
2548 {
2549 	Ulong	ul;
2550 	Ullong	ull;
2551 
2552 	ustar_to_info(ptb, info);
2553 
2554 	if ((info->f_xflags & XF_ATIME) == 0) {
2555 		if (ptb->xstar_dbuf.t_atime[0] & 0x80)
2556 			stob(ptb->xstar_dbuf.t_atime, &ul, 11);
2557 		else
2558 			stoli(ptb->xstar_dbuf.t_atime, &ul, 11);
2559 		info->f_atime = (time_t)ul;
2560 		info->f_ansec = 0L;
2561 	}
2562 	if ((info->f_xflags & XF_CTIME) == 0) {
2563 		if (ptb->xstar_dbuf.t_ctime[0] & 0x80)
2564 			stob(ptb->xstar_dbuf.t_ctime, &ul, 11);
2565 		else
2566 			stoli(ptb->xstar_dbuf.t_ctime, &ul, 11);
2567 		info->f_ctime = (time_t)ul;
2568 		info->f_cnsec = 0L;
2569 	}
2570 
2571 	if (is_sparse(info) || is_multivol(info)) {
2572 		if ((info->f_xflags & XF_REALSIZE) == 0) {
2573 			stolli(ptb->xstar_in_dbuf.t_realsize, &ull);
2574 			info->f_size = ull;
2575 		}
2576 	}
2577 	if (is_multivol(info)) {
2578 		if ((info->f_xflags & XF_OFFSET) == 0) {
2579 			stolli(ptb->xstar_in_dbuf.t_offset, &ull);
2580 			info->f_contoffset = ull;
2581 		}
2582 	}
2583 }
2584 
2585 /*
2586  * Used to convert from GNU tar format header.
2587  */
2588 LOCAL void
gnutar_to_info(ptb,info)2589 gnutar_to_info(ptb, info)
2590 	register TCB	*ptb;
2591 	register FINFO	*info;
2592 {
2593 	Ulong	ul;
2594 	Ullong	ull;
2595 
2596 	ustar_to_info(ptb, info);
2597 
2598 	if ((info->f_xflags & XF_ATIME) == 0) {
2599 		if (ptb->gnu_dbuf.t_atime[0] & 0x80)
2600 			stob(ptb->gnu_dbuf.t_atime, &ul, 11);
2601 		else
2602 			stoli(ptb->gnu_dbuf.t_atime, &ul, 11);
2603 		info->f_atime = (time_t)ul;
2604 		info->f_ansec = 0L;
2605 		if (info->f_atime == 0 && ptb->gnu_dbuf.t_atime[0] == '\0')
2606 			info->f_atime = info->f_mtime;
2607 		else
2608 			info->f_xflags |= XF_ATIME;
2609 	}
2610 
2611 	if ((info->f_xflags & XF_CTIME) == 0) {
2612 		if (ptb->gnu_dbuf.t_ctime[0] & 0x80)
2613 			stob(ptb->gnu_dbuf.t_ctime, &ul, 11);
2614 		else
2615 			stoli(ptb->gnu_dbuf.t_ctime, &ul, 11);
2616 		info->f_ctime = (time_t)ul;
2617 		info->f_cnsec = 0L;
2618 		if (info->f_ctime == 0 && ptb->gnu_dbuf.t_ctime[0] == '\0')
2619 			info->f_ctime = info->f_mtime;
2620 		else
2621 			info->f_xflags |= XF_CTIME;
2622 	}
2623 
2624 	if (is_sparse(info)) {
2625 		stolli(ptb->gnu_in_dbuf.t_realsize, &ull);
2626 		info->f_size = ull;
2627 	}
2628 	if (is_multivol(info)) {
2629 		stolli(ptb->gnu_dbuf.t_offset, &ull);
2630 		info->f_contoffset = ull;
2631 	}
2632 }
2633 
2634 LOCAL int
ustoxt(ustype)2635 ustoxt(ustype)
2636 	char	ustype;
2637 {
2638 	/*
2639 	 * Map ANSI types
2640 	 */
2641 	if (ustype >= REGTYPE && ustype <= CONTTYPE)
2642 		return (_USTOXT(ustype));
2643 
2644 	/*
2645 	 * Map Vendor Unique (Gnu tar & Star) types ANSI: "local enhancements"
2646 	 */
2647 	if ((props.pr_flags & (PR_LOCAL_STAR|PR_LOCAL_GNU)) &&
2648 					ustype >= 'A' && ustype <= 'Z')
2649 		return (_VTTOXT(ustype));
2650 
2651 	/*
2652 	 * treat unknown types as regular files conforming to standard
2653 	 */
2654 	return (XT_FILE);
2655 }
2656 
2657 LOCAL BOOL
checkeof(ptb)2658 checkeof(ptb)
2659 	TCB	*ptb;
2660 {
2661 extern	m_stats	*stats;
2662 extern	long	bigcnt;
2663 extern	char	*bigbase;
2664 	long	lastsize = 0;
2665 
2666 	if (!eofblock(ptb))
2667 		return (FALSE);
2668 	if (debug)
2669 		errmsgno(EX_BAD, "First  EOF Block at %lld OK\n", tblocks());
2670 
2671 	stats->eofblock = tblocks();
2672 	markeof();
2673 	if (bigcnt == 0 && (rflag || uflag)) {
2674 		/*
2675 		 * If bigcnt == 0, the next readblock() call reads a new
2676 		 * tape record and overwrites the current bigbuf data.
2677 		 * Save the current read data in the buffer save area.
2678 		 */
2679 		movebytes(bigbuf, bigbase, bigsize);
2680 		lastsize = stats->lastsize;
2681 	}
2682 
2683 	if (readblock((char *)ptb, TBLOCK) == EOF) {
2684 		errmsgno(EX_BAD,
2685 		"Incorrect EOF, second EOF block is missing at %lld.\n",
2686 		tblocks());
2687 		goto goteof;
2688 	}
2689 	if (!eofblock(ptb)) {
2690 		if (!nowarn)
2691 			errmsgno(EX_BAD,
2692 			"WARNING: Partial (single block) EOF detected at %lld.\n",
2693 			tblocks());
2694 		return (FALSE);
2695 	}
2696 	if (debug)
2697 		errmsgno(EX_BAD, "Second EOF Block OK at %lld\n", tblocks());
2698 
2699 	stats->eofblock = tblocks();
2700 goteof:
2701 	if (lastsize) {
2702 		/*
2703 		 * Restore the old buffer content and back position the archive
2704 		 * by one more tape block.
2705 		 */
2706 		movebytes(bigbase, bigbuf, bigsize);
2707 		stats->lastsize = lastsize;
2708 		backtape();
2709 	}
2710 	return (TRUE);
2711 }
2712 
2713 LOCAL BOOL
eofblock(ptb)2714 eofblock(ptb)
2715 	TCB	*ptb;
2716 {
2717 	register short	i;
2718 	register char	*s = (char *)ptb;
2719 
2720 	if (props.pr_nflags & PR_DUMB_EOF)
2721 		return (ptb->dbuf.t_name[0] == '\0');
2722 
2723 	for (i = 0; i < TBLOCK; i++)
2724 		if (*s++ != '\0')
2725 			return (FALSE);
2726 	return (TRUE);
2727 }
2728 
2729 /*
2730  * Convert string -> long int
2731  */
2732 LOCAL void
stoli(s,l,fieldw)2733 stoli(s, l, fieldw)
2734 	register char	*s;
2735 		Ulong	*l;
2736 		int	fieldw;
2737 {
2738 	register Ulong	ret = 0L;
2739 	register char	c;
2740 	register int	t;
2741 	register char	*ep = s + fieldw;
2742 
2743 #ifdef	__never__
2744 	/*
2745 	 * We do not like this to be used for the t_chksum field.
2746 	 */
2747 	if (*((Uchar*)s) & 0x80) {
2748 		stob(s, l, 7);
2749 		return;
2750 	}
2751 #endif
2752 
2753 	while (*s == ' ') {
2754 		if (s++ >= ep)
2755 			break;
2756 	}
2757 
2758 	for (; s <= ep; ) {
2759 		c = *s++;
2760 		if (isoctal(c)) {
2761 			t = c - '0';
2762 		} else {
2763 			--s;
2764 			break;
2765 		}
2766 		ret *= 8;
2767 		ret += t;
2768 	}
2769 	*l = ret;
2770 	if (s > ep) {
2771 		errmsgno(EX_BAD,
2772 			"WARNING: Unterminated octal number at %lld.\n",
2773 			tblocks());
2774 	}
2775 }
2776 
2777 /*
2778  * Convert string -> long long int
2779  */
2780 EXPORT void
stolli(s,ull)2781 stolli(s, ull)
2782 	register char	*s;
2783 		Ullong	*ull;
2784 {
2785 	register Ullong	ret = (Ullong)0;
2786 	register char	c;
2787 	register int	t;
2788 	register char	*ep = s + 11;
2789 
2790 	if (*((Uchar*)s) & 0x80) {
2791 		stollb(s, ull, 11);
2792 #ifdef	B256_DEBUG
2793 		fprintf(stderr, "VALL %lld\n", *ull);
2794 #endif
2795 		return;
2796 	}
2797 
2798 	while (*s == ' ') {
2799 		if (s++ >= ep)
2800 			break;
2801 	}
2802 
2803 	for (; s <= ep; ) {
2804 		c = *s++;
2805 		if (isoctal(c)) {
2806 			t = c - '0';
2807 		} else {
2808 			--s;
2809 			break;
2810 		}
2811 		ret *= 8;
2812 		ret += t;
2813 	}
2814 	*ull = ret;
2815 	if (s > ep) {
2816 		errmsgno(EX_BAD,
2817 			"WARNING: Unterminated octal number at %lld.\n",
2818 			tblocks());
2819 	}
2820 }
2821 
2822 /*
2823  * Convert long int -> string.
2824  */
2825 LOCAL void
litos(s,l,fieldw)2826 litos(s, l, fieldw)
2827 		char	*s;
2828 	register Ulong	l;
2829 	register int	fieldw;
2830 {
2831 	register char	*p	= &s[fieldw+1];
2832 	register char	fill	= props.pr_fillc;
2833 
2834 	/*
2835 	 * Bei 12 Byte Feldern w�rde hier das N�chste Feld �berschrieben, wenn
2836 	 * entgegen der normalen Reihenfolge geschrieben wird!
2837 	 * Da der TCB sowieso vorher genullt wird ist es aber kein Problem
2838 	 * das bei 8 Bytes Feldern notwendige Nullbyte wegzulassen.
2839 	 */
2840 #ifdef	__needed__
2841 	*p = '\0';
2842 #endif
2843 	/*
2844 	 * Das Zeichen nach einer Zahl.
2845 	 * XXX Soll hier besser ein NULL Byte bei POSIX Tar hin?
2846 	 * XXX Wuerde das Probleme mit einer automatischen Erkennung geben?
2847 	 */
2848 	*--p = ' ';
2849 
2850 	do {
2851 		*--p = (l%8) + '0';	/* Compiler optimiert */
2852 
2853 	} while (--fieldw > 0 && (l /= 8) > 0);
2854 
2855 	switch (fieldw) {
2856 
2857 	default:
2858 		break;
2859 	case 11:	*--p = fill;	/* FALLTHROUGH */
2860 	case 10:	*--p = fill;	/* FALLTHROUGH */
2861 	case 9:		*--p = fill;	/* FALLTHROUGH */
2862 	case 8:		*--p = fill;	/* FALLTHROUGH */
2863 	case 7:		*--p = fill;	/* FALLTHROUGH */
2864 	case 6:		*--p = fill;	/* FALLTHROUGH */
2865 	case 5:		*--p = fill;	/* FALLTHROUGH */
2866 	case 4:		*--p = fill;	/* FALLTHROUGH */
2867 	case 3:		*--p = fill;	/* FALLTHROUGH */
2868 	case 2:		*--p = fill;	/* FALLTHROUGH */
2869 	case 1:		*--p = fill;	/* FALLTHROUGH */
2870 	case 0:;
2871 	}
2872 }
2873 
2874 /*
2875  * Convert long long int -> string.
2876  */
2877 EXPORT void
llitos(s,ull,fieldw)2878 llitos(s, ull, fieldw)
2879 		char	*s;
2880 	register Ullong	ull;
2881 	register int	fieldw;
2882 {
2883 	register char	*p	= &s[fieldw+1];
2884 	register char	fill	= props.pr_fillc;
2885 
2886 	/*
2887 	 * Currently only used with fieldwidth == 11.
2888 	 * XXX Large 8 byte fields are handled separately.
2889 	 */
2890 	if (/* fieldw == 11 && */ ull > MAXOCTAL11) {
2891 		llbtos(s, ull, fieldw);
2892 		return;
2893 	}
2894 
2895 	/*
2896 	 * Bei 12 Byte Feldern w�rde hier das N�chste Feld �berschrieben, wenn
2897 	 * entgegen der normalen Reihenfolge geschrieben wird!
2898 	 * Da der TCB sowieso vorher genullt wird ist es aber kein Problem
2899 	 * das bei 8 Bytes Feldern notwendige Nullbyte wegzulassen.
2900 	 */
2901 #ifdef	__needed__
2902 	*p = '\0';
2903 #endif
2904 	/*
2905 	 * Das Zeichen nach einer Zahl.
2906 	 * XXX Soll hier besser ein NULL Byte bei POSIX Tar hin?
2907 	 * XXX Wuerde das Probleme mit einer automatischen Erkennung geben?
2908 	 */
2909 	*--p = ' ';
2910 
2911 	do {
2912 		*--p = (ull%8) + '0';	/* Compiler optimiert */
2913 
2914 	} while (--fieldw > 0 && (ull /= 8) > 0);
2915 
2916 	switch (fieldw) {
2917 
2918 	default:
2919 		break;
2920 	case 11:	*--p = fill;	/* FALLTHROUGH */
2921 	case 10:	*--p = fill;	/* FALLTHROUGH */
2922 	case 9:		*--p = fill;	/* FALLTHROUGH */
2923 	case 8:		*--p = fill;	/* FALLTHROUGH */
2924 	case 7:		*--p = fill;	/* FALLTHROUGH */
2925 	case 6:		*--p = fill;	/* FALLTHROUGH */
2926 	case 5:		*--p = fill;	/* FALLTHROUGH */
2927 	case 4:		*--p = fill;	/* FALLTHROUGH */
2928 	case 3:		*--p = fill;	/* FALLTHROUGH */
2929 	case 2:		*--p = fill;	/* FALLTHROUGH */
2930 	case 1:		*--p = fill;	/* FALLTHROUGH */
2931 	case 0:;
2932 	}
2933 }
2934 
2935 /*
2936  * Convert binary (base 256) string -> long int.
2937  */
2938 LOCAL void
stob(s,l,fieldw)2939 stob(s, l, fieldw)
2940 	register char	*s;
2941 		Ulong	*l;
2942 	register int	fieldw;
2943 {
2944 	register Ulong	ret = 0L;
2945 	register Uchar	c;
2946 
2947 	c = *s++ & 0x7F;
2948 	ret = c * 256;
2949 
2950 	while (--fieldw >= 0) {
2951 		c = *s++;
2952 		ret *= 256;
2953 		ret += c;
2954 	}
2955 	*l = ret;
2956 }
2957 
2958 /*
2959  * Convert binary (base 256) string -> long long int.
2960  */
2961 LOCAL void
stollb(s,ull,fieldw)2962 stollb(s, ull, fieldw)
2963 	register char	*s;
2964 		Ullong	*ull;
2965 	register int	fieldw;
2966 {
2967 	register Ullong	ret = 0L;
2968 	register Uchar	c;
2969 
2970 	c = *s++ & 0x7F;
2971 	ret = c * 256;
2972 
2973 	while (--fieldw >= 0) {
2974 		c = *s++;
2975 		ret *= 256;
2976 		ret += c;
2977 	}
2978 	*ull = ret;
2979 }
2980 
2981 /*
2982  * Convert long int -> binary (base 256) string.
2983  */
2984 LOCAL void
btos(s,l,fieldw)2985 btos(s, l, fieldw)
2986 		char	*s;
2987 	register Ulong	l;
2988 	register int	fieldw;
2989 {
2990 	register char	*p	= &s[fieldw+1];
2991 
2992 	do {
2993 		*--p = l%256;	/* Compiler optimiert */
2994 
2995 	} while (--fieldw > 0 && (l /= 256) > 0);
2996 
2997 	s[0] |= 0x80;
2998 }
2999 
3000 /*
3001  * Convert long long int -> binary (base 256) string.
3002  */
3003 LOCAL void
llbtos(s,ull,fieldw)3004 llbtos(s, ull, fieldw)
3005 		char	*s;
3006 	register Ullong	ull;
3007 	register int	fieldw;
3008 {
3009 	register char	*p	= &s[fieldw+1];
3010 
3011 	do {
3012 		*--p = ull%256;	/* Compiler optimiert */
3013 
3014 	} while (--fieldw > 0 && (ull /= 256) > 0);
3015 
3016 	s[0] |= 0x80;
3017 }
3018 
3019 LOCAL BOOL
nameascii(name)3020 nameascii(name)
3021 	register char	*name;
3022 {
3023 	register unsigned char	c;
3024 	while ((c = (unsigned char)*name++) != '\0') {
3025 		if (c > 127)
3026 			return (FALSE);
3027 	}
3028 	return (TRUE);
3029 }
3030 
3031 LOCAL void
print_hrange(type,ull)3032 print_hrange(type, ull)
3033 	char	*type;
3034 	Ullong	ull;
3035 {
3036 	if (nowarn)
3037 		return;
3038 	errmsgno(EX_BAD,
3039 		"WARNING: %s '%llu' in header exceeds local range at %lld.\n",
3040 		type, ull, tblocks());
3041 }
3042 
3043 /* ------------------------------------------------------------------------- */
3044 EXPORT void
dump_info(info)3045 dump_info(info)
3046 	FINFO	*info;
3047 {
3048 	error("f_name:      '%s'\n", info->f_name);
3049 	error("f_namelen:   %lu\n", info->f_namelen);
3050 	error("f_lname:     '%s'\n", info->f_lname);
3051 	error("f_lnamelen:  %lu\n", info->f_lnamelen);
3052 	error("f_uname:     '%s'\n", info->f_uname);
3053 	error("f_umaxlen:   %lu\n", info->f_umaxlen);
3054 	error("f_gname:     '%s'\n", info->f_gname);
3055 	error("f_gmaxlen:   %lu\n", info->f_gmaxlen);
3056 
3057 	error("f_dir:       %p\n", info->f_dir);
3058 	error("f_dirinos:   %p\n", info->f_dirinos);
3059 	error("f_dirlen:    %lld\n", (Llong)info->f_dirlen);
3060 	error("f_dirents:   %lld\n", (Llong)info->f_dirents);
3061 	error("f_dev:       0x%llX\n", (Ullong)info->f_dev);
3062 	error("f_ino:       %llu\n", (Ullong)info->f_ino);
3063 	error("f_nlink:     %llu\n", (Ullong)info->f_nlink);
3064 	error("f_mode:      0%llo\n", (Ullong)info->f_mode);
3065 	error("f_uid:       %lld\n", (Llong)info->f_uid);
3066 	error("f_gid:       %lld\n", (Llong)info->f_gid);
3067 
3068 	error("f_size:      %lld\n", (Llong)info->f_size);
3069 	error("f_rsize:     %lld\n", (Llong)info->f_rsize);
3070 	error("f_contoffset:%lld\n", (Llong)info->f_contoffset);
3071 	error("f_flags:     0x%lX\n", info->f_flags);
3072 	error("f_xflags:    0x%lX\n", info->f_xflags);
3073 	error("f_xftype:    %lu (%s)\n", info->f_xftype, XTTONAME(info->f_xftype));
3074 	error("f_rxftype:   %lu (%s)\n", info->f_rxftype, XTTONAME(info->f_rxftype));
3075 	error("f_filetype:  %lu\n", info->f_filetype);
3076 	error("f_typeflag:  '%c'\n", info->f_typeflag);
3077 	error("f_type:      0%llo\n", (Ullong)info->f_type);
3078 	error("f_rdev:      %lu\n", info->f_rdev);
3079 	error("f_rdevmaj:   %lu\n", info->f_rdevmaj);
3080 	error("f_rdevmin:   %lu\n", info->f_rdevmin);
3081 	error("f_atime:     %.24s +0.%9.9ld s\n", ctime(&info->f_atime), info->f_ansec);
3082 	error("f_mtime:     %.24s +0.%9.9ld s\n", ctime(&info->f_mtime), info->f_mnsec);
3083 	error("f_ctime:     %.24s +0.%9.9ld s\n", ctime(&info->f_ctime), info->f_cnsec);
3084 	error("f_fflags:    0x%lX\n", info->f_fflags);
3085 }
3086