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