1 /* $OpenBSD: tar.c,v 1.34 2004/10/23 19:34:14 otto Exp $ */
2 /* $NetBSD: tar.c,v 1.5 1995/03/21 09:07:49 cgd Exp $ */
5 * Copyright (c) 1992 Keith Muller.
6 * Copyright (c) 1992, 1993
7 * The Regents of the University of California. All rights reserved.
9 * This code is derived from software contributed to Berkeley by
10 * Keith Muller of the University of California, San Diego.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 static const char sccsid
[] = "@(#)tar.c 8.2 (Berkeley) 4/18/94";
41 static const char rcsid
[] __attribute__((__unused__
)) = "$OpenBSD: tar.c,v 1.34 2004/10/23 19:34:14 otto Exp $";
45 #include <sys/types.h>
48 #include <sys/param.h>
62 * This file implements the -x pax format support; it is incomplete.
63 * Known missing features include:
64 * many -o options for "copy" mode are not implemented (only path=)
65 * many format specifiers for -o listopt are not implemented
66 * -o listopt option should work for all archive formats, not just -x pax
67 * This file was originally derived from the file tar.c. You should
68 * 'diff' it to that file to see how much of the -x pax format has been implemented.
71 char pax_eh_datablk
[4*1024];
72 int pax_read_or_list_mode
= 0;
73 int want_a_m_time_headers
= 0;
74 int want_linkdata
= 0;
76 int pax_invalid_action
= 0;
77 char * pax_invalid_action_write_path
= NULL
;
78 char * pax_invalid_action_write_cwd
= NULL
;
81 *path_g
, *path_x
, *path_g_current
, *path_x_current
,
82 *uname_g
, *uname_x
, *uname_g_current
, *uname_x_current
,
83 *gname_g
, *gname_x
, *gname_g_current
, *gname_x_current
,
84 *comment_g
, *comment_x
, *comment_g_current
, *comment_x_current
,
85 *charset_g
, *charset_x
, *charset_g_current
, *charset_x_current
,
86 *atime_g
, *atime_x
, *atime_g_current
, *atime_x_current
,
87 *gid_g
, *gid_x
, *gid_g_current
, *gid_x_current
,
88 *linkpath_g
, *linkpath_x
, *linkpath_g_current
, *linkpath_x_current
,
89 *mtime_g
, *mtime_x
, *mtime_g_current
, *mtime_x_current
,
90 *size_g
, *size_x
, *size_g_current
, *size_x_current
,
91 *uid_g
, *uid_x
, *uid_g_current
, *uid_x_current
;
93 char *header_name_g_requested
= NULL
,
94 *header_name_x_requested
= NULL
;
96 char *header_name_g
= "/tmp/GlobalHead.%p.%n",
97 *header_name_x
= "%d/PaxHeaders.%p/%f";
99 int nglobal_headers
= 0;
100 char *pax_list_opt_format
;
102 #define O_OPTION_ACTION_NOTIMPL 0
103 #define O_OPTION_ACTION_INVALID 1
104 #define O_OPTION_ACTION_DELETE 2
105 #define O_OPTION_ACTION_STORE_HEADER 3
106 #define O_OPTION_ACTION_TIMES 4
107 #define O_OPTION_ACTION_HEADER_NAME 5
108 #define O_OPTION_ACTION_LISTOPT 6
109 #define O_OPTION_ACTION_LINKDATA 7
111 #define O_OPTION_ACTION_IGNORE 8
112 #define O_OPTION_ACTION_ERROR 9
113 #define O_OPTION_ACTION_STORE_HEADER2 10
115 #define ATTRSRC_FROM_NOWHERE 0
116 #define ATTRSRC_FROM_X_O_OPTION 1
117 #define ATTRSRC_FROM_G_O_OPTION 2
118 #define ATTRSRC_FROM_X_HEADER 3
119 #define ATTRSRC_FROM_G_HEADER 4
121 #define KW_PATH_CASE 0
122 #define KW_SKIP_CASE -1
127 int active
; /* 1 means active, 0 means deleted via -o delete= */
130 /* next 2 entries only used by store_header actions */
131 char ** g_value
; /* -o keyword= value */
132 char ** x_value
; /* -o keyword:= value */
133 char ** g_value_current
; /* keyword= value found in Global extended header */
134 char ** x_value_current
; /* keyword= value found in extended header */
135 int header_inx
; /* starting index of header field this keyword represents */
136 int header_len
; /* length of header field this keyword represents */
137 /* If negative, special cases line path= */
140 O_OPTION_TYPE o_option_table
[] = {
141 { "atime", 5, 1, O_OPTION_ACTION_STORE_HEADER
, O_OPTION_ACTION_STORE_HEADER
,
142 &atime_g
, &atime_x
, &atime_g_current
, &atime_x_current
, 0, KW_SKIP_CASE
},
143 { "charset", 7, 1, O_OPTION_ACTION_STORE_HEADER
, O_OPTION_ACTION_IGNORE
,
144 &charset_g
, &charset_x
, &charset_g_current
, &charset_x_current
, 0, KW_SKIP_CASE
},
145 { "comment", 7, 1, O_OPTION_ACTION_STORE_HEADER
, O_OPTION_ACTION_IGNORE
,
146 &comment_g
, &comment_x
, &comment_g_current
, &comment_x_current
, 0, KW_SKIP_CASE
},
147 { "gid", 3, 1, O_OPTION_ACTION_STORE_HEADER2
, O_OPTION_ACTION_STORE_HEADER2
,
148 &gid_g
, &gid_x
, &gid_g_current
, &gid_x_current
, 116, 8 },
149 { "gname", 5, 1, O_OPTION_ACTION_STORE_HEADER2
, O_OPTION_ACTION_STORE_HEADER2
,
150 &gname_g
, &gname_x
, &gname_g_current
, &gname_x_current
, 297, 32 },
151 { "linkpath", 8, 1, O_OPTION_ACTION_STORE_HEADER
, O_OPTION_ACTION_STORE_HEADER
,
152 &linkpath_g
, &linkpath_x
, &linkpath_g_current
, &linkpath_x_current
, 0, KW_SKIP_CASE
},
153 { "mtime", 5, 1, O_OPTION_ACTION_STORE_HEADER
, O_OPTION_ACTION_STORE_HEADER
,
154 &mtime_g
, &mtime_x
, &mtime_g_current
, &mtime_x_current
, 136, KW_SKIP_CASE
},
155 { "path", 4, 1, O_OPTION_ACTION_STORE_HEADER
, O_OPTION_ACTION_STORE_HEADER
,
156 &path_g
, &path_x
, &path_g_current
, &path_x_current
, 0, KW_PATH_CASE
},
157 { "size", 4, 1, O_OPTION_ACTION_STORE_HEADER
, O_OPTION_ACTION_STORE_HEADER
,
158 &size_g
, &size_x
, &size_g_current
, &size_x_current
, 124, KW_SKIP_CASE
},
159 { "uid", 3, 1, O_OPTION_ACTION_STORE_HEADER2
, O_OPTION_ACTION_STORE_HEADER2
,
160 &uid_g
, &uid_x
, &uid_g_current
, &uid_x_current
, 108, 8 },
161 { "uname", 5, 1, O_OPTION_ACTION_STORE_HEADER2
, O_OPTION_ACTION_STORE_HEADER2
,
162 &uname_g
, &uname_x
, &uname_g_current
, &uname_x_current
, 265, 32 },
164 { "exthdr.name", 11, 1, O_OPTION_ACTION_HEADER_NAME
, O_OPTION_ACTION_ERROR
,
165 &header_name_x
, &header_name_x_requested
, NULL
, NULL
, 0, KW_SKIP_CASE
},
166 { "globexthdr.name", 15, 1, O_OPTION_ACTION_HEADER_NAME
, O_OPTION_ACTION_ERROR
,
167 &header_name_g
, &header_name_g_requested
, NULL
, NULL
, 0, KW_SKIP_CASE
},
169 { "delete", 6, 1, O_OPTION_ACTION_DELETE
, O_OPTION_ACTION_ERROR
,
170 NULL
, NULL
, NULL
, NULL
, 0, KW_SKIP_CASE
},
171 { "invalid", 7, 1, O_OPTION_ACTION_INVALID
, O_OPTION_ACTION_ERROR
,
172 NULL
, NULL
, NULL
, NULL
, 0, KW_SKIP_CASE
},
173 { "linkdata", 8, 1, O_OPTION_ACTION_LINKDATA
, O_OPTION_ACTION_ERROR
,
174 NULL
, NULL
, NULL
, NULL
, 0, KW_SKIP_CASE
}, /* Test 241 */
175 { "listopt", 7, 1, O_OPTION_ACTION_LISTOPT
, O_OPTION_ACTION_ERROR
,
176 &pax_list_opt_format
, NULL
, NULL
, NULL
, 0, KW_SKIP_CASE
}, /* Test 242 */
177 /* Note: listopt is supposed to apply for all formats, not just -x pax only */
178 { "times", 5, 1, O_OPTION_ACTION_TIMES
, O_OPTION_ACTION_ERROR
,
179 NULL
, NULL
, NULL
, NULL
, 0, KW_SKIP_CASE
},
183 global_ext_header_inx
;
185 /* Make these tables big enough to handle lots of -o options, not just one per table entry */
186 int ext_header_entry
[4*sizeof(o_option_table
)/sizeof(O_OPTION_TYPE
)],
187 global_ext_header_entry
[4*sizeof(o_option_table
)/sizeof(O_OPTION_TYPE
)];
190 * Routines for reading, writing and header identify of various versions of pax
193 static size_t expandname(char *, size_t, char **, const char *, size_t);
194 static u_long
pax_chksm(char *, int);
195 char *name_split(char *, int);
196 static int ul_oct(u_long
, char *, int, int);
198 static int uqd_oct(u_quad_t
, char *, int, int);
201 static uid_t uid_nobody
;
202 static uid_t uid_warn
;
203 static gid_t gid_nobody
;
204 static gid_t gid_warn
;
207 * Routines common to all versions of pax
211 static int tar_nodir
; /* do not write dirs under old tar */
212 char *gnu_name_string
; /* GNU ././@LongLink hackery name */
213 char *gnu_link_string
; /* GNU ././@LongLink hackery link */
217 * add the tar trailer of two null blocks
219 * 0 if ok, -1 otherwise (what wr_skip returns)
225 return(wr_skip((off_t
)(NULLCNT
*BLKMULT
)));
230 * no cleanup needed here, just return size of trailer (for append)
232 * size of trailer (2 * BLKMULT)
238 return((off_t
)(NULLCNT
*BLKMULT
));
243 * Called to determine if a header block is a valid trailer. We are passed
244 * the block, the in_sync flag (which tells us we are in resync mode;
245 * looking for a valid header), and cnt (which starts at zero) which is
246 * used to count the number of empty blocks we have seen so far.
248 * 0 if a valid trailer, -1 if not a valid trailer, or 1 if the block
249 * could never contain a header.
253 tar_trail(ARCHD
*ignore
, char *buf
, int in_resync
, int *cnt
)
258 * look for all zero, trailer is two consecutive blocks of zero
260 for (i
= 0; i
< BLKMULT
; ++i
) {
266 * if not all zero it is not a trailer, but MIGHT be a header.
272 * When given a zero block, we must be careful!
273 * If we are not in resync mode, check for the trailer. Have to watch
274 * out that we do not mis-identify file data as the trailer, so we do
275 * NOT try to id a trailer during resync mode. During resync mode we
276 * might as well throw this block out since a valid header can NEVER be
277 * a block of all 0 (we must have a valid file name).
279 if (!in_resync
&& (++*cnt
>= NULLCNT
))
287 * convert an unsigned long to an octal string. many oddball field
288 * termination characters are used by the various versions of tar in the
289 * different fields. term selects which kind to use. str is '0' padded
290 * at the front to len. we are unable to use only one format as many old
291 * tar readers are very cranky about this.
293 * 0 if the number fit into the string, -1 otherwise
297 ul_oct(u_long val
, char *str
, int len
, int term
)
302 * term selects the appropriate character(s) for the end of the string
324 * convert and blank pad if there is space
327 *pt
-- = '0' + (char)(val
& 0x7);
328 if ((val
= val
>> 3) == (u_long
)0)
334 if (val
!= (u_long
)0)
342 * convert an u_quad_t to an octal string. one of many oddball field
343 * termination characters are used by the various versions of tar in the
344 * different fields. term selects which kind to use. str is '0' padded
345 * at the front to len. we are unable to use only one format as many old
346 * tar readers are very cranky about this.
348 * 0 if the number fit into the string, -1 otherwise
352 uqd_oct(u_quad_t val
, char *str
, int len
, int term
)
357 * term selects the appropriate character(s) for the end of the string
379 * convert and blank pad if there is space
382 *pt
-- = '0' + (char)(val
& 0x7);
383 if ((val
= val
>> 3) == 0)
389 if (val
!= (u_quad_t
)0)
397 * calculate the checksum for a pax block counting the checksum field as
398 * all blanks (BLNKSUM is that value pre-calculated, the sum of 8 blanks).
399 * NOTE: we use len to short circuit summing 0's on write since we ALWAYS
400 * pad headers with 0.
402 * unsigned long checksum
406 pax_chksm(char *blk
, int len
)
410 u_long chksm
= BLNKSUM
; /* initial value is checksum field sum */
413 * add the part of the block before the checksum field
416 stop
= blk
+ CHK_OFFSET
;
418 chksm
+= (u_long
)(*pt
++ & 0xff);
420 * move past the checksum field and keep going, spec counts the
421 * checksum field as the sum of 8 blanks (which is pre-computed as
423 * ASSUMED: len is greater than CHK_OFFSET. (len is where our 0 padding
424 * starts, no point in summing zero's)
429 chksm
+= (u_long
)(*pt
++ & 0xff);
435 * Routines for old BSD style tar (also made portable to sysV tar)
438 /* pax_id must be derived from ustar, NOT tar */
441 * determine if a block given to us is a valid tar header (and not a USTAR
442 * header). We have to be on the lookout for those pesky blocks of all
445 * 0 if a tar header, -1 otherwise
449 tar_id(char *blk
, int size
)
457 uhd
= (HD_USTAR
*)blk
;
460 * check for block of zero's first, a simple and fast test, then make
461 * sure this is not a ustar header by looking for the ustar magic
462 * cookie. We should use TMAGLEN, but some USTAR archive programs are
463 * wrong and create archives missing the \0. Last we check the
464 * checksum. If this is ok we have to assume it is a valid header.
466 if (hd
->name
[0] == '\0')
468 if (strncmp(uhd
->magic
, TMAGIC
, TMAGLEN
- 1) == 0)
470 if (asc_ul(hd
->chksum
,sizeof(hd
->chksum
),OCT
) != tar_chksm(blk
,BLKMULT
))
472 force_one_volume
= 1;
478 pax_format_list_output(ARCHD
*arcn
, time_t now
, FILE *fp
, int term
)
480 /* parse specified listopt format */
481 char *nextpercent
, *nextchar
;
486 nextpercent
= strchr(pax_list_opt_format
,'%');
487 if (nextpercent
==NULL
) {
488 /* Strange case: no specifiers? */
489 safe_print(pax_list_opt_format
, fp
);
490 (void)putc(term
, fp
);
494 pos
= nextpercent
-pax_list_opt_format
;
495 memcpy(buf
,pax_list_opt_format
, pos
);
496 while (nextpercent
++) {
497 switch (*nextpercent
) {
500 cpylen
= strlen(fname
);
501 memcpy(&buf
[pos
],fname
,cpylen
);
509 paxwarn(1, "Unimplemented listopt format: %c",*nextpercent
);
513 if (*nextpercent
=='\0') {
516 nextchar
= nextpercent
;
517 nextpercent
= strchr(nextpercent
,'%');
518 if (nextpercent
==NULL
) {
519 cpylen
= strlen(nextchar
);
521 cpylen
= nextpercent
- nextchar
;
523 memcpy(&buf
[pos
],nextchar
, cpylen
);
527 safe_print(&buf
[0], fp
);
528 (void)putc(term
, fp
);
534 cleanup_pax_invalid_action()
536 switch (pax_invalid_action
) {
537 case PAX_INVALID_ACTION_BYPASS
:
538 case PAX_INVALID_ACTION_RENAME
:
540 case PAX_INVALID_ACTION_WRITE
:
541 pax_invalid_action_write_path
= NULL
;
542 if (pax_invalid_action_write_cwd
) {
543 free(pax_invalid_action_write_cwd
);
544 pax_invalid_action_write_cwd
= NULL
;
547 case PAX_INVALID_ACTION_UTF8
:
549 paxwarn(1, "pax_invalid_action not implemented:%d", pax_invalid_action
);
554 record_pax_invalid_action_results(ARCHD
* arcn
, char * fixed_path
)
556 switch (pax_invalid_action
) {
557 case PAX_INVALID_ACTION_BYPASS
:
558 case PAX_INVALID_ACTION_RENAME
:
560 case PAX_INVALID_ACTION_WRITE
:
561 pax_invalid_action_write_path
= fixed_path
;
562 pax_invalid_action_write_cwd
= strdup(arcn
->name
);
563 pax_invalid_action_write_cwd
[fixed_path
-arcn
->name
-1] = '\0';
565 case PAX_INVALID_ACTION_UTF8
:
567 paxwarn(1, "pax_invalid_action not implemented:%d", pax_invalid_action
);
572 perform_pax_invalid_action(ARCHD
* arcn
, int err
)
575 switch (pax_invalid_action
) {
576 case PAX_INVALID_ACTION_BYPASS
:
579 case PAX_INVALID_ACTION_RENAME
:
580 rc
= tty_rename(arcn
);
582 case PAX_INVALID_ACTION_WRITE
:
583 pax_invalid_action_write_path
= NULL
;
584 pax_invalid_action_write_cwd
= NULL
;
587 case PAX_INVALID_ACTION_UTF8
:
589 paxwarn(1, "pax_invalid_action not implemented:%d", pax_invalid_action
);
590 rc
= -1; /* do nothing? */
596 delete_keywords(char * pattern
)
599 /* loop over all keywords, marking any matched as deleted */
600 for (i
= 0; i
< sizeof(o_option_table
)/sizeof(O_OPTION_TYPE
); i
++) {
601 if (fnmatch(pattern
, o_option_table
[i
].name
, 0) == 0) {
602 /* Found option: mark deleted */
603 o_option_table
[i
].active
= 0;
610 * handle pax format specific -o options
612 * 0 if ok -1 otherwise
621 while ((opt
= opt_next()) != NULL
) {
624 pax_invalid_action
= PAX_INVALID_ACTION_BYPASS
; /* Default for pax format */
625 /* look up opt->name */
626 for (i
= 0; i
< sizeof(o_option_table
)/sizeof(O_OPTION_TYPE
); i
++) {
627 if (strncasecmp(opt
->name
, o_option_table
[i
].name
, o_option_table
[i
].len
) == 0) {
628 /* Found option: see if already set */
631 switch (o_option_table
[i
].cmdline_action
) {
632 case O_OPTION_ACTION_INVALID
:
633 if (opt
->separator
!= SEP_EQ
) {
634 paxwarn(1,"-o %s= option requires '=' separator: option ignored",
639 if (strncasecmp(opt
->value
,"bypass",6) == 0) {
640 pax_invalid_action
= PAX_INVALID_ACTION_BYPASS
;
641 } else if (strncasecmp(opt
->value
,"rename",6) == 0) {
642 pax_invalid_action
= PAX_INVALID_ACTION_RENAME
;
643 } else if (strncasecmp(opt
->value
,"UTF-8",5) == 0) {
644 pax_invalid_action
= PAX_INVALID_ACTION_UTF8
;
645 } else if (strncasecmp(opt
->value
,"write",5) == 0) {
646 pax_invalid_action
= PAX_INVALID_ACTION_WRITE
;
648 paxwarn(1,"Invalid action %s not recognized: option ignored",
652 paxwarn(1,"Invalid action RHS not specified: option ignored");
655 case O_OPTION_ACTION_DELETE
:
656 if (opt
->separator
!= SEP_EQ
) {
657 paxwarn(1,"-o %s= option requires '=' separator: option ignored",
661 /* Mark all matches as deleted */
662 /* can have multiple -o delete= patterns */
663 delete_keywords(opt
->value
);
665 case O_OPTION_ACTION_STORE_HEADER2
:
666 if(pax_read_or_list_mode
) pids
= 1; /* Force -p o for these options */
667 case O_OPTION_ACTION_STORE_HEADER
:
668 if (o_option_table
[i
].g_value
== NULL
||
669 o_option_table
[i
].x_value
== NULL
) {
670 paxwarn(1,"-o option not implemented: %s=%s",
671 opt
->name
, opt
->value
);
673 if (opt
->separator
== SEP_EQ
) {
674 *(o_option_table
[i
].g_value
) = opt
->value
;
675 global_ext_header_entry
[global_ext_header_inx
++] = i
;
676 } else if (opt
->separator
== SEP_COLONEQ
) {
677 *(o_option_table
[i
].x_value
) = opt
->value
;
678 ext_header_entry
[ext_header_inx
++] = i
;
679 } else { /* SEP_NONE */
680 paxwarn(1,"-o %s option is missing value", opt
->name
);
684 case O_OPTION_ACTION_TIMES
:
685 if (opt
->separator
!= SEP_NONE
) {
686 paxwarn(1,"-o %s option takes no value: option ignored", opt
->name
);
689 want_a_m_time_headers
= 1;
691 case O_OPTION_ACTION_LINKDATA
:
692 if (opt
->separator
!= SEP_NONE
) {
693 paxwarn(1,"-o %s option takes no value: option ignored", opt
->name
);
698 case O_OPTION_ACTION_HEADER_NAME
:
699 if (opt
->separator
!= SEP_EQ
) {
700 paxwarn(1,"-o %s= option requires '=' separator: option ignored",
704 *(o_option_table
[i
].g_value
) = opt
->value
;
705 *(o_option_table
[i
].x_value
) = "YES";
707 case O_OPTION_ACTION_LISTOPT
:
708 if (opt
->separator
!= SEP_EQ
) {
709 paxwarn(1,"-o %s= option requires '=' separator: option ignored",
713 *(o_option_table
[i
].g_value
) = opt
->value
;
715 case O_OPTION_ACTION_NOTIMPL
:
717 paxwarn(1,"pax format -o option not yet implemented: %s=%s",
718 opt
->name
, opt
->value
);
724 if (got_option
== -1) {
725 paxwarn(1,"pax format -o option not recognized: %s=%s",
726 opt
->name
, opt
->value
);
734 /* pax_rd is derived from ustar_rd NOT tar_rd */
737 * extract the values out of block already determined to be a tar header.
738 * store the values in the ARCHD parameter.
744 tar_rd(ARCHD
*arcn
, char *buf
)
750 * we only get proper sized buffers passed to us
752 if (tar_id(buf
, BLKMULT
) < 0)
754 memset(arcn
, 0, sizeof(*arcn
));
755 arcn
->org_name
= arcn
->name
;
756 arcn
->sb
.st_nlink
= 1;
759 * copy out the name and values in the stat buffer
762 if (hd
->linkflag
!= LONGLINKTYPE
&& hd
->linkflag
!= LONGNAMETYPE
) {
763 arcn
->nlen
= expandname(arcn
->name
, sizeof(arcn
->name
),
764 &gnu_name_string
, hd
->name
, sizeof(hd
->name
));
765 arcn
->ln_nlen
= expandname(arcn
->ln_name
, sizeof(arcn
->ln_name
),
766 &gnu_link_string
, hd
->linkname
, sizeof(hd
->linkname
));
768 arcn
->sb
.st_mode
= (mode_t
)(asc_ul(hd
->mode
,sizeof(hd
->mode
),OCT
) &
770 arcn
->sb
.st_uid
= (uid_t
)asc_ul(hd
->uid
, sizeof(hd
->uid
), OCT
);
771 arcn
->sb
.st_gid
= (gid_t
)asc_ul(hd
->gid
, sizeof(hd
->gid
), OCT
);
773 arcn
->sb
.st_size
= (off_t
)asc_ul(hd
->size
, sizeof(hd
->size
), OCT
);
775 arcn
->sb
.st_size
= (off_t
)asc_uqd(hd
->size
, sizeof(hd
->size
), OCT
);
777 arcn
->sb
.st_mtime
= (time_t)asc_ul(hd
->mtime
, sizeof(hd
->mtime
), OCT
);
778 arcn
->sb
.st_ctime
= arcn
->sb
.st_atime
= arcn
->sb
.st_mtime
;
781 * have to look at the last character, it may be a '/' and that is used
782 * to encode this as a directory
784 pt
= &(arcn
->name
[arcn
->nlen
- 1]);
787 switch (hd
->linkflag
) {
790 * symbolic link, need to get the link name and set the type in
791 * the st_mode so -v printing will look correct.
793 arcn
->type
= PAX_SLK
;
794 arcn
->sb
.st_mode
|= S_IFLNK
;
798 * hard link, need to get the link name, set the type in the
799 * st_mode and st_nlink so -v printing will look better.
801 arcn
->type
= PAX_HLK
;
802 arcn
->sb
.st_nlink
= 2;
805 * no idea of what type this thing really points at, but
806 * we set something for printing only.
808 arcn
->sb
.st_mode
|= S_IFREG
;
813 * GNU long link/file; we tag these here and let the
814 * pax internals deal with it -- too ugly otherwise.
817 hd
->linkflag
== LONGLINKTYPE
? PAX_GLL
: PAX_GLF
;
818 arcn
->pad
= TAR_PAD(arcn
->sb
.st_size
);
819 arcn
->skip
= arcn
->sb
.st_size
;
823 * It is a directory, set the mode for -v printing
825 arcn
->type
= PAX_DIR
;
826 arcn
->sb
.st_mode
|= S_IFDIR
;
827 arcn
->sb
.st_nlink
= 2;
833 * If we have a trailing / this is a directory and NOT a file.
835 arcn
->ln_name
[0] = '\0';
839 * it is a directory, set the mode for -v printing
841 arcn
->type
= PAX_DIR
;
842 arcn
->sb
.st_mode
|= S_IFDIR
;
843 arcn
->sb
.st_nlink
= 2;
846 * have a file that will be followed by data. Set the
847 * skip value to the size field and calculate the size
850 arcn
->type
= PAX_REG
;
851 arcn
->sb
.st_mode
|= S_IFREG
;
852 arcn
->pad
= TAR_PAD(arcn
->sb
.st_size
);
853 arcn
->skip
= arcn
->sb
.st_size
;
859 * strip off any trailing slash.
868 /* pax_wr is derived from ustar_wr NOT tar_wr */
871 * write a tar header for the file specified in the ARCHD to the archive.
872 * Have to check for file types that cannot be stored and file names that
873 * are too long. Be careful of the term (last arg) to ul_oct, each field
874 * of tar has it own spec for the termination character(s).
875 * ASSUMED: space after header in header block is zero filled
877 * 0 if file has data to be written after the header, 1 if file has NO
878 * data to write after the header, -1 if archive write failed
886 char hdblk
[sizeof(HD_TAR
)];
889 * check for those file system types which tar cannot store
891 switch (arcn
->type
) {
894 * user asked that dirs not be written to the archive
900 paxwarn(1, "Tar cannot archive a character device %s",
904 paxwarn(1, "Tar cannot archive a block device %s", arcn
->org_name
);
907 paxwarn(1, "Tar cannot archive a socket %s", arcn
->org_name
);
910 paxwarn(1, "Tar cannot archive a fifo %s", arcn
->org_name
);
915 if (arcn
->ln_nlen
> sizeof(hd
->linkname
)) {
916 paxwarn(1,"Link name too long for tar %s", arcn
->ln_name
);
927 * check file name len, remember extra char for dirs (the / at the end)
930 if (arcn
->type
== PAX_DIR
)
932 if (len
>= sizeof(hd
->name
)) {
933 paxwarn(1, "File name too long for tar %s", arcn
->name
);
938 * Copy the data out of the ARCHD into the tar header based on the type
939 * of the file. Remember, many tar readers want all fields to be
940 * padded with zero so we zero the header first. We then set the
941 * linkflag field (type), the linkname, the size, and set the padding
942 * (if any) to be added after the file data (0 for all other types,
943 * as they only have a header).
945 memset(hdblk
, 0, sizeof(hdblk
));
946 hd
= (HD_TAR
*)hdblk
;
947 strlcpy(hd
->name
, arcn
->name
, sizeof(hd
->name
));
950 if (arcn
->type
== PAX_DIR
) {
952 * directories are the same as files, except have a filename
953 * that ends with a /, we add the slash here. No data follows
956 hd
->linkflag
= AREGTYPE
;
957 hd
->name
[len
-1] = '/';
958 if (ul_oct((u_long
)0L, hd
->size
, sizeof(hd
->size
), 1))
960 } else if (arcn
->type
== PAX_SLK
) {
962 * no data follows this file, so no pad
964 hd
->linkflag
= SYMTYPE
;
965 strlcpy(hd
->linkname
, arcn
->ln_name
, sizeof(hd
->linkname
));
966 if (ul_oct((u_long
)0L, hd
->size
, sizeof(hd
->size
), 1))
968 } else if ((arcn
->type
== PAX_HLK
) || (arcn
->type
== PAX_HRG
)) {
970 * no data follows this file, so no pad
972 hd
->linkflag
= LNKTYPE
;
973 strlcpy(hd
->linkname
, arcn
->ln_name
, sizeof(hd
->linkname
));
974 if (ul_oct((u_long
)0L, hd
->size
, sizeof(hd
->size
), 1))
978 * data follows this file, so set the pad
980 hd
->linkflag
= AREGTYPE
;
982 if (ul_oct((u_long
)arcn
->sb
.st_size
, hd
->size
,
983 sizeof(hd
->size
), 1)) {
985 if (uqd_oct((u_quad_t
)arcn
->sb
.st_size
, hd
->size
,
986 sizeof(hd
->size
), 1)) {
988 paxwarn(1,"File is too large for tar %s", arcn
->org_name
);
991 arcn
->pad
= TAR_PAD(arcn
->sb
.st_size
);
995 * copy those fields that are independent of the type
997 if (ul_oct((u_long
)arcn
->sb
.st_mode
, hd
->mode
, sizeof(hd
->mode
), 0) ||
998 ul_oct((u_long
)arcn
->sb
.st_uid
, hd
->uid
, sizeof(hd
->uid
), 0) ||
999 ul_oct((u_long
)arcn
->sb
.st_gid
, hd
->gid
, sizeof(hd
->gid
), 0) ||
1000 ul_oct((u_long
)arcn
->sb
.st_mtime
, hd
->mtime
, sizeof(hd
->mtime
), 1))
1004 * calculate and add the checksum, then write the header. A return of
1005 * 0 tells the caller to now write the file data, 1 says no data needs
1008 if (ul_oct(tar_chksm(hdblk
, sizeof(HD_TAR
)), hd
->chksum
,
1009 sizeof(hd
->chksum
), 3))
1011 if (wr_rdbuf(hdblk
, sizeof(HD_TAR
)) < 0)
1013 if (wr_skip((off_t
)(BLKMULT
- sizeof(HD_TAR
))) < 0)
1015 if ((arcn
->type
== PAX_CTG
) || (arcn
->type
== PAX_REG
))
1021 * header field is out of range
1023 paxwarn(1, "Tar header field is too small for %s", arcn
->org_name
);
1030 * Routines for POSIX ustar
1035 * initialization for ustar read
1037 * 0 if ok, -1 otherwise
1043 if ((usrtb_start() < 0) || (grptb_start() < 0))
1050 * initialization for ustar write
1052 * 0 if ok, -1 otherwise
1058 if ((uidtb_start() < 0) || (gidtb_start() < 0))
1065 expand_extended_headers(ARCHD
*arcn
, HD_USTAR
*hd
)
1067 char mybuf
[BLKMULT
];
1069 char * current_value
;
1070 int path_replaced
= 0;
1074 while (myhd
->typeflag
== PAXGTYPE
|| myhd
->typeflag
== PAXXTYPE
) {
1076 int size
, nbytes
, inx
;
1077 size
= asc_ul(myhd
->size
, sizeof(myhd
->size
), OCT
);
1078 if (size
> sizeof(mybuf
)) {
1079 paxwarn(1,"extended header buffer overflow");
1082 nbytes
= rd_wrbuf(mybuf
, size
);
1083 if (nbytes
!= size
) {
1084 paxwarn(1,"extended header data read failure: nbytes=%d, size=%d\n",
1089 printf("Read 1 extended header: type=%c, size=%d\n",
1090 myhd->typeflag, size);
1093 /* loop over buffer collecting attributes */
1094 while (nbytes
> 0) {
1095 int got_option
= -1;
1096 int nentries
= sscanf(&mybuf
[inx
],"%d ", &len
);
1097 if (nentries
!= 1) {
1098 paxwarn(1,"Extended header failure: length");
1101 if (len
< 0 || (inx
+len
-1 >= sizeof(mybuf
))) {
1102 paxwarn(1, "Extended header failure: invalid length (%d)", len
);
1105 if (mybuf
[inx
+len
-1] != '\n') {
1106 paxwarn(1,"Extended header failure: missed newline");
1109 mybuf
[inx
+len
-1] = '\0';
1110 name
= strchr(&mybuf
[inx
],' ');
1113 paxwarn(1,"Extended header failure: missing space");
1116 str
= strchr(name
,'=');
1118 *str
++='\0'; /* end of name */
1120 paxwarn(1,"Extended header failure: missing RHS string");
1123 for (i
= 0; i
< sizeof(o_option_table
)/sizeof(O_OPTION_TYPE
); i
++) {
1124 if (strncasecmp(name
, o_option_table
[i
].name
, o_option_table
[i
].len
) == 0) {
1125 /* Found option: see if already set TBD */
1131 if (got_option
== -1) {
1132 paxwarn(1,"Unrecognized header keyword: %s",name
);
1134 /* Determine precedence of -o and header attributes */
1135 int found_value
= ATTRSRC_FROM_NOWHERE
;
1136 current_value
= NULL
;
1137 if (myhd
->typeflag
== PAXXTYPE
) {
1138 if (*o_option_table
[got_option
].x_value
) {
1139 current_value
= *o_option_table
[got_option
].x_value
;
1140 found_value
= ATTRSRC_FROM_X_O_OPTION
;
1142 current_value
= str
;
1143 found_value
= ATTRSRC_FROM_X_HEADER
;
1145 } else if (myhd
->typeflag
== PAXGTYPE
) {
1146 if (*o_option_table
[got_option
].g_value
) {
1147 current_value
= *o_option_table
[got_option
].g_value
;
1148 found_value
= ATTRSRC_FROM_G_O_OPTION
;
1150 current_value
= str
;
1151 found_value
= ATTRSRC_FROM_G_HEADER
;
1154 paxwarn(1,"Unsupported header type:%c",myhd
->typeflag
);
1156 if (current_value
) {
1157 /* Save this attribute value for use later */
1158 switch (o_option_table
[got_option
].header_action
) {
1159 case O_OPTION_ACTION_IGNORE
:
1160 paxwarn(1,"ignoring header keyword: %s",name
);
1162 case O_OPTION_ACTION_STORE_HEADER2
:
1163 case O_OPTION_ACTION_STORE_HEADER
:
1164 switch (found_value
) {
1165 case ATTRSRC_FROM_NOWHERE
: /* shouldn't happen */
1166 paxwarn(1, "internal error: value from nowhere");
1168 case ATTRSRC_FROM_X_O_OPTION
:
1169 case ATTRSRC_FROM_G_O_OPTION
:
1171 case ATTRSRC_FROM_X_HEADER
:
1172 current_value
= strdup(current_value
);
1173 if(*o_option_table
[got_option
].x_value_current
)
1174 free(*o_option_table
[got_option
].x_value_current
);
1175 *o_option_table
[got_option
].x_value_current
= current_value
;
1177 case ATTRSRC_FROM_G_HEADER
:
1178 current_value
= strdup(current_value
);
1179 if(*o_option_table
[got_option
].g_value_current
)
1180 free(*o_option_table
[got_option
].g_value_current
);
1181 *o_option_table
[got_option
].g_value_current
= current_value
;
1185 case O_OPTION_ACTION_ERROR
:
1187 paxwarn(1,"Unsupported extended header attribute: %s=%s",
1196 /* position file at next header */
1197 (void)rd_skip(TAR_PAD(size
));
1199 /* read next header */
1200 nbytes
= rd_wrbuf(mybuf
, frmt
->hsz
);
1201 if (nbytes
!= frmt
->hsz
) {
1202 paxwarn(1,"extended header read failure: nbytes=%d, size=%d\n",
1205 myhd
= ((HD_USTAR
*)mybuf
);
1206 /* repeat until no more extended headers */
1209 /* The header about to be returned must now be updated using all the extended
1210 header values collected and any command line options */
1211 /* Acceleration: check during command option processing. If there are no -o
1212 options, and no changes from any header, do not need to run through this loop. */
1214 current_value
= NULL
;
1215 for (i
= 0; i
< sizeof(o_option_table
)/sizeof(O_OPTION_TYPE
); i
++) {
1216 int header_len
, free_it
;
1217 if (!o_option_table
[i
].active
) continue; /* deleted keywords */
1218 header_len
= o_option_table
[i
].header_len
;
1220 if (header_len
>= 0) { /* Normal keywords */
1221 current_value
= *o_option_table
[i
].x_value
;
1222 if (!current_value
) { /* No -o := */
1223 current_value
= *o_option_table
[i
].x_value_current
;
1224 if (current_value
) {
1225 /* Must remove it: x header values not valid beyond this header */
1226 *o_option_table
[i
].x_value_current
= NULL
;
1228 } else { /* No x values, try globals */
1229 current_value
= *o_option_table
[i
].g_value
;
1231 current_value
= *o_option_table
[i
].g_value_current
;
1234 if (current_value
) {
1235 /* Update current header with this value */
1237 printf ("Found current_value:%s for %s, pids=%d\n",
1238 current_value, o_option_table[i].name, pids);
1240 len
= strlen(current_value
);
1241 if (header_len
== KW_PATH_CASE
) { /* Special case for path keyword */
1244 strlcpy(arcn
->name
,current_value
,sizeof(arcn
->name
));
1246 if (len
> header_len
) {
1247 paxwarn(1," length of string from extended header bigger than header field:"
1248 " THAT won't work!\n");
1250 char * p
= (char *) myhd
;
1251 memcpy(&p
[o_option_table
[i
].header_inx
],
1252 current_value
, len
);
1253 if (len
!= header_len
) {
1255 p
[o_option_table
[i
].header_inx
+len
+1] = '\0';
1260 if (free_it
) free(current_value
);
1264 if (myhd
==hd
) return(path_replaced
);
1266 /* must put new header into memory of original */
1267 memcpy(hd
, myhd
, sizeof(HD_USTAR
));
1269 return(path_replaced
);
1274 * determine if a block given to us is a valid pax header. We have to
1275 * be on the lookout for those pesky blocks of all zero's
1277 * 0 if a ustar header, -1 otherwise
1281 pax_id(char *blk
, int size
)
1287 hd
= (HD_USTAR
*)blk
;
1290 * check for block of zero's first, a simple and fast test then check
1291 * ustar magic cookie. We should use TMAGLEN, but some USTAR archive
1292 * programs are fouled up and create archives missing the \0. Last we
1293 * check the checksum. If ok we have to assume it is a valid header.
1295 if (hd
->name
[0] == '\0')
1297 if (strncmp(hd
->magic
, TMAGIC
, TMAGLEN
- 1) != 0)
1299 if (asc_ul(hd
->chksum
,sizeof(hd
->chksum
),OCT
) != pax_chksm(blk
,BLKMULT
))
1301 if ((hd
->typeflag
!= PAXXTYPE
) && (hd
->typeflag
!= PAXGTYPE
)) {
1302 /* Not explicitly pax format, but at least ustar */
1303 if (act
==LIST
|| act
==EXTRACT
) {
1304 /* Although insufficient evidence, call it pax format */
1309 pax_invalid_action
= PAX_INVALID_ACTION_BYPASS
; /* Default for pax format */
1315 * extract the values out of block already determined to be a pax header.
1316 * store the values in the ARCHD parameter.
1322 pax_rd(ARCHD
*arcn
, char *buf
)
1331 * we only get proper sized buffers
1333 if (pax_id(buf
, BLKMULT
) < 0)
1336 memset(arcn
, 0, sizeof(*arcn
));
1337 arcn
->org_name
= arcn
->name
;
1338 arcn
->sb
.st_nlink
= 1;
1339 hd
= (HD_USTAR
*)buf
;
1341 check_path
= expand_extended_headers(arcn
, hd
);
1345 * pathname derived from extended head or -o option;
1346 * full name is in one string, but length may exceed
1347 * max path so be careful.
1349 if (arcn
->nlen
> sizeof(arcn
->name
)) {
1350 paxwarn(1,"pathname from extended header info doesn't fit! (len=%d)\n",
1355 * see if the filename is split into two parts. if so, join the parts.
1356 * we copy the prefix first and add a / between the prefix and name.
1358 char *dest
= arcn
->name
;
1359 if (*(hd
->prefix
) != '\0') {
1360 cnt
= strlcpy(dest
, hd
->prefix
, sizeof(arcn
->name
) - 1);
1368 if (hd
->typeflag
!= LONGLINKTYPE
&& hd
->typeflag
!= LONGNAMETYPE
) {
1369 arcn
->nlen
= expandname(dest
, sizeof(arcn
->name
) - cnt
,
1370 &gnu_name_string
, hd
->name
, sizeof(hd
->name
));
1371 arcn
->ln_nlen
= expandname(arcn
->ln_name
, sizeof(arcn
->ln_name
),
1372 &gnu_link_string
, hd
->linkname
, sizeof(hd
->linkname
));
1377 * follow the spec to the letter. we should only have mode bits, strip
1378 * off all other crud we may be passed.
1380 arcn
->sb
.st_mode
= (mode_t
)(asc_ul(hd
->mode
, sizeof(hd
->mode
), OCT
) &
1383 arcn
->sb
.st_size
= (off_t
)asc_ul(hd
->size
, sizeof(hd
->size
), OCT
);
1385 arcn
->sb
.st_size
= (off_t
)asc_uqd(hd
->size
, sizeof(hd
->size
), OCT
);
1387 arcn
->sb
.st_mtime
= (time_t)asc_ul(hd
->mtime
, sizeof(hd
->mtime
), OCT
);
1388 arcn
->sb
.st_ctime
= arcn
->sb
.st_atime
= arcn
->sb
.st_mtime
;
1391 * If we can find the ascii names for gname and uname in the password
1392 * and group files we will use the uid's and gid they bind. Otherwise
1393 * we use the uid and gid values stored in the header. (This is what
1394 * the posix spec wants).
1396 hd
->gname
[sizeof(hd
->gname
) - 1] = '\0';
1397 if (gid_name(hd
->gname
, &(arcn
->sb
.st_gid
)) < 0)
1398 arcn
->sb
.st_gid
= (gid_t
)asc_ul(hd
->gid
, sizeof(hd
->gid
), OCT
);
1399 hd
->uname
[sizeof(hd
->uname
) - 1] = '\0';
1400 if (uid_name(hd
->uname
, &(arcn
->sb
.st_uid
)) < 0)
1401 arcn
->sb
.st_uid
= (uid_t
)asc_ul(hd
->uid
, sizeof(hd
->uid
), OCT
);
1404 * set the defaults, these may be changed depending on the file type
1408 arcn
->sb
.st_rdev
= (dev_t
)0;
1411 * set the mode and PAX type according to the typeflag in the header
1413 switch (hd
->typeflag
) {
1415 arcn
->type
= PAX_FIF
;
1416 arcn
->sb
.st_mode
|= S_IFIFO
;
1419 arcn
->type
= PAX_DIR
;
1420 arcn
->sb
.st_mode
|= S_IFDIR
;
1421 arcn
->sb
.st_nlink
= 2;
1424 * Some programs that create pax archives append a '/'
1425 * to the pathname for directories. This clearly violates
1426 * pax specs, but we will silently strip it off anyway.
1428 if (arcn
->name
[arcn
->nlen
- 1] == '/')
1429 arcn
->name
[--arcn
->nlen
] = '\0';
1434 * this type requires the rdev field to be set.
1436 if (hd
->typeflag
== BLKTYPE
) {
1437 arcn
->type
= PAX_BLK
;
1438 arcn
->sb
.st_mode
|= S_IFBLK
;
1440 arcn
->type
= PAX_CHR
;
1441 arcn
->sb
.st_mode
|= S_IFCHR
;
1443 devmajor
= (dev_t
)asc_ul(hd
->devmajor
,sizeof(hd
->devmajor
),OCT
);
1444 devminor
= (dev_t
)asc_ul(hd
->devminor
,sizeof(hd
->devminor
),OCT
);
1445 arcn
->sb
.st_rdev
= TODEV(devmajor
, devminor
);
1449 if (hd
->typeflag
== SYMTYPE
) {
1450 arcn
->type
= PAX_SLK
;
1451 arcn
->sb
.st_mode
|= S_IFLNK
;
1453 arcn
->type
= PAX_HLK
;
1455 * so printing looks better
1457 arcn
->sb
.st_mode
|= S_IFREG
;
1458 arcn
->sb
.st_nlink
= 2;
1464 * GNU long link/file; we tag these here and let the
1465 * pax internals deal with it -- too ugly otherwise.
1468 hd
->typeflag
== LONGLINKTYPE
? PAX_GLL
: PAX_GLF
;
1469 arcn
->pad
= TAR_PAD(arcn
->sb
.st_size
);
1470 arcn
->skip
= arcn
->sb
.st_size
;
1477 * these types have file data that follows. Set the skip and
1480 arcn
->type
= PAX_REG
;
1481 arcn
->pad
= TAR_PAD(arcn
->sb
.st_size
);
1482 arcn
->skip
= arcn
->sb
.st_size
;
1483 arcn
->sb
.st_mode
|= S_IFREG
;
1490 adjust_copy_for_pax_options(ARCHD
* arcn
)
1492 /* Because ext_header options take precedence over global_header options, apply
1493 global options first, then override with any extended header options */
1495 if (global_ext_header_inx
) {
1496 for (i
=0; i
< global_ext_header_inx
; i
++) {
1497 if (!o_option_table
[global_ext_header_entry
[i
]].active
) continue; /* deleted keywords */
1498 if (strcmp(o_option_table
[global_ext_header_entry
[i
]].name
, "path")==0) {
1499 strlcpy(arcn
->name
,*(o_option_table
[global_ext_header_entry
[i
]].g_value
),
1500 sizeof(arcn
->name
));
1501 arcn
->nlen
= strlen(*(o_option_table
[global_ext_header_entry
[i
]].g_value
));
1502 } else { /* only handle path for now: others TBD */
1503 paxwarn(1, "adjust arcn for global extended header options not implemented:%d", i
);
1507 if (ext_header_inx
) {
1508 for (i
=0; i
< ext_header_inx
; i
++) {
1509 if (!o_option_table
[ext_header_entry
[i
]].active
) continue; /* deleted keywords */
1510 if (strcmp(o_option_table
[ext_header_entry
[i
]].name
, "path")==0) {
1511 strlcpy(arcn
->name
,*(o_option_table
[ext_header_entry
[i
]].x_value
),
1512 sizeof(arcn
->name
));
1513 arcn
->nlen
= strlen(*(o_option_table
[ext_header_entry
[i
]].x_value
));
1514 } else { /* only handle path for now: others TBD */
1515 paxwarn(1, "adjust arcn for extended header options not implemented:%d", i
);
1519 if (want_a_m_time_headers
) {
1525 emit_extended_header_record(int len
, int total_len
, int head_type
,
1526 char * name
, char * value
)
1528 if (total_len
+ len
> sizeof(pax_eh_datablk
)) {
1529 paxwarn(1,"extended header buffer overflow for header type '%c': %d",
1530 head_type
, total_len
+len
);
1532 sprintf(&pax_eh_datablk
[total_len
],"%d %s=%s\n", len
, name
, value
);
1539 substitute_percent(char * header
, char * filename
)
1541 char *nextpercent
, *nextchar
;
1544 char *dname
, *fname
;
1546 nextpercent
= strchr(header
,'%');
1547 if (nextpercent
==NULL
) return header
;
1548 pos
= nextpercent
-header
;
1549 memcpy(buf
,header
, pos
);
1550 while (nextpercent
++) {
1551 switch (*nextpercent
) {
1553 buf
[pos
++]='%'; /* just skip it */
1556 dname
= strrchr(filename
,'/');
1561 cpylen
= dname
-filename
;
1564 memcpy(&buf
[pos
],dname
,cpylen
);
1568 fname
= strrchr(filename
,'/');
1574 cpylen
= strlen(fname
);
1575 memcpy(&buf
[pos
],fname
,cpylen
);
1579 pos
+= sprintf (&buf
[pos
],"%d",nglobal_headers
);
1582 pos
+= sprintf (&buf
[pos
],"%d",getpid());
1585 paxwarn(1,"header format substitution failed: '%c'", *nextpercent
);
1589 if (*nextpercent
=='\0') {
1592 nextchar
= nextpercent
;
1593 nextpercent
= strchr(nextpercent
,'%');
1594 if (nextpercent
==NULL
) {
1595 cpylen
= strlen(nextchar
);
1597 cpylen
= nextpercent
- nextchar
;
1599 memcpy(&buf
[pos
],nextchar
, cpylen
);
1603 return (strdup(&buf
[0]));
1607 generate_pax_ext_header_and_data(ARCHD
*arcn
, int nfields
, int *table
,
1608 char header_type
, char * header_name
, char * header_name_requested
)
1611 char hdblk
[sizeof(HD_USTAR
)];
1612 u_long records_size
;
1613 int term_char
, i
, len
, total_len
;
1616 if (nfields
== 0 && (header_name_requested
== NULL
)) {
1617 if (header_type
==PAXXTYPE
) {
1618 if (!want_a_m_time_headers
) return (0);
1623 /* There might be no fields but a header with a specific name or
1624 times might be wanted */
1628 memset(hdblk
, 0, sizeof(hdblk
));
1629 hd
= (HD_USTAR
*)hdblk
;
1630 memset(pax_eh_datablk
, 0, sizeof(pax_eh_datablk
));
1632 /* generate header */
1633 hd
->typeflag
= header_type
;
1635 /* These fields appear to be necessary to be able to treat extended headers
1636 like files in older versions of pax */
1637 ul_oct((u_long
)0444, hd
->mode
, sizeof(hd
->mode
), term_char
);
1638 strncpy(hd
->magic
, TMAGIC
, TMAGLEN
);
1639 strncpy(hd
->version
, TVERSION
, TVERSLEN
);
1640 ul_oct((u_long
)arcn
->sb
.st_mtime
,hd
->mtime
,sizeof(hd
->mtime
),term_char
);
1642 /* compute size of data */
1644 for (i
=0; i
< nfields
; i
++) {
1645 if (!o_option_table
[table
[i
]].active
) continue; /* deleted keywords */
1646 name
= o_option_table
[table
[i
]].name
;
1647 if (header_type
== PAXXTYPE
) {
1648 str
= *(o_option_table
[table
[i
]].x_value
);
1650 str
= *(o_option_table
[table
[i
]].g_value
);
1653 paxwarn(1,"Missing option value for %s", name
);
1656 len
= strlen(str
) + o_option_table
[table
[i
]].len
+ 3;
1658 else if (len
< 98) len
= len
+ 2;
1659 else if (len
< 997) len
= len
+ 3;
1660 else if (len
< 9996) len
= len
+ 4;
1662 paxwarn(1,"extended header data too long for header type '%c': %d",
1665 total_len
= emit_extended_header_record(len
, total_len
,
1666 header_type
, name
, str
);
1669 if ((header_type
== PAXXTYPE
) && want_a_m_time_headers
) {
1670 char time_buffer
[12];
1671 memset(time_buffer
,0,sizeof(time_buffer
));
1672 sprintf(&time_buffer
[0],"%d",(int)arcn
->sb
.st_atime
);
1673 /* 3 chars + strlen("atime") + time + # chars in len */
1674 len
= 3 + 5 + strlen(&time_buffer
[0]) + 2;
1675 total_len
= emit_extended_header_record(len
, total_len
,
1676 header_type
, "atime", &time_buffer
[0]);
1677 memset(time_buffer
,0,sizeof(time_buffer
));
1678 sprintf(&time_buffer
[0],"%d",(int)arcn
->sb
.st_mtime
);
1679 /* 3 chars + strlen("mtime") + time + # chars in len */
1680 len
= 3 + 5 + strlen(&time_buffer
[0]) + 2;
1681 total_len
= emit_extended_header_record(len
, total_len
,
1682 header_type
, "mtime", &time_buffer
[0]);
1685 /* Check if all fields were deleted: might not need to generate anything */
1686 if ((total_len
==0) && (header_name_requested
== NULL
)) return (0);
1688 if (header_type
== PAXGTYPE
) nglobal_headers
++;
1689 /* substitution of fields in header_name */
1690 header_name
= substitute_percent(header_name
, arcn
->name
);
1691 if (strlen(header_name
) == sizeof(hd
->name
)) { /* must account for name just fits in buffer */
1692 strncpy(hd
->name
, header_name
, sizeof(hd
->name
));
1694 strlcpy(hd
->name
, header_name
, sizeof(hd
->name
));
1697 records_size
= (u_long
)total_len
;
1698 if (ul_oct(records_size
, hd
->size
, sizeof(hd
->size
), term_char
)) {
1699 paxwarn(1,"extended header data too long for header type '%c'", header_type
);
1703 if (ul_oct(pax_chksm(hdblk
, sizeof(HD_USTAR
)), hd
->chksum
, sizeof(hd
->chksum
), term_char
)) {
1704 paxwarn(1,"extended header data checksum failed: header type '%c'", header_type
);
1708 /* write out header */
1709 if (wr_rdbuf(hdblk
, sizeof(HD_USTAR
)) < 0)
1711 if (wr_skip((off_t
)(BLKMULT
- sizeof(HD_USTAR
))) < 0)
1713 /* write out header data */
1714 if (total_len
> 0) {
1715 if (wr_rdbuf(pax_eh_datablk
, total_len
) < 0)
1717 if (wr_skip((off_t
)(BLKMULT
- total_len
)) < 0)
1720 printf("data written:\n%s",&pax_eh_datablk[0]);
1725 paxwarn(0,"extended header and data written: header type '%c', #items: %d, %d characters",
1726 header_type, nfields, records_size);
1733 * write a pax header for the file specified in the ARCHD to the archive
1734 * Have to check for file types that cannot be stored and file names that
1735 * are too long. Be careful of the term (last arg) to ul_oct, we only use
1736 * '\0' for the termination character (this is different than picky tar)
1737 * ASSUMED: space after header in header block is zero filled
1739 * 0 if file has data to be written after the header, 1 if file has NO
1740 * data to write after the header, -1 if archive write failed
1748 char hdblk
[sizeof(HD_USTAR
)];
1750 int term_char
=3; /* orignal setting */
1751 term_char
=1; /* To pass conformance tests 274, 301 */
1754 * check for those file system types pax cannot store
1756 if (arcn
->type
== PAX_SCK
) {
1757 paxwarn(1, "Pax cannot archive a socket %s", arcn
->org_name
);
1762 * check the length of the linkname
1764 if (((arcn
->type
== PAX_SLK
) || (arcn
->type
== PAX_HLK
) ||
1765 (arcn
->type
== PAX_HRG
)) && (arcn
->ln_nlen
> sizeof(hd
->linkname
))){
1766 paxwarn(1, "Link name too long for pax %s", arcn
->ln_name
);
1768 * Conformance: test pax:285 wants error code to be non-zero, and
1769 * test tar:12 wants error code from pax to be 0
1775 * split the path name into prefix and name fields (if needed). if
1776 * pt != arcn->name, the name has to be split
1778 if ((pt
= name_split(arcn
->name
, arcn
->nlen
)) == NULL
) {
1779 paxwarn(1, "File name too long for pax %s", arcn
->name
);
1783 generate_pax_ext_header_and_data(arcn
, global_ext_header_inx
, &global_ext_header_entry
[0],
1784 PAXGTYPE
, header_name_g
, header_name_g_requested
);
1785 generate_pax_ext_header_and_data(arcn
, ext_header_inx
, &ext_header_entry
[0],
1786 PAXXTYPE
, header_name_x
, header_name_x_requested
);
1789 * zero out the header so we don't have to worry about zero fill below
1791 memset(hdblk
, 0, sizeof(hdblk
));
1792 hd
= (HD_USTAR
*)hdblk
;
1794 /* To pass conformance tests 274/301, always set these fields to "zero" */
1795 ul_oct(0, hd
->devmajor
, sizeof(hd
->devmajor
), term_char
);
1796 ul_oct(0, hd
->devminor
, sizeof(hd
->devminor
), term_char
);
1799 * split the name, or zero out the prefix
1801 if (pt
!= arcn
->name
) {
1803 * name was split, pt points at the / where the split is to
1804 * occur, we remove the / and copy the first part to the prefix
1807 strlcpy(hd
->prefix
, arcn
->name
, sizeof(hd
->prefix
));
1812 * copy the name part. this may be the whole path or the part after
1815 if (strlen(pt
) == sizeof(hd
->name
)) { /* must account for name just fits in buffer */
1816 strncpy(hd
->name
, pt
, sizeof(hd
->name
));
1818 strlcpy(hd
->name
, pt
, sizeof(hd
->name
));
1822 * set the fields in the header that are type dependent
1824 switch (arcn
->type
) {
1826 hd
->typeflag
= DIRTYPE
;
1827 if (ul_oct((u_long
)0L, hd
->size
, sizeof(hd
->size
), term_char
))
1832 if (arcn
->type
== PAX_CHR
)
1833 hd
->typeflag
= CHRTYPE
;
1835 hd
->typeflag
= BLKTYPE
;
1836 if (ul_oct((u_long
)MAJOR(arcn
->sb
.st_rdev
), hd
->devmajor
,
1837 sizeof(hd
->devmajor
), term_char
) ||
1838 ul_oct((u_long
)MINOR(arcn
->sb
.st_rdev
), hd
->devminor
,
1839 sizeof(hd
->devminor
), term_char
) ||
1840 ul_oct((u_long
)0L, hd
->size
, sizeof(hd
->size
), term_char
))
1844 hd
->typeflag
= FIFOTYPE
;
1845 if (ul_oct((u_long
)0L, hd
->size
, sizeof(hd
->size
), term_char
))
1851 if (arcn
->type
== PAX_SLK
)
1852 hd
->typeflag
= SYMTYPE
;
1854 hd
->typeflag
= LNKTYPE
;
1855 if (strlen(arcn
->ln_name
) == sizeof(hd
->linkname
)) { /* must account for name just fits in buffer */
1856 strncpy(hd
->linkname
, arcn
->ln_name
, sizeof(hd
->linkname
));
1858 strlcpy(hd
->linkname
, arcn
->ln_name
, sizeof(hd
->linkname
));
1860 if (ul_oct((u_long
)0L, hd
->size
, sizeof(hd
->size
), term_char
))
1867 * file data with this type, set the padding
1869 if (arcn
->type
== PAX_CTG
)
1870 hd
->typeflag
= CONTTYPE
;
1872 hd
->typeflag
= REGTYPE
;
1873 arcn
->pad
= TAR_PAD(arcn
->sb
.st_size
);
1875 if (ul_oct((u_long
)arcn
->sb
.st_size
, hd
->size
,
1876 sizeof(hd
->size
), term_char
)) {
1878 if (uqd_oct((u_quad_t
)arcn
->sb
.st_size
, hd
->size
,
1879 sizeof(hd
->size
), term_char
)) {
1881 paxwarn(1,"File is too long for pax %s",arcn
->org_name
);
1887 strncpy(hd
->magic
, TMAGIC
, TMAGLEN
);
1888 strncpy(hd
->version
, TVERSION
, TVERSLEN
);
1891 * set the remaining fields. Some versions want all 16 bits of mode
1892 * we better humor them (they really do not meet spec though)....
1894 if (ul_oct((u_long
)arcn
->sb
.st_uid
, hd
->uid
, sizeof(hd
->uid
), term_char
)) {
1895 if (uid_nobody
== 0) {
1896 if (uid_name("nobody", &uid_nobody
) == -1)
1899 if (uid_warn
!= arcn
->sb
.st_uid
) {
1900 uid_warn
= arcn
->sb
.st_uid
;
1902 "Pax header field is too small for uid %lu, "
1903 "using nobody", (u_long
)arcn
->sb
.st_uid
);
1905 if (ul_oct((u_long
)uid_nobody
, hd
->uid
, sizeof(hd
->uid
), term_char
))
1908 if (ul_oct((u_long
)arcn
->sb
.st_gid
, hd
->gid
, sizeof(hd
->gid
), term_char
)) {
1909 if (gid_nobody
== 0) {
1910 if (gid_name("nobody", &gid_nobody
) == -1)
1913 if (gid_warn
!= arcn
->sb
.st_gid
) {
1914 gid_warn
= arcn
->sb
.st_gid
;
1916 "Pax header field is too small for gid %lu, "
1917 "using nobody", (u_long
)arcn
->sb
.st_gid
);
1919 if (ul_oct((u_long
)gid_nobody
, hd
->gid
, sizeof(hd
->gid
), term_char
))
1922 /* However, Unix conformance tests do not like MORE than 12 mode bits:
1923 remove all beyond (see definition of stat.st_mode structure) */
1924 mode12only
= ((u_long
)arcn
->sb
.st_mode
) & 0x00000fff;
1925 if (ul_oct((u_long
)mode12only
, hd
->mode
, sizeof(hd
->mode
), term_char
) ||
1926 ul_oct((u_long
)arcn
->sb
.st_mtime
,hd
->mtime
,sizeof(hd
->mtime
),term_char
))
1928 strncpy(hd
->uname
, name_uid(arcn
->sb
.st_uid
, 0), sizeof(hd
->uname
));
1929 strncpy(hd
->gname
, name_gid(arcn
->sb
.st_gid
, 0), sizeof(hd
->gname
));
1932 * calculate and store the checksum write the header to the archive
1933 * return 0 tells the caller to now write the file data, 1 says no data
1934 * needs to be written
1936 if (ul_oct(pax_chksm(hdblk
, sizeof(HD_USTAR
)), hd
->chksum
,
1937 sizeof(hd
->chksum
), term_char
))
1939 if (wr_rdbuf(hdblk
, sizeof(HD_USTAR
)) < 0)
1941 if (wr_skip((off_t
)(BLKMULT
- sizeof(HD_USTAR
))) < 0)
1943 if ((arcn
->type
== PAX_CTG
) || (arcn
->type
== PAX_REG
))
1949 * header field is out of range
1951 paxwarn(1, "Pax header field is too small for %s", arcn
->org_name
);
1958 * see if the name has to be split for storage in a ustar header. We try
1959 * to fit the entire name in the name field without splitting if we can.
1960 * The split point is always at a /
1962 * character pointer to split point (always the / that is to be removed
1963 * if the split is not needed, the points is set to the start of the file
1964 * name (it would violate the spec to split there). A NULL is returned if
1965 * the file name is too long
1969 name_split(char *name
, int len
)
1974 * check to see if the file name is small enough to fit in the name
1975 * field. if so just return a pointer to the name.
1979 if (len
> (TPFSZ
+ TNMSZ
))
1983 * we start looking at the biggest sized piece that fits in the name
1984 * field. We walk forward looking for a slash to split at. The idea is
1985 * to find the biggest piece to fit in the name field (or the smallest
1986 * prefix we can find)
1988 start
= name
+ len
- TNMSZ
-1;
1989 while ((*start
!= '\0') && (*start
!= '/'))
1993 * if we hit the end of the string, this name cannot be split, so we
1994 * cannot store this file.
2001 * NOTE: /str where the length of str == TNMSZ can not be stored under
2002 * the p1003.1-1990 spec for ustar. We could force a prefix of / and
2003 * the file would then expand on extract to //str. The len == 0 below
2004 * makes this special case follow the spec to the letter.
2006 if ((len
>= TPFSZ
) || (len
== 0))
2010 * ok have a split point, return it to the caller
2017 expandname(char *buf
, size_t len
, char **gnu_name
, const char *name
, size_t name_len
)
2022 if ((nlen
= strlcpy(buf
, *gnu_name
, len
)) >= len
)
2027 if (name_len
< len
) {
2028 /* name may not be null terminated: it might be as big as the
2029 field, so copy is limited to the max size of the header field */
2030 if ((nlen
= strlcpy(buf
, name
, name_len
+1)) >= name_len
+1)
2033 if ((nlen
= strlcpy(buf
, name
, len
)) >= len
)