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");
1080 nbytes
= rd_wrbuf(mybuf
, size
);
1081 if (nbytes
!= size
) {
1082 paxwarn(1,"extended header data read failure: nbytes=%d, size=%d\n",
1086 printf("Read 1 extended header: type=%c, size=%d\n",
1087 myhd->typeflag, size);
1090 /* loop over buffer collecting attributes */
1091 while (nbytes
> 0) {
1092 int got_option
= -1;
1093 int nentries
= sscanf(&mybuf
[inx
],"%d ", &len
);
1094 if (nentries
!= 1) {
1095 paxwarn(1,"Extended header failure: length");
1097 if (mybuf
[inx
+len
-1] != '\n')
1098 paxwarn(1,"Extended header failure: missed newline");
1099 else mybuf
[inx
+len
-1] = '\0';
1100 name
= strchr(&mybuf
[inx
],' ');
1103 paxwarn(1,"Extended header failure: missing space");
1104 str
= strchr(name
,'=');
1106 *str
++='\0'; /* end of name */
1108 paxwarn(1,"Extended header failure: missing RHS string");
1109 for (i
= 0; i
< sizeof(o_option_table
)/sizeof(O_OPTION_TYPE
); i
++) {
1110 if (strncasecmp(name
, o_option_table
[i
].name
, o_option_table
[i
].len
) == 0) {
1111 /* Found option: see if already set TBD */
1117 if (got_option
== -1) {
1118 paxwarn(1,"Unrecognized header keyword: %s",name
);
1120 /* Determine precedence of -o and header attributes */
1121 int found_value
= ATTRSRC_FROM_NOWHERE
;
1122 current_value
= NULL
;
1123 if (myhd
->typeflag
== PAXXTYPE
) {
1124 if (*o_option_table
[got_option
].x_value
) {
1125 current_value
= *o_option_table
[got_option
].x_value
;
1126 found_value
= ATTRSRC_FROM_X_O_OPTION
;
1128 current_value
= str
;
1129 found_value
= ATTRSRC_FROM_X_HEADER
;
1131 } else if (myhd
->typeflag
== PAXGTYPE
) {
1132 if (*o_option_table
[got_option
].g_value
) {
1133 current_value
= *o_option_table
[got_option
].g_value
;
1134 found_value
= ATTRSRC_FROM_G_O_OPTION
;
1136 current_value
= str
;
1137 found_value
= ATTRSRC_FROM_G_HEADER
;
1140 paxwarn(1,"Unsupported header type:%c",myhd
->typeflag
);
1142 if (current_value
) {
1143 /* Save this attribute value for use later */
1144 switch (o_option_table
[got_option
].header_action
) {
1145 case O_OPTION_ACTION_IGNORE
:
1146 paxwarn(1,"ignoring header keyword: %s",name
);
1148 case O_OPTION_ACTION_STORE_HEADER2
:
1149 case O_OPTION_ACTION_STORE_HEADER
:
1150 switch (found_value
) {
1151 case ATTRSRC_FROM_NOWHERE
: /* shouldn't happen */
1152 paxwarn(1, "internal error: value from nowhere");
1154 case ATTRSRC_FROM_X_O_OPTION
:
1155 case ATTRSRC_FROM_G_O_OPTION
:
1157 case ATTRSRC_FROM_X_HEADER
:
1158 current_value
= strdup(current_value
);
1159 if(*o_option_table
[got_option
].x_value_current
)
1160 free(*o_option_table
[got_option
].x_value_current
);
1161 *o_option_table
[got_option
].x_value_current
= current_value
;
1163 case ATTRSRC_FROM_G_HEADER
:
1164 current_value
= strdup(current_value
);
1165 if(*o_option_table
[got_option
].g_value_current
)
1166 free(*o_option_table
[got_option
].g_value_current
);
1167 *o_option_table
[got_option
].g_value_current
= current_value
;
1171 case O_OPTION_ACTION_ERROR
:
1173 paxwarn(1,"Unsupported extended header attribute: %s=%s",
1182 /* position file at next header */
1183 (void)rd_skip(TAR_PAD(size
));
1185 /* read next header */
1186 nbytes
= rd_wrbuf(mybuf
, frmt
->hsz
);
1187 if (nbytes
!= frmt
->hsz
) {
1188 paxwarn(1,"extended header read failure: nbytes=%d, size=%d\n",
1191 myhd
= ((HD_USTAR
*)mybuf
);
1192 /* repeat until no more extended headers */
1195 /* The header about to be returned must now be updated using all the extended
1196 header values collected and any command line options */
1197 /* Acceleration: check during command option processing. If there are no -o
1198 options, and no changes from any header, do not need to run through this loop. */
1200 current_value
= NULL
;
1201 for (i
= 0; i
< sizeof(o_option_table
)/sizeof(O_OPTION_TYPE
); i
++) {
1202 int header_len
, free_it
;
1203 if (!o_option_table
[i
].active
) continue; /* deleted keywords */
1204 header_len
= o_option_table
[i
].header_len
;
1206 if (header_len
>= 0) { /* Normal keywords */
1207 current_value
= *o_option_table
[i
].x_value
;
1208 if (!current_value
) { /* No -o := */
1209 current_value
= *o_option_table
[i
].x_value_current
;
1210 if (current_value
) {
1211 /* Must remove it: x header values not valid beyond this header */
1212 *o_option_table
[i
].x_value_current
= NULL
;
1214 } else { /* No x values, try globals */
1215 current_value
= *o_option_table
[i
].g_value
;
1217 current_value
= *o_option_table
[i
].g_value_current
;
1220 if (current_value
) {
1221 /* Update current header with this value */
1223 printf ("Found current_value:%s for %s, pids=%d\n",
1224 current_value, o_option_table[i].name, pids);
1226 len
= strlen(current_value
);
1227 if (header_len
== KW_PATH_CASE
) { /* Special case for path keyword */
1230 strlcpy(arcn
->name
,current_value
,sizeof(arcn
->name
));
1232 if (len
> header_len
) {
1233 paxwarn(1," length of string from extended header bigger than header field:"
1234 " THAT won't work!\n");
1236 char * p
= (char *) myhd
;
1237 memcpy(&p
[o_option_table
[i
].header_inx
],
1238 current_value
, len
);
1239 if (len
!= header_len
) {
1241 p
[o_option_table
[i
].header_inx
+len
+1] = '\0';
1246 if (free_it
) free(current_value
);
1250 if (myhd
==hd
) return(path_replaced
);
1252 /* must put new header into memory of original */
1253 memcpy(hd
, myhd
, sizeof(HD_USTAR
));
1255 return(path_replaced
);
1260 * determine if a block given to us is a valid pax header. We have to
1261 * be on the lookout for those pesky blocks of all zero's
1263 * 0 if a ustar header, -1 otherwise
1267 pax_id(char *blk
, int size
)
1273 hd
= (HD_USTAR
*)blk
;
1276 * check for block of zero's first, a simple and fast test then check
1277 * ustar magic cookie. We should use TMAGLEN, but some USTAR archive
1278 * programs are fouled up and create archives missing the \0. Last we
1279 * check the checksum. If ok we have to assume it is a valid header.
1281 if (hd
->name
[0] == '\0')
1283 if (strncmp(hd
->magic
, TMAGIC
, TMAGLEN
- 1) != 0)
1285 if (asc_ul(hd
->chksum
,sizeof(hd
->chksum
),OCT
) != pax_chksm(blk
,BLKMULT
))
1287 if ((hd
->typeflag
!= PAXXTYPE
) && (hd
->typeflag
!= PAXGTYPE
)) {
1288 /* Not explicitly pax format, but at least ustar */
1289 if (act
==LIST
|| act
==EXTRACT
) {
1290 /* Although insufficient evidence, call it pax format */
1295 pax_invalid_action
= PAX_INVALID_ACTION_BYPASS
; /* Default for pax format */
1301 * extract the values out of block already determined to be a pax header.
1302 * store the values in the ARCHD parameter.
1308 pax_rd(ARCHD
*arcn
, char *buf
)
1317 * we only get proper sized buffers
1319 if (pax_id(buf
, BLKMULT
) < 0)
1322 memset(arcn
, 0, sizeof(*arcn
));
1323 arcn
->org_name
= arcn
->name
;
1324 arcn
->sb
.st_nlink
= 1;
1325 hd
= (HD_USTAR
*)buf
;
1327 check_path
= expand_extended_headers(arcn
, hd
);
1331 * pathname derived from extended head or -o option;
1332 * full name is in one string, but length may exceed
1333 * max path so be careful.
1335 if (arcn
->nlen
> sizeof(arcn
->name
)) {
1336 paxwarn(1,"pathname from extended header info doesn't fit! (len=%d)\n",
1341 * see if the filename is split into two parts. if so, join the parts.
1342 * we copy the prefix first and add a / between the prefix and name.
1344 char *dest
= arcn
->name
;
1345 if (*(hd
->prefix
) != '\0') {
1346 cnt
= strlcpy(dest
, hd
->prefix
, sizeof(arcn
->name
) - 1);
1354 if (hd
->typeflag
!= LONGLINKTYPE
&& hd
->typeflag
!= LONGNAMETYPE
) {
1355 arcn
->nlen
= expandname(dest
, sizeof(arcn
->name
) - cnt
,
1356 &gnu_name_string
, hd
->name
, sizeof(hd
->name
));
1357 arcn
->ln_nlen
= expandname(arcn
->ln_name
, sizeof(arcn
->ln_name
),
1358 &gnu_link_string
, hd
->linkname
, sizeof(hd
->linkname
));
1363 * follow the spec to the letter. we should only have mode bits, strip
1364 * off all other crud we may be passed.
1366 arcn
->sb
.st_mode
= (mode_t
)(asc_ul(hd
->mode
, sizeof(hd
->mode
), OCT
) &
1369 arcn
->sb
.st_size
= (off_t
)asc_ul(hd
->size
, sizeof(hd
->size
), OCT
);
1371 arcn
->sb
.st_size
= (off_t
)asc_uqd(hd
->size
, sizeof(hd
->size
), OCT
);
1373 arcn
->sb
.st_mtime
= (time_t)asc_ul(hd
->mtime
, sizeof(hd
->mtime
), OCT
);
1374 arcn
->sb
.st_ctime
= arcn
->sb
.st_atime
= arcn
->sb
.st_mtime
;
1377 * If we can find the ascii names for gname and uname in the password
1378 * and group files we will use the uid's and gid they bind. Otherwise
1379 * we use the uid and gid values stored in the header. (This is what
1380 * the posix spec wants).
1382 hd
->gname
[sizeof(hd
->gname
) - 1] = '\0';
1383 if (gid_name(hd
->gname
, &(arcn
->sb
.st_gid
)) < 0)
1384 arcn
->sb
.st_gid
= (gid_t
)asc_ul(hd
->gid
, sizeof(hd
->gid
), OCT
);
1385 hd
->uname
[sizeof(hd
->uname
) - 1] = '\0';
1386 if (uid_name(hd
->uname
, &(arcn
->sb
.st_uid
)) < 0)
1387 arcn
->sb
.st_uid
= (uid_t
)asc_ul(hd
->uid
, sizeof(hd
->uid
), OCT
);
1390 * set the defaults, these may be changed depending on the file type
1394 arcn
->sb
.st_rdev
= (dev_t
)0;
1397 * set the mode and PAX type according to the typeflag in the header
1399 switch (hd
->typeflag
) {
1401 arcn
->type
= PAX_FIF
;
1402 arcn
->sb
.st_mode
|= S_IFIFO
;
1405 arcn
->type
= PAX_DIR
;
1406 arcn
->sb
.st_mode
|= S_IFDIR
;
1407 arcn
->sb
.st_nlink
= 2;
1410 * Some programs that create pax archives append a '/'
1411 * to the pathname for directories. This clearly violates
1412 * pax specs, but we will silently strip it off anyway.
1414 if (arcn
->name
[arcn
->nlen
- 1] == '/')
1415 arcn
->name
[--arcn
->nlen
] = '\0';
1420 * this type requires the rdev field to be set.
1422 if (hd
->typeflag
== BLKTYPE
) {
1423 arcn
->type
= PAX_BLK
;
1424 arcn
->sb
.st_mode
|= S_IFBLK
;
1426 arcn
->type
= PAX_CHR
;
1427 arcn
->sb
.st_mode
|= S_IFCHR
;
1429 devmajor
= (dev_t
)asc_ul(hd
->devmajor
,sizeof(hd
->devmajor
),OCT
);
1430 devminor
= (dev_t
)asc_ul(hd
->devminor
,sizeof(hd
->devminor
),OCT
);
1431 arcn
->sb
.st_rdev
= TODEV(devmajor
, devminor
);
1435 if (hd
->typeflag
== SYMTYPE
) {
1436 arcn
->type
= PAX_SLK
;
1437 arcn
->sb
.st_mode
|= S_IFLNK
;
1439 arcn
->type
= PAX_HLK
;
1441 * so printing looks better
1443 arcn
->sb
.st_mode
|= S_IFREG
;
1444 arcn
->sb
.st_nlink
= 2;
1450 * GNU long link/file; we tag these here and let the
1451 * pax internals deal with it -- too ugly otherwise.
1454 hd
->typeflag
== LONGLINKTYPE
? PAX_GLL
: PAX_GLF
;
1455 arcn
->pad
= TAR_PAD(arcn
->sb
.st_size
);
1456 arcn
->skip
= arcn
->sb
.st_size
;
1463 * these types have file data that follows. Set the skip and
1466 arcn
->type
= PAX_REG
;
1467 arcn
->pad
= TAR_PAD(arcn
->sb
.st_size
);
1468 arcn
->skip
= arcn
->sb
.st_size
;
1469 arcn
->sb
.st_mode
|= S_IFREG
;
1476 adjust_copy_for_pax_options(ARCHD
* arcn
)
1478 /* Because ext_header options take precedence over global_header options, apply
1479 global options first, then override with any extended header options */
1481 if (global_ext_header_inx
) {
1482 for (i
=0; i
< global_ext_header_inx
; i
++) {
1483 if (!o_option_table
[global_ext_header_entry
[i
]].active
) continue; /* deleted keywords */
1484 if (strcmp(o_option_table
[global_ext_header_entry
[i
]].name
, "path")==0) {
1485 strlcpy(arcn
->name
,*(o_option_table
[global_ext_header_entry
[i
]].g_value
),
1486 sizeof(arcn
->name
));
1487 arcn
->nlen
= strlen(*(o_option_table
[global_ext_header_entry
[i
]].g_value
));
1488 } else { /* only handle path for now: others TBD */
1489 paxwarn(1, "adjust arcn for global extended header options not implemented:%d", i
);
1493 if (ext_header_inx
) {
1494 for (i
=0; i
< ext_header_inx
; i
++) {
1495 if (!o_option_table
[ext_header_entry
[i
]].active
) continue; /* deleted keywords */
1496 if (strcmp(o_option_table
[ext_header_entry
[i
]].name
, "path")==0) {
1497 strlcpy(arcn
->name
,*(o_option_table
[ext_header_entry
[i
]].x_value
),
1498 sizeof(arcn
->name
));
1499 arcn
->nlen
= strlen(*(o_option_table
[ext_header_entry
[i
]].x_value
));
1500 } else { /* only handle path for now: others TBD */
1501 paxwarn(1, "adjust arcn for extended header options not implemented:%d", i
);
1505 if (want_a_m_time_headers
) {
1511 emit_extended_header_record(int len
, int total_len
, int head_type
,
1512 char * name
, char * value
)
1514 if (total_len
+ len
> sizeof(pax_eh_datablk
)) {
1515 paxwarn(1,"extended header buffer overflow for header type '%c': %d",
1516 head_type
, total_len
+len
);
1518 sprintf(&pax_eh_datablk
[total_len
],"%d %s=%s\n", len
, name
, value
);
1525 substitute_percent(char * header
, char * filename
)
1527 char *nextpercent
, *nextchar
;
1530 char *dname
, *fname
;
1532 nextpercent
= strchr(header
,'%');
1533 if (nextpercent
==NULL
) return header
;
1534 pos
= nextpercent
-header
;
1535 memcpy(buf
,header
, pos
);
1536 while (nextpercent
++) {
1537 switch (*nextpercent
) {
1539 buf
[pos
++]='%'; /* just skip it */
1542 dname
= strrchr(filename
,'/');
1547 cpylen
= dname
-filename
;
1550 memcpy(&buf
[pos
],dname
,cpylen
);
1554 fname
= strrchr(filename
,'/');
1560 cpylen
= strlen(fname
);
1561 memcpy(&buf
[pos
],fname
,cpylen
);
1565 pos
+= sprintf (&buf
[pos
],"%d",nglobal_headers
);
1568 pos
+= sprintf (&buf
[pos
],"%d",getpid());
1571 paxwarn(1,"header format substitution failed: '%c'", *nextpercent
);
1575 if (*nextpercent
=='\0') {
1578 nextchar
= nextpercent
;
1579 nextpercent
= strchr(nextpercent
,'%');
1580 if (nextpercent
==NULL
) {
1581 cpylen
= strlen(nextchar
);
1583 cpylen
= nextpercent
- nextchar
;
1585 memcpy(&buf
[pos
],nextchar
, cpylen
);
1589 return (strdup(&buf
[0]));
1593 generate_pax_ext_header_and_data(ARCHD
*arcn
, int nfields
, int *table
,
1594 char header_type
, char * header_name
, char * header_name_requested
)
1597 char hdblk
[sizeof(HD_USTAR
)];
1598 u_long records_size
;
1599 int term_char
, i
, len
, total_len
;
1602 if (nfields
== 0 && (header_name_requested
== NULL
)) {
1603 if (header_type
==PAXXTYPE
) {
1604 if (!want_a_m_time_headers
) return (0);
1609 /* There might be no fields but a header with a specific name or
1610 times might be wanted */
1614 memset(hdblk
, 0, sizeof(hdblk
));
1615 hd
= (HD_USTAR
*)hdblk
;
1616 memset(pax_eh_datablk
, 0, sizeof(pax_eh_datablk
));
1618 /* generate header */
1619 hd
->typeflag
= header_type
;
1621 /* These fields appear to be necessary to be able to treat extended headers
1622 like files in older versions of pax */
1623 ul_oct((u_long
)0444, hd
->mode
, sizeof(hd
->mode
), term_char
);
1624 strncpy(hd
->magic
, TMAGIC
, TMAGLEN
);
1625 strncpy(hd
->version
, TVERSION
, TVERSLEN
);
1626 ul_oct((u_long
)arcn
->sb
.st_mtime
,hd
->mtime
,sizeof(hd
->mtime
),term_char
);
1628 /* compute size of data */
1630 for (i
=0; i
< nfields
; i
++) {
1631 if (!o_option_table
[table
[i
]].active
) continue; /* deleted keywords */
1632 name
= o_option_table
[table
[i
]].name
;
1633 if (header_type
== PAXXTYPE
) {
1634 str
= *(o_option_table
[table
[i
]].x_value
);
1636 str
= *(o_option_table
[table
[i
]].g_value
);
1639 paxwarn(1,"Missing option value for %s", name
);
1642 len
= strlen(str
) + o_option_table
[table
[i
]].len
+ 3;
1644 else if (len
< 98) len
= len
+ 2;
1645 else if (len
< 997) len
= len
+ 3;
1646 else if (len
< 9996) len
= len
+ 4;
1648 paxwarn(1,"extended header data too long for header type '%c': %d",
1651 total_len
= emit_extended_header_record(len
, total_len
,
1652 header_type
, name
, str
);
1655 if ((header_type
== PAXXTYPE
) && want_a_m_time_headers
) {
1656 char time_buffer
[12];
1657 memset(time_buffer
,0,sizeof(time_buffer
));
1658 sprintf(&time_buffer
[0],"%d",(int)arcn
->sb
.st_atime
);
1659 /* 3 chars + strlen("atime") + time + # chars in len */
1660 len
= 3 + 5 + strlen(&time_buffer
[0]) + 2;
1661 total_len
= emit_extended_header_record(len
, total_len
,
1662 header_type
, "atime", &time_buffer
[0]);
1663 memset(time_buffer
,0,sizeof(time_buffer
));
1664 sprintf(&time_buffer
[0],"%d",(int)arcn
->sb
.st_mtime
);
1665 /* 3 chars + strlen("mtime") + time + # chars in len */
1666 len
= 3 + 5 + strlen(&time_buffer
[0]) + 2;
1667 total_len
= emit_extended_header_record(len
, total_len
,
1668 header_type
, "mtime", &time_buffer
[0]);
1671 /* Check if all fields were deleted: might not need to generate anything */
1672 if ((total_len
==0) && (header_name_requested
== NULL
)) return (0);
1674 if (header_type
== PAXGTYPE
) nglobal_headers
++;
1675 /* substitution of fields in header_name */
1676 header_name
= substitute_percent(header_name
, arcn
->name
);
1677 if (strlen(header_name
) == sizeof(hd
->name
)) { /* must account for name just fits in buffer */
1678 strncpy(hd
->name
, header_name
, sizeof(hd
->name
));
1680 strlcpy(hd
->name
, header_name
, sizeof(hd
->name
));
1683 records_size
= (u_long
)total_len
;
1684 if (ul_oct(records_size
, hd
->size
, sizeof(hd
->size
), term_char
)) {
1685 paxwarn(1,"extended header data too long for header type '%c'", header_type
);
1689 if (ul_oct(pax_chksm(hdblk
, sizeof(HD_USTAR
)), hd
->chksum
, sizeof(hd
->chksum
), term_char
)) {
1690 paxwarn(1,"extended header data checksum failed: header type '%c'", header_type
);
1694 /* write out header */
1695 if (wr_rdbuf(hdblk
, sizeof(HD_USTAR
)) < 0)
1697 if (wr_skip((off_t
)(BLKMULT
- sizeof(HD_USTAR
))) < 0)
1699 /* write out header data */
1700 if (total_len
> 0) {
1701 if (wr_rdbuf(pax_eh_datablk
, total_len
) < 0)
1703 if (wr_skip((off_t
)(BLKMULT
- total_len
)) < 0)
1706 printf("data written:\n%s",&pax_eh_datablk[0]);
1711 paxwarn(0,"extended header and data written: header type '%c', #items: %d, %d characters",
1712 header_type, nfields, records_size);
1719 * write a pax header for the file specified in the ARCHD to the archive
1720 * Have to check for file types that cannot be stored and file names that
1721 * are too long. Be careful of the term (last arg) to ul_oct, we only use
1722 * '\0' for the termination character (this is different than picky tar)
1723 * ASSUMED: space after header in header block is zero filled
1725 * 0 if file has data to be written after the header, 1 if file has NO
1726 * data to write after the header, -1 if archive write failed
1734 char hdblk
[sizeof(HD_USTAR
)];
1736 int term_char
=3; /* orignal setting */
1737 term_char
=1; /* To pass conformance tests 274, 301 */
1740 * check for those file system types pax cannot store
1742 if (arcn
->type
== PAX_SCK
) {
1743 paxwarn(1, "Pax cannot archive a socket %s", arcn
->org_name
);
1748 * check the length of the linkname
1750 if (((arcn
->type
== PAX_SLK
) || (arcn
->type
== PAX_HLK
) ||
1751 (arcn
->type
== PAX_HRG
)) && (arcn
->ln_nlen
> sizeof(hd
->linkname
))){
1752 paxwarn(1, "Link name too long for pax %s", arcn
->ln_name
);
1754 * Conformance: test pax:285 wants error code to be non-zero, and
1755 * test tar:12 wants error code from pax to be 0
1761 * split the path name into prefix and name fields (if needed). if
1762 * pt != arcn->name, the name has to be split
1764 if ((pt
= name_split(arcn
->name
, arcn
->nlen
)) == NULL
) {
1765 paxwarn(1, "File name too long for pax %s", arcn
->name
);
1769 generate_pax_ext_header_and_data(arcn
, global_ext_header_inx
, &global_ext_header_entry
[0],
1770 PAXGTYPE
, header_name_g
, header_name_g_requested
);
1771 generate_pax_ext_header_and_data(arcn
, ext_header_inx
, &ext_header_entry
[0],
1772 PAXXTYPE
, header_name_x
, header_name_x_requested
);
1775 * zero out the header so we don't have to worry about zero fill below
1777 memset(hdblk
, 0, sizeof(hdblk
));
1778 hd
= (HD_USTAR
*)hdblk
;
1780 /* To pass conformance tests 274/301, always set these fields to "zero" */
1781 ul_oct(0, hd
->devmajor
, sizeof(hd
->devmajor
), term_char
);
1782 ul_oct(0, hd
->devminor
, sizeof(hd
->devminor
), term_char
);
1785 * split the name, or zero out the prefix
1787 if (pt
!= arcn
->name
) {
1789 * name was split, pt points at the / where the split is to
1790 * occur, we remove the / and copy the first part to the prefix
1793 strlcpy(hd
->prefix
, arcn
->name
, sizeof(hd
->prefix
));
1798 * copy the name part. this may be the whole path or the part after
1801 if (strlen(pt
) == sizeof(hd
->name
)) { /* must account for name just fits in buffer */
1802 strncpy(hd
->name
, pt
, sizeof(hd
->name
));
1804 strlcpy(hd
->name
, pt
, sizeof(hd
->name
));
1808 * set the fields in the header that are type dependent
1810 switch (arcn
->type
) {
1812 hd
->typeflag
= DIRTYPE
;
1813 if (ul_oct((u_long
)0L, hd
->size
, sizeof(hd
->size
), term_char
))
1818 if (arcn
->type
== PAX_CHR
)
1819 hd
->typeflag
= CHRTYPE
;
1821 hd
->typeflag
= BLKTYPE
;
1822 if (ul_oct((u_long
)MAJOR(arcn
->sb
.st_rdev
), hd
->devmajor
,
1823 sizeof(hd
->devmajor
), term_char
) ||
1824 ul_oct((u_long
)MINOR(arcn
->sb
.st_rdev
), hd
->devminor
,
1825 sizeof(hd
->devminor
), term_char
) ||
1826 ul_oct((u_long
)0L, hd
->size
, sizeof(hd
->size
), term_char
))
1830 hd
->typeflag
= FIFOTYPE
;
1831 if (ul_oct((u_long
)0L, hd
->size
, sizeof(hd
->size
), term_char
))
1837 if (arcn
->type
== PAX_SLK
)
1838 hd
->typeflag
= SYMTYPE
;
1840 hd
->typeflag
= LNKTYPE
;
1841 if (strlen(arcn
->ln_name
) == sizeof(hd
->linkname
)) { /* must account for name just fits in buffer */
1842 strncpy(hd
->linkname
, arcn
->ln_name
, sizeof(hd
->linkname
));
1844 strlcpy(hd
->linkname
, arcn
->ln_name
, sizeof(hd
->linkname
));
1846 if (ul_oct((u_long
)0L, hd
->size
, sizeof(hd
->size
), term_char
))
1853 * file data with this type, set the padding
1855 if (arcn
->type
== PAX_CTG
)
1856 hd
->typeflag
= CONTTYPE
;
1858 hd
->typeflag
= REGTYPE
;
1859 arcn
->pad
= TAR_PAD(arcn
->sb
.st_size
);
1861 if (ul_oct((u_long
)arcn
->sb
.st_size
, hd
->size
,
1862 sizeof(hd
->size
), term_char
)) {
1864 if (uqd_oct((u_quad_t
)arcn
->sb
.st_size
, hd
->size
,
1865 sizeof(hd
->size
), term_char
)) {
1867 paxwarn(1,"File is too long for pax %s",arcn
->org_name
);
1873 strncpy(hd
->magic
, TMAGIC
, TMAGLEN
);
1874 strncpy(hd
->version
, TVERSION
, TVERSLEN
);
1877 * set the remaining fields. Some versions want all 16 bits of mode
1878 * we better humor them (they really do not meet spec though)....
1880 if (ul_oct((u_long
)arcn
->sb
.st_uid
, hd
->uid
, sizeof(hd
->uid
), term_char
)) {
1881 if (uid_nobody
== 0) {
1882 if (uid_name("nobody", &uid_nobody
) == -1)
1885 if (uid_warn
!= arcn
->sb
.st_uid
) {
1886 uid_warn
= arcn
->sb
.st_uid
;
1888 "Pax header field is too small for uid %lu, "
1889 "using nobody", (u_long
)arcn
->sb
.st_uid
);
1891 if (ul_oct((u_long
)uid_nobody
, hd
->uid
, sizeof(hd
->uid
), term_char
))
1894 if (ul_oct((u_long
)arcn
->sb
.st_gid
, hd
->gid
, sizeof(hd
->gid
), term_char
)) {
1895 if (gid_nobody
== 0) {
1896 if (gid_name("nobody", &gid_nobody
) == -1)
1899 if (gid_warn
!= arcn
->sb
.st_gid
) {
1900 gid_warn
= arcn
->sb
.st_gid
;
1902 "Pax header field is too small for gid %lu, "
1903 "using nobody", (u_long
)arcn
->sb
.st_gid
);
1905 if (ul_oct((u_long
)gid_nobody
, hd
->gid
, sizeof(hd
->gid
), term_char
))
1908 /* However, Unix conformance tests do not like MORE than 12 mode bits:
1909 remove all beyond (see definition of stat.st_mode structure) */
1910 mode12only
= ((u_long
)arcn
->sb
.st_mode
) & 0x00000fff;
1911 if (ul_oct((u_long
)mode12only
, hd
->mode
, sizeof(hd
->mode
), term_char
) ||
1912 ul_oct((u_long
)arcn
->sb
.st_mtime
,hd
->mtime
,sizeof(hd
->mtime
),term_char
))
1914 strncpy(hd
->uname
, name_uid(arcn
->sb
.st_uid
, 0), sizeof(hd
->uname
));
1915 strncpy(hd
->gname
, name_gid(arcn
->sb
.st_gid
, 0), sizeof(hd
->gname
));
1918 * calculate and store the checksum write the header to the archive
1919 * return 0 tells the caller to now write the file data, 1 says no data
1920 * needs to be written
1922 if (ul_oct(pax_chksm(hdblk
, sizeof(HD_USTAR
)), hd
->chksum
,
1923 sizeof(hd
->chksum
), term_char
))
1925 if (wr_rdbuf(hdblk
, sizeof(HD_USTAR
)) < 0)
1927 if (wr_skip((off_t
)(BLKMULT
- sizeof(HD_USTAR
))) < 0)
1929 if ((arcn
->type
== PAX_CTG
) || (arcn
->type
== PAX_REG
))
1935 * header field is out of range
1937 paxwarn(1, "Pax header field is too small for %s", arcn
->org_name
);
1944 * see if the name has to be split for storage in a ustar header. We try
1945 * to fit the entire name in the name field without splitting if we can.
1946 * The split point is always at a /
1948 * character pointer to split point (always the / that is to be removed
1949 * if the split is not needed, the points is set to the start of the file
1950 * name (it would violate the spec to split there). A NULL is returned if
1951 * the file name is too long
1955 name_split(char *name
, int len
)
1960 * check to see if the file name is small enough to fit in the name
1961 * field. if so just return a pointer to the name.
1965 if (len
> (TPFSZ
+ TNMSZ
))
1969 * we start looking at the biggest sized piece that fits in the name
1970 * field. We walk forward looking for a slash to split at. The idea is
1971 * to find the biggest piece to fit in the name field (or the smallest
1972 * prefix we can find)
1974 start
= name
+ len
- TNMSZ
-1;
1975 while ((*start
!= '\0') && (*start
!= '/'))
1979 * if we hit the end of the string, this name cannot be split, so we
1980 * cannot store this file.
1987 * NOTE: /str where the length of str == TNMSZ can not be stored under
1988 * the p1003.1-1990 spec for ustar. We could force a prefix of / and
1989 * the file would then expand on extract to //str. The len == 0 below
1990 * makes this special case follow the spec to the letter.
1992 if ((len
>= TPFSZ
) || (len
== 0))
1996 * ok have a split point, return it to the caller
2003 expandname(char *buf
, size_t len
, char **gnu_name
, const char *name
, size_t name_len
)
2008 if ((nlen
= strlcpy(buf
, *gnu_name
, len
)) >= len
)
2013 if (name_len
< len
) {
2014 /* name may not be null terminated: it might be as big as the
2015 field, so copy is limited to the max size of the header field */
2016 if ((nlen
= strlcpy(buf
, name
, name_len
+1)) >= name_len
+1)
2019 if ((nlen
= strlcpy(buf
, name
, len
)) >= len
)