file_cmds-185.2.tar.gz
[apple/file_cmds.git] / pax / pax_format.c
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 $ */
3
4 /*-
5 * Copyright (c) 1992 Keith Muller.
6 * Copyright (c) 1992, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * This code is derived from software contributed to Berkeley by
10 * Keith Muller of the University of California, San Diego.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
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.
23 *
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
34 * SUCH DAMAGE.
35 */
36
37 #ifndef lint
38 #if 0
39 static const char sccsid[] = "@(#)tar.c 8.2 (Berkeley) 4/18/94";
40 #else
41 static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: tar.c,v 1.34 2004/10/23 19:34:14 otto Exp $";
42 #endif
43 #endif /* not lint */
44
45 #include <sys/types.h>
46 #include <sys/time.h>
47 #include <sys/stat.h>
48 #include <sys/param.h>
49 #include <string.h>
50 #include <stdio.h>
51 #include <unistd.h>
52 #include <stdlib.h>
53 #include "pax.h"
54 #include "extern.h"
55 #include "tar.h"
56 #include <fnmatch.h>
57 #include <regex.h>
58 #include "pat_rep.h"
59 #include <errno.h>
60
61 /*
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.
69 */
70
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;
75
76 int pax_invalid_action = 0;
77 char * pax_invalid_action_write_path = NULL;
78 char * pax_invalid_action_write_cwd = NULL;
79
80 char
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;
92
93 char *header_name_g_requested = NULL,
94 *header_name_x_requested = NULL;
95
96 char *header_name_g = "/tmp/GlobalHead.%p.%n",
97 *header_name_x = "%d/PaxHeaders.%p/%f";
98
99 int nglobal_headers = 0;
100 char *pax_list_opt_format;
101
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
110
111 #define O_OPTION_ACTION_IGNORE 8
112 #define O_OPTION_ACTION_ERROR 9
113 #define O_OPTION_ACTION_STORE_HEADER2 10
114
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
120
121 #define KW_PATH_CASE 0
122 #define KW_SKIP_CASE -1
123
124 typedef struct {
125 char * name;
126 int len;
127 int active; /* 1 means active, 0 means deleted via -o delete= */
128 int cmdline_action;
129 int header_action;
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= */
138 } O_OPTION_TYPE;
139
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 },
163
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 },
168
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 },
180 };
181
182 int ext_header_inx,
183 global_ext_header_inx;
184
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)];
188
189 /*
190 * Routines for reading, writing and header identify of various versions of pax
191 */
192
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);
197 #ifndef LONG_OFF_T
198 static int uqd_oct(u_quad_t, char *, int, int);
199 #endif
200
201 static uid_t uid_nobody;
202 static uid_t uid_warn;
203 static gid_t gid_nobody;
204 static gid_t gid_warn;
205
206 /*
207 * Routines common to all versions of pax
208 */
209
210 #if 0
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 */
214
215 /*
216 * tar_endwr()
217 * add the tar trailer of two null blocks
218 * Return:
219 * 0 if ok, -1 otherwise (what wr_skip returns)
220 */
221
222 int
223 tar_endwr(void)
224 {
225 return(wr_skip((off_t)(NULLCNT*BLKMULT)));
226 }
227
228 /*
229 * tar_endrd()
230 * no cleanup needed here, just return size of trailer (for append)
231 * Return:
232 * size of trailer (2 * BLKMULT)
233 */
234
235 off_t
236 tar_endrd(void)
237 {
238 return((off_t)(NULLCNT*BLKMULT));
239 }
240
241 /*
242 * tar_trail()
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.
247 * Return:
248 * 0 if a valid trailer, -1 if not a valid trailer, or 1 if the block
249 * could never contain a header.
250 */
251
252 int
253 tar_trail(ARCHD *ignore, char *buf, int in_resync, int *cnt)
254 {
255 int i;
256
257 /*
258 * look for all zero, trailer is two consecutive blocks of zero
259 */
260 for (i = 0; i < BLKMULT; ++i) {
261 if (buf[i] != '\0')
262 break;
263 }
264
265 /*
266 * if not all zero it is not a trailer, but MIGHT be a header.
267 */
268 if (i != BLKMULT)
269 return(-1);
270
271 /*
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).
278 */
279 if (!in_resync && (++*cnt >= NULLCNT))
280 return(0);
281 return(1);
282 }
283 #endif
284
285 /*
286 * ul_oct()
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.
292 * Return:
293 * 0 if the number fit into the string, -1 otherwise
294 */
295
296 static int
297 ul_oct(u_long val, char *str, int len, int term)
298 {
299 char *pt;
300
301 /*
302 * term selects the appropriate character(s) for the end of the string
303 */
304 pt = str + len - 1;
305 switch (term) {
306 case 3:
307 *pt-- = '\0';
308 break;
309 case 2:
310 *pt-- = ' ';
311 *pt-- = '\0';
312 break;
313 case 1:
314 *pt-- = ' ';
315 break;
316 case 0:
317 default:
318 *pt-- = '\0';
319 *pt-- = ' ';
320 break;
321 }
322
323 /*
324 * convert and blank pad if there is space
325 */
326 while (pt >= str) {
327 *pt-- = '0' + (char)(val & 0x7);
328 if ((val = val >> 3) == (u_long)0)
329 break;
330 }
331
332 while (pt >= str)
333 *pt-- = '0';
334 if (val != (u_long)0)
335 return(-1);
336 return(0);
337 }
338
339 #ifndef LONG_OFF_T
340 /*
341 * uqd_oct()
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.
347 * Return:
348 * 0 if the number fit into the string, -1 otherwise
349 */
350
351 static int
352 uqd_oct(u_quad_t val, char *str, int len, int term)
353 {
354 char *pt;
355
356 /*
357 * term selects the appropriate character(s) for the end of the string
358 */
359 pt = str + len - 1;
360 switch (term) {
361 case 3:
362 *pt-- = '\0';
363 break;
364 case 2:
365 *pt-- = ' ';
366 *pt-- = '\0';
367 break;
368 case 1:
369 *pt-- = ' ';
370 break;
371 case 0:
372 default:
373 *pt-- = '\0';
374 *pt-- = ' ';
375 break;
376 }
377
378 /*
379 * convert and blank pad if there is space
380 */
381 while (pt >= str) {
382 *pt-- = '0' + (char)(val & 0x7);
383 if ((val = val >> 3) == 0)
384 break;
385 }
386
387 while (pt >= str)
388 *pt-- = '0';
389 if (val != (u_quad_t)0)
390 return(-1);
391 return(0);
392 }
393 #endif
394
395 /*
396 * pax_chksm()
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.
401 * Return:
402 * unsigned long checksum
403 */
404
405 static u_long
406 pax_chksm(char *blk, int len)
407 {
408 char *stop;
409 char *pt;
410 u_long chksm = BLNKSUM; /* initial value is checksum field sum */
411
412 /*
413 * add the part of the block before the checksum field
414 */
415 pt = blk;
416 stop = blk + CHK_OFFSET;
417 while (pt < stop)
418 chksm += (u_long)(*pt++ & 0xff);
419 /*
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
422 * BLNKSUM).
423 * ASSUMED: len is greater than CHK_OFFSET. (len is where our 0 padding
424 * starts, no point in summing zero's)
425 */
426 pt += CHK_LEN;
427 stop = blk + len;
428 while (pt < stop)
429 chksm += (u_long)(*pt++ & 0xff);
430 return(chksm);
431 }
432
433 #if 0
434 /*
435 * Routines for old BSD style tar (also made portable to sysV tar)
436 */
437
438 /* pax_id must be derived from ustar, NOT tar */
439 /*
440 * tar_id()
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
443 * zero's.
444 * Return:
445 * 0 if a tar header, -1 otherwise
446 */
447
448 int
449 tar_id(char *blk, int size)
450 {
451 HD_TAR *hd;
452 HD_USTAR *uhd;
453
454 if (size < BLKMULT)
455 return(-1);
456 hd = (HD_TAR *)blk;
457 uhd = (HD_USTAR *)blk;
458
459 /*
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.
465 */
466 if (hd->name[0] == '\0')
467 return(-1);
468 if (strncmp(uhd->magic, TMAGIC, TMAGLEN - 1) == 0)
469 return(-1);
470 if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != tar_chksm(blk,BLKMULT))
471 return(-1);
472 force_one_volume = 1;
473 return(0);
474 }
475 #endif
476
477 void
478 pax_format_list_output(ARCHD *arcn, time_t now, FILE *fp, int term)
479 {
480 /* parse specified listopt format */
481 char *nextpercent, *nextchar;
482 char buf[4*1024];
483 int pos, cpylen;
484 char *fname;
485
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);
491 (void)fflush(fp);
492 return;
493 }
494 pos = nextpercent-pax_list_opt_format;
495 memcpy(buf,pax_list_opt_format, pos);
496 while (nextpercent++) {
497 switch (*nextpercent) {
498 case 'F':
499 fname = arcn->name;
500 cpylen = strlen(fname);
501 memcpy(&buf[pos],fname,cpylen);
502 pos+= cpylen;
503 break;
504 case 'D':
505 case 'T':
506 case 'M':
507 case 'L':
508 default:
509 paxwarn(1, "Unimplemented listopt format: %c",*nextpercent);
510 break;
511 }
512 nextpercent++;
513 if (*nextpercent=='\0') {
514 break;
515 }
516 nextchar = nextpercent;
517 nextpercent = strchr(nextpercent,'%');
518 if (nextpercent==NULL) {
519 cpylen = strlen(nextchar);
520 } else {
521 cpylen = nextpercent - nextchar;
522 }
523 memcpy(&buf[pos],nextchar, cpylen);
524 pos += cpylen;
525 }
526 buf[pos]='\0';
527 safe_print(&buf[0], fp);
528 (void)putc(term, fp);
529 (void)fflush(fp);
530 return;
531 }
532
533 void
534 cleanup_pax_invalid_action()
535 {
536 switch (pax_invalid_action) {
537 case PAX_INVALID_ACTION_BYPASS:
538 case PAX_INVALID_ACTION_RENAME:
539 break;
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;
545 }
546 break;
547 case PAX_INVALID_ACTION_UTF8:
548 default:
549 paxwarn(1, "pax_invalid_action not implemented:%d", pax_invalid_action);
550 }
551 }
552
553 void
554 record_pax_invalid_action_results(ARCHD * arcn, char * fixed_path)
555 {
556 switch (pax_invalid_action) {
557 case PAX_INVALID_ACTION_BYPASS:
558 case PAX_INVALID_ACTION_RENAME:
559 break;
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';
564 break;
565 case PAX_INVALID_ACTION_UTF8:
566 default:
567 paxwarn(1, "pax_invalid_action not implemented:%d", pax_invalid_action);
568 }
569 }
570
571 int
572 perform_pax_invalid_action(ARCHD * arcn, int err)
573 {
574 int rc = 0;
575 switch (pax_invalid_action) {
576 case PAX_INVALID_ACTION_BYPASS:
577 rc = -1;
578 break;
579 case PAX_INVALID_ACTION_RENAME:
580 rc = tty_rename(arcn);
581 break;
582 case PAX_INVALID_ACTION_WRITE:
583 pax_invalid_action_write_path = NULL;
584 pax_invalid_action_write_cwd = NULL;
585 rc = 2;
586 break;
587 case PAX_INVALID_ACTION_UTF8:
588 default:
589 paxwarn(1, "pax_invalid_action not implemented:%d", pax_invalid_action);
590 rc = -1; /* do nothing? */
591 }
592 return rc;
593 }
594
595 void
596 delete_keywords(char * pattern)
597 {
598 int i;
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;
604 }
605 }
606 }
607
608 /*
609 * pax_opt()
610 * handle pax format specific -o options
611 * Return:
612 * 0 if ok -1 otherwise
613 */
614
615 int
616 pax_opt(void)
617 {
618 OPLIST *opt;
619 int got_option = 0;
620
621 while ((opt = opt_next()) != NULL) {
622 int i;
623 got_option = -1;
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 */
629 /* Save it away */
630 got_option = 1;
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",
635 opt->name);
636 break;
637 }
638 if (opt->value) {
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;
647 } else {
648 paxwarn(1,"Invalid action %s not recognized: option ignored",
649 opt->value);
650 }
651 } else {
652 paxwarn(1,"Invalid action RHS not specified: option ignored");
653 }
654 break;
655 case O_OPTION_ACTION_DELETE:
656 if (opt->separator != SEP_EQ) {
657 paxwarn(1,"-o %s= option requires '=' separator: option ignored",
658 opt->name);
659 break;
660 }
661 /* Mark all matches as deleted */
662 /* can have multiple -o delete= patterns */
663 delete_keywords(opt->value);
664 break;
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);
672 } else {
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);
681 }
682 }
683 break;
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);
687 break;
688 }
689 want_a_m_time_headers = 1;
690 break;
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);
694 break;
695 }
696 want_linkdata = 1;
697 break;
698 case O_OPTION_ACTION_HEADER_NAME:
699 if (opt->separator != SEP_EQ) {
700 paxwarn(1,"-o %s= option requires '=' separator: option ignored",
701 opt->name);
702 break;
703 }
704 *(o_option_table[i].g_value) = opt->value;
705 *(o_option_table[i].x_value) = "YES";
706 break;
707 case O_OPTION_ACTION_LISTOPT:
708 if (opt->separator != SEP_EQ) {
709 paxwarn(1,"-o %s= option requires '=' separator: option ignored",
710 opt->name);
711 break;
712 }
713 *(o_option_table[i].g_value) = opt->value;
714 break;
715 case O_OPTION_ACTION_NOTIMPL:
716 default:
717 paxwarn(1,"pax format -o option not yet implemented: %s=%s",
718 opt->name, opt->value);
719 break;
720 }
721 break;
722 }
723 }
724 if (got_option == -1) {
725 paxwarn(1,"pax format -o option not recognized: %s=%s",
726 opt->name, opt->value);
727 }
728 }
729 return(0);
730 }
731
732
733 #if 0
734 /* pax_rd is derived from ustar_rd NOT tar_rd */
735 /*
736 * tar_rd()
737 * extract the values out of block already determined to be a tar header.
738 * store the values in the ARCHD parameter.
739 * Return:
740 * 0
741 */
742
743 int
744 tar_rd(ARCHD *arcn, char *buf)
745 {
746 HD_TAR *hd;
747 char *pt;
748
749 /*
750 * we only get proper sized buffers passed to us
751 */
752 if (tar_id(buf, BLKMULT) < 0)
753 return(-1);
754 memset(arcn, 0, sizeof(*arcn));
755 arcn->org_name = arcn->name;
756 arcn->sb.st_nlink = 1;
757
758 /*
759 * copy out the name and values in the stat buffer
760 */
761 hd = (HD_TAR *)buf;
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));
767 }
768 arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode,sizeof(hd->mode),OCT) &
769 0xfff);
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);
772 #ifdef LONG_OFF_T
773 arcn->sb.st_size = (off_t)asc_ul(hd->size, sizeof(hd->size), OCT);
774 #else
775 arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT);
776 #endif
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;
779
780 /*
781 * have to look at the last character, it may be a '/' and that is used
782 * to encode this as a directory
783 */
784 pt = &(arcn->name[arcn->nlen - 1]);
785 arcn->pad = 0;
786 arcn->skip = 0;
787 switch (hd->linkflag) {
788 case SYMTYPE:
789 /*
790 * symbolic link, need to get the link name and set the type in
791 * the st_mode so -v printing will look correct.
792 */
793 arcn->type = PAX_SLK;
794 arcn->sb.st_mode |= S_IFLNK;
795 break;
796 case LNKTYPE:
797 /*
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.
800 */
801 arcn->type = PAX_HLK;
802 arcn->sb.st_nlink = 2;
803
804 /*
805 * no idea of what type this thing really points at, but
806 * we set something for printing only.
807 */
808 arcn->sb.st_mode |= S_IFREG;
809 break;
810 case LONGLINKTYPE:
811 case LONGNAMETYPE:
812 /*
813 * GNU long link/file; we tag these here and let the
814 * pax internals deal with it -- too ugly otherwise.
815 */
816 arcn->type =
817 hd->linkflag == LONGLINKTYPE ? PAX_GLL : PAX_GLF;
818 arcn->pad = TAR_PAD(arcn->sb.st_size);
819 arcn->skip = arcn->sb.st_size;
820 break;
821 case DIRTYPE:
822 /*
823 * It is a directory, set the mode for -v printing
824 */
825 arcn->type = PAX_DIR;
826 arcn->sb.st_mode |= S_IFDIR;
827 arcn->sb.st_nlink = 2;
828 break;
829 case AREGTYPE:
830 case REGTYPE:
831 default:
832 /*
833 * If we have a trailing / this is a directory and NOT a file.
834 */
835 arcn->ln_name[0] = '\0';
836 arcn->ln_nlen = 0;
837 if (*pt == '/') {
838 /*
839 * it is a directory, set the mode for -v printing
840 */
841 arcn->type = PAX_DIR;
842 arcn->sb.st_mode |= S_IFDIR;
843 arcn->sb.st_nlink = 2;
844 } else {
845 /*
846 * have a file that will be followed by data. Set the
847 * skip value to the size field and calculate the size
848 * of the padding.
849 */
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;
854 }
855 break;
856 }
857
858 /*
859 * strip off any trailing slash.
860 */
861 if (*pt == '/') {
862 *pt = '\0';
863 --arcn->nlen;
864 }
865 return(0);
866 }
867
868 /* pax_wr is derived from ustar_wr NOT tar_wr */
869 /*
870 * 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
876 * Return:
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
879 */
880
881 int
882 tar_wr(ARCHD *arcn)
883 {
884 HD_TAR *hd;
885 int len;
886 char hdblk[sizeof(HD_TAR)];
887
888 /*
889 * check for those file system types which tar cannot store
890 */
891 switch (arcn->type) {
892 case PAX_DIR:
893 /*
894 * user asked that dirs not be written to the archive
895 */
896 if (tar_nodir)
897 return(1);
898 break;
899 case PAX_CHR:
900 paxwarn(1, "Tar cannot archive a character device %s",
901 arcn->org_name);
902 return(1);
903 case PAX_BLK:
904 paxwarn(1, "Tar cannot archive a block device %s", arcn->org_name);
905 return(1);
906 case PAX_SCK:
907 paxwarn(1, "Tar cannot archive a socket %s", arcn->org_name);
908 return(1);
909 case PAX_FIF:
910 paxwarn(1, "Tar cannot archive a fifo %s", arcn->org_name);
911 return(1);
912 case PAX_SLK:
913 case PAX_HLK:
914 case PAX_HRG:
915 if (arcn->ln_nlen > sizeof(hd->linkname)) {
916 paxwarn(1,"Link name too long for tar %s", arcn->ln_name);
917 return(1);
918 }
919 break;
920 case PAX_REG:
921 case PAX_CTG:
922 default:
923 break;
924 }
925
926 /*
927 * check file name len, remember extra char for dirs (the / at the end)
928 */
929 len = arcn->nlen;
930 if (arcn->type == PAX_DIR)
931 ++len;
932 if (len >= sizeof(hd->name)) {
933 paxwarn(1, "File name too long for tar %s", arcn->name);
934 return(1);
935 }
936
937 /*
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).
944 */
945 memset(hdblk, 0, sizeof(hdblk));
946 hd = (HD_TAR *)hdblk;
947 strlcpy(hd->name, arcn->name, sizeof(hd->name));
948 arcn->pad = 0;
949
950 if (arcn->type == PAX_DIR) {
951 /*
952 * directories are the same as files, except have a filename
953 * that ends with a /, we add the slash here. No data follows
954 * dirs, so no pad.
955 */
956 hd->linkflag = AREGTYPE;
957 hd->name[len-1] = '/';
958 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1))
959 goto out;
960 } else if (arcn->type == PAX_SLK) {
961 /*
962 * no data follows this file, so no pad
963 */
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))
967 goto out;
968 } else if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) {
969 /*
970 * no data follows this file, so no pad
971 */
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))
975 goto out;
976 } else {
977 /*
978 * data follows this file, so set the pad
979 */
980 hd->linkflag = AREGTYPE;
981 # ifdef LONG_OFF_T
982 if (ul_oct((u_long)arcn->sb.st_size, hd->size,
983 sizeof(hd->size), 1)) {
984 # else
985 if (uqd_oct((u_quad_t)arcn->sb.st_size, hd->size,
986 sizeof(hd->size), 1)) {
987 # endif
988 paxwarn(1,"File is too large for tar %s", arcn->org_name);
989 return(1);
990 }
991 arcn->pad = TAR_PAD(arcn->sb.st_size);
992 }
993
994 /*
995 * copy those fields that are independent of the type
996 */
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))
1001 goto out;
1002
1003 /*
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
1006 * to be written
1007 */
1008 if (ul_oct(tar_chksm(hdblk, sizeof(HD_TAR)), hd->chksum,
1009 sizeof(hd->chksum), 3))
1010 goto out;
1011 if (wr_rdbuf(hdblk, sizeof(HD_TAR)) < 0)
1012 return(-1);
1013 if (wr_skip((off_t)(BLKMULT - sizeof(HD_TAR))) < 0)
1014 return(-1);
1015 if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG))
1016 return(0);
1017 return(1);
1018
1019 out:
1020 /*
1021 * header field is out of range
1022 */
1023 paxwarn(1, "Tar header field is too small for %s", arcn->org_name);
1024 return(1);
1025 }
1026 #endif
1027
1028 #if 0
1029 /*
1030 * Routines for POSIX ustar
1031 */
1032
1033 /*
1034 * ustar_strd()
1035 * initialization for ustar read
1036 * Return:
1037 * 0 if ok, -1 otherwise
1038 */
1039
1040 int
1041 ustar_strd(void)
1042 {
1043 if ((usrtb_start() < 0) || (grptb_start() < 0))
1044 return(-1);
1045 return(0);
1046 }
1047
1048 /*
1049 * ustar_stwr()
1050 * initialization for ustar write
1051 * Return:
1052 * 0 if ok, -1 otherwise
1053 */
1054
1055 int
1056 ustar_stwr(void)
1057 {
1058 if ((uidtb_start() < 0) || (gidtb_start() < 0))
1059 return(-1);
1060 return(0);
1061 }
1062 #endif
1063
1064 int
1065 expand_extended_headers(ARCHD *arcn, HD_USTAR *hd)
1066 {
1067 char mybuf[BLKMULT];
1068 HD_USTAR *myhd;
1069 char * current_value;
1070 int path_replaced = 0;
1071 int i, len;
1072
1073 myhd = hd;
1074 while (myhd->typeflag == PAXGTYPE || myhd->typeflag == PAXXTYPE) {
1075 char *name, *str;
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 exit(1);
1081 }
1082 nbytes = rd_wrbuf(mybuf, size);
1083 if (nbytes != size) {
1084 paxwarn(1,"extended header data read failure: nbytes=%d, size=%d\n",
1085 nbytes, size);
1086 exit(1);
1087 }
1088 /*
1089 printf("Read 1 extended header: type=%c, size=%d\n",
1090 myhd->typeflag, size);
1091 */
1092 inx=0;
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");
1099 exit(1);
1100 }
1101 if (len < 0 || (inx+len-1 >= sizeof(mybuf))) {
1102 paxwarn(1, "Extended header failure: invalid length (%d)", len);
1103 exit(1);
1104 }
1105 if (mybuf[inx+len-1] != '\n') {
1106 paxwarn(1,"Extended header failure: missed newline");
1107 exit(1);
1108 } else
1109 mybuf[inx+len-1] = '\0';
1110 name = strchr(&mybuf[inx],' ');
1111 if (name) name++;
1112 else {
1113 paxwarn(1,"Extended header failure: missing space");
1114 exit(1);
1115 }
1116 str = strchr(name,'=');
1117 if (str) {
1118 *str++='\0'; /* end of name */
1119 } else {
1120 paxwarn(1,"Extended header failure: missing RHS string");
1121 exit(1);
1122 }
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 */
1126 /* Save it away */
1127 got_option = i;
1128 break;
1129 }
1130 }
1131 if (got_option == -1) {
1132 paxwarn(1,"Unrecognized header keyword: %s",name);
1133 } else {
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;
1141 } else {
1142 current_value = str;
1143 found_value = ATTRSRC_FROM_X_HEADER;
1144 }
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;
1149 } else {
1150 current_value = str;
1151 found_value = ATTRSRC_FROM_G_HEADER;
1152 }
1153 } else {
1154 paxwarn(1,"Unsupported header type:%c",myhd->typeflag);
1155 }
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);
1161 break;
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");
1167 break;
1168 case ATTRSRC_FROM_X_O_OPTION:
1169 case ATTRSRC_FROM_G_O_OPTION:
1170 break;
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;
1176 break;
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;
1182 break;
1183 }
1184 break;
1185 case O_OPTION_ACTION_ERROR:
1186 default:
1187 paxwarn(1,"Unsupported extended header attribute: %s=%s",
1188 name, str);
1189 }
1190 }
1191 }
1192 inx+=len;
1193 nbytes -= len;
1194 }
1195
1196 /* position file at next header */
1197 (void)rd_skip(TAR_PAD(size));
1198
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",
1203 nbytes, frmt->hsz);
1204 }
1205 myhd = ((HD_USTAR *)mybuf);
1206 /* repeat until no more extended headers */
1207 }
1208
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. */
1213
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;
1219 free_it = 0;
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;
1227 free_it = 1;
1228 } else { /* No x values, try globals */
1229 current_value = *o_option_table[i].g_value;
1230 if (!current_value)
1231 current_value = *o_option_table[i].g_value_current;
1232 }
1233 }
1234 if (current_value) {
1235 /* Update current header with this value */
1236 /*
1237 printf ("Found current_value:%s for %s, pids=%d\n",
1238 current_value, o_option_table[i].name, pids);
1239 */
1240 len = strlen(current_value);
1241 if (header_len == KW_PATH_CASE) { /* Special case for path keyword */
1242 path_replaced = 1;
1243 arcn->nlen = len;
1244 strlcpy(arcn->name,current_value,sizeof(arcn->name));
1245 } else {
1246 if (len > header_len) {
1247 paxwarn(1," length of string from extended header bigger than header field:"
1248 " THAT won't work!\n");
1249 } else {
1250 char * p = (char *) myhd;
1251 memcpy(&p[o_option_table[i].header_inx],
1252 current_value, len);
1253 if (len != header_len) {
1254 /* pad with ? */
1255 p[o_option_table[i].header_inx+len+1] = '\0';
1256 }
1257 }
1258 }
1259 }
1260 if (free_it) free(current_value);
1261 }
1262 }
1263
1264 if (myhd==hd) return(path_replaced);
1265
1266 /* must put new header into memory of original */
1267 memcpy(hd, myhd, sizeof(HD_USTAR));
1268
1269 return(path_replaced);
1270 }
1271
1272 /*
1273 * pax_id()
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
1276 * Return:
1277 * 0 if a ustar header, -1 otherwise
1278 */
1279
1280 int
1281 pax_id(char *blk, int size)
1282 {
1283 HD_USTAR *hd;
1284
1285 if (size < BLKMULT)
1286 return(-1);
1287 hd = (HD_USTAR *)blk;
1288
1289 /*
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.
1294 */
1295 if (hd->name[0] == '\0')
1296 return(-1);
1297 if (strncmp(hd->magic, TMAGIC, TMAGLEN - 1) != 0)
1298 return(-1);
1299 if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != pax_chksm(blk,BLKMULT))
1300 return(-1);
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 */
1305 return(0);
1306 }
1307 return(-1);
1308 }
1309 pax_invalid_action = PAX_INVALID_ACTION_BYPASS; /* Default for pax format */
1310 return(0);
1311 }
1312
1313 /*
1314 * pax_rd()
1315 * extract the values out of block already determined to be a pax header.
1316 * store the values in the ARCHD parameter.
1317 * Return:
1318 * 0
1319 */
1320
1321 int
1322 pax_rd(ARCHD *arcn, char *buf)
1323 {
1324 HD_USTAR *hd;
1325 int cnt = 0;
1326 int check_path;
1327 dev_t devmajor;
1328 dev_t devminor;
1329
1330 /*
1331 * we only get proper sized buffers
1332 */
1333 if (pax_id(buf, BLKMULT) < 0)
1334 return(-1);
1335
1336 memset(arcn, 0, sizeof(*arcn));
1337 arcn->org_name = arcn->name;
1338 arcn->sb.st_nlink = 1;
1339 hd = (HD_USTAR *)buf;
1340
1341 check_path = expand_extended_headers(arcn, hd);
1342
1343 if (check_path) {
1344 /*
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.
1348 */
1349 if (arcn->nlen > sizeof(arcn->name)) {
1350 paxwarn(1,"pathname from extended header info doesn't fit! (len=%d)\n",
1351 arcn->nlen);
1352 }
1353 } else {
1354 /*
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.
1357 */
1358 char *dest = arcn->name;
1359 if (*(hd->prefix) != '\0') {
1360 cnt = strlcpy(dest, hd->prefix, sizeof(arcn->name) - 1);
1361 dest += cnt;
1362 *dest++ = '/';
1363 cnt++;
1364 } else {
1365 cnt = 0;
1366 }
1367
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));
1373 }
1374 }
1375
1376 /*
1377 * follow the spec to the letter. we should only have mode bits, strip
1378 * off all other crud we may be passed.
1379 */
1380 arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode, sizeof(hd->mode), OCT) &
1381 0xfff);
1382 #ifdef LONG_OFF_T
1383 arcn->sb.st_size = (off_t)asc_ul(hd->size, sizeof(hd->size), OCT);
1384 #else
1385 arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT);
1386 #endif
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;
1389
1390 /*
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).
1395 */
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);
1402
1403 /*
1404 * set the defaults, these may be changed depending on the file type
1405 */
1406 arcn->pad = 0;
1407 arcn->skip = 0;
1408 arcn->sb.st_rdev = (dev_t)0;
1409
1410 /*
1411 * set the mode and PAX type according to the typeflag in the header
1412 */
1413 switch (hd->typeflag) {
1414 case FIFOTYPE:
1415 arcn->type = PAX_FIF;
1416 arcn->sb.st_mode |= S_IFIFO;
1417 break;
1418 case DIRTYPE:
1419 arcn->type = PAX_DIR;
1420 arcn->sb.st_mode |= S_IFDIR;
1421 arcn->sb.st_nlink = 2;
1422
1423 /*
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.
1427 */
1428 if (arcn->name[arcn->nlen - 1] == '/')
1429 arcn->name[--arcn->nlen] = '\0';
1430 break;
1431 case BLKTYPE:
1432 case CHRTYPE:
1433 /*
1434 * this type requires the rdev field to be set.
1435 */
1436 if (hd->typeflag == BLKTYPE) {
1437 arcn->type = PAX_BLK;
1438 arcn->sb.st_mode |= S_IFBLK;
1439 } else {
1440 arcn->type = PAX_CHR;
1441 arcn->sb.st_mode |= S_IFCHR;
1442 }
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);
1446 break;
1447 case SYMTYPE:
1448 case LNKTYPE:
1449 if (hd->typeflag == SYMTYPE) {
1450 arcn->type = PAX_SLK;
1451 arcn->sb.st_mode |= S_IFLNK;
1452 } else {
1453 arcn->type = PAX_HLK;
1454 /*
1455 * so printing looks better
1456 */
1457 arcn->sb.st_mode |= S_IFREG;
1458 arcn->sb.st_nlink = 2;
1459 }
1460 break;
1461 case LONGLINKTYPE:
1462 case LONGNAMETYPE:
1463 /*
1464 * GNU long link/file; we tag these here and let the
1465 * pax internals deal with it -- too ugly otherwise.
1466 */
1467 arcn->type =
1468 hd->typeflag == LONGLINKTYPE ? PAX_GLL : PAX_GLF;
1469 arcn->pad = TAR_PAD(arcn->sb.st_size);
1470 arcn->skip = arcn->sb.st_size;
1471 break;
1472 case CONTTYPE:
1473 case AREGTYPE:
1474 case REGTYPE:
1475 default:
1476 /*
1477 * these types have file data that follows. Set the skip and
1478 * pad fields.
1479 */
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;
1484 break;
1485 }
1486 return(0);
1487 }
1488
1489 void
1490 adjust_copy_for_pax_options(ARCHD * arcn)
1491 {
1492 /* Because ext_header options take precedence over global_header options, apply
1493 global options first, then override with any extended header options */
1494 int i;
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);
1504 }
1505 }
1506 }
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);
1516 }
1517 }
1518 }
1519 if (want_a_m_time_headers) {
1520 /* TBD */
1521 }
1522 }
1523
1524 static int
1525 emit_extended_header_record(int len, int total_len, int head_type,
1526 char * name, char * value)
1527 {
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);
1531 } else {
1532 sprintf(&pax_eh_datablk[total_len],"%d %s=%s\n", len, name, value);
1533 total_len += len;
1534 }
1535 return (total_len);
1536 }
1537
1538 static char *
1539 substitute_percent(char * header, char * filename)
1540 {
1541 char *nextpercent, *nextchar;
1542 char buf[4*1024];
1543 int pos, cpylen;
1544 char *dname, *fname;
1545
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) {
1552 case '%':
1553 buf[pos++]='%'; /* just skip it */
1554 break;
1555 case 'd':
1556 dname = strrchr(filename,'/');
1557 if (dname==NULL) {
1558 cpylen = 1;
1559 dname = ".";
1560 } else {
1561 cpylen = dname-filename;
1562 dname = filename;
1563 }
1564 memcpy(&buf[pos],dname,cpylen);
1565 pos+= cpylen;
1566 break;
1567 case 'f':
1568 fname = strrchr(filename,'/');
1569 if (fname==NULL) {
1570 fname = filename;
1571 } else {
1572 fname++;
1573 }
1574 cpylen = strlen(fname);
1575 memcpy(&buf[pos],fname,cpylen);
1576 pos+= cpylen;
1577 break;
1578 case 'n':
1579 pos += sprintf (&buf[pos],"%d",nglobal_headers);
1580 break;
1581 case 'p':
1582 pos += sprintf (&buf[pos],"%d",getpid());
1583 break;
1584 default:
1585 paxwarn(1,"header format substitution failed: '%c'", *nextpercent);
1586 return (header);
1587 }
1588 nextpercent++;
1589 if (*nextpercent=='\0') {
1590 break;
1591 }
1592 nextchar = nextpercent;
1593 nextpercent = strchr(nextpercent,'%');
1594 if (nextpercent==NULL) {
1595 cpylen = strlen(nextchar);
1596 } else {
1597 cpylen = nextpercent - nextchar;
1598 }
1599 memcpy(&buf[pos],nextchar, cpylen);
1600 pos += cpylen;
1601 }
1602 buf[pos]='\0';
1603 return (strdup(&buf[0]));
1604 }
1605
1606 int
1607 generate_pax_ext_header_and_data(ARCHD *arcn, int nfields, int *table,
1608 char header_type, char * header_name, char * header_name_requested)
1609 {
1610 HD_USTAR *hd;
1611 char hdblk[sizeof(HD_USTAR)];
1612 u_long records_size;
1613 int term_char, i, len, total_len;
1614 char * str, *name;
1615
1616 if (nfields == 0 && (header_name_requested == NULL)) {
1617 if (header_type==PAXXTYPE) {
1618 if (!want_a_m_time_headers) return (0);
1619 } else
1620 return (0);
1621 }
1622
1623 /* There might be no fields but a header with a specific name or
1624 times might be wanted */
1625
1626 term_char = 1;
1627 records_size = 0;
1628 memset(hdblk, 0, sizeof(hdblk));
1629 hd = (HD_USTAR *)hdblk;
1630 memset(pax_eh_datablk, 0, sizeof(pax_eh_datablk));
1631
1632 /* generate header */
1633 hd->typeflag = header_type;
1634
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);
1641
1642 /* compute size of data */
1643 total_len = 0;
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);
1649 } else {
1650 str = *(o_option_table[table[i]].g_value);
1651 }
1652 if (str==NULL) {
1653 paxwarn(1,"Missing option value for %s", name);
1654 continue;
1655 }
1656 len = strlen(str) + o_option_table[table[i]].len + 3;
1657 if (len < 9) len++;
1658 else if (len < 98) len = len + 2;
1659 else if (len < 997) len = len + 3;
1660 else if (len < 9996) len = len + 4;
1661 else {
1662 paxwarn(1,"extended header data too long for header type '%c': %d",
1663 header_type, len);
1664 }
1665 total_len = emit_extended_header_record(len, total_len,
1666 header_type, name, str);
1667 }
1668
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]);
1683 }
1684
1685 /* Check if all fields were deleted: might not need to generate anything */
1686 if ((total_len==0) && (header_name_requested == NULL)) return (0);
1687
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));
1693 } else {
1694 strlcpy(hd->name, header_name, sizeof(hd->name));
1695 }
1696
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);
1700 return(1);
1701 }
1702
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);
1705 return(1);
1706 }
1707
1708 /* write out header */
1709 if (wr_rdbuf(hdblk, sizeof(HD_USTAR)) < 0)
1710 return(-1);
1711 if (wr_skip((off_t)(BLKMULT - sizeof(HD_USTAR))) < 0)
1712 return(-1);
1713 /* write out header data */
1714 if (total_len > 0) {
1715 if (wr_rdbuf(pax_eh_datablk, total_len) < 0)
1716 return(-1);
1717 if (wr_skip((off_t)(BLKMULT - total_len)) < 0)
1718 return(-1);
1719 /*
1720 printf("data written:\n%s",&pax_eh_datablk[0]);
1721 */
1722 }
1723
1724 /*
1725 paxwarn(0,"extended header and data written: header type '%c', #items: %d, %d characters",
1726 header_type, nfields, records_size);
1727 */
1728 return (0);
1729 }
1730
1731 /*
1732 * pax_wr()
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
1738 * Return:
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
1741 */
1742
1743 int
1744 pax_wr(ARCHD *arcn)
1745 {
1746 HD_USTAR *hd;
1747 char *pt;
1748 char hdblk[sizeof(HD_USTAR)];
1749 mode_t mode12only;
1750 int term_char=3; /* orignal setting */
1751 term_char=1; /* To pass conformance tests 274, 301 */
1752
1753 /*
1754 * check for those file system types pax cannot store
1755 */
1756 if (arcn->type == PAX_SCK) {
1757 paxwarn(1, "Pax cannot archive a socket %s", arcn->org_name);
1758 return(1);
1759 }
1760
1761 /*
1762 * check the length of the linkname
1763 */
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);
1767 /*
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
1770 */
1771 return(1);
1772 }
1773
1774 /*
1775 * split the path name into prefix and name fields (if needed). if
1776 * pt != arcn->name, the name has to be split
1777 */
1778 if ((pt = name_split(arcn->name, arcn->nlen)) == NULL) {
1779 paxwarn(1, "File name too long for pax %s", arcn->name);
1780 return(1);
1781 }
1782
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);
1787
1788 /*
1789 * zero out the header so we don't have to worry about zero fill below
1790 */
1791 memset(hdblk, 0, sizeof(hdblk));
1792 hd = (HD_USTAR *)hdblk;
1793 arcn->pad = 0L;
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);
1797
1798 /*
1799 * split the name, or zero out the prefix
1800 */
1801 if (pt != arcn->name) {
1802 /*
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
1805 */
1806 *pt = '\0';
1807 strlcpy(hd->prefix, arcn->name, sizeof(hd->prefix));
1808 *pt++ = '/';
1809 }
1810
1811 /*
1812 * copy the name part. this may be the whole path or the part after
1813 * the prefix
1814 */
1815 if (strlen(pt) == sizeof(hd->name)) { /* must account for name just fits in buffer */
1816 strncpy(hd->name, pt, sizeof(hd->name));
1817 } else {
1818 strlcpy(hd->name, pt, sizeof(hd->name));
1819 }
1820
1821 /*
1822 * set the fields in the header that are type dependent
1823 */
1824 switch (arcn->type) {
1825 case PAX_DIR:
1826 hd->typeflag = DIRTYPE;
1827 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), term_char))
1828 goto out;
1829 break;
1830 case PAX_CHR:
1831 case PAX_BLK:
1832 if (arcn->type == PAX_CHR)
1833 hd->typeflag = CHRTYPE;
1834 else
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))
1841 goto out;
1842 break;
1843 case PAX_FIF:
1844 hd->typeflag = FIFOTYPE;
1845 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), term_char))
1846 goto out;
1847 break;
1848 case PAX_SLK:
1849 case PAX_HLK:
1850 case PAX_HRG:
1851 if (arcn->type == PAX_SLK)
1852 hd->typeflag = SYMTYPE;
1853 else
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));
1857 } else {
1858 strlcpy(hd->linkname, arcn->ln_name, sizeof(hd->linkname));
1859 }
1860 if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), term_char))
1861 goto out;
1862 break;
1863 case PAX_REG:
1864 case PAX_CTG:
1865 default:
1866 /*
1867 * file data with this type, set the padding
1868 */
1869 if (arcn->type == PAX_CTG)
1870 hd->typeflag = CONTTYPE;
1871 else
1872 hd->typeflag = REGTYPE;
1873 arcn->pad = TAR_PAD(arcn->sb.st_size);
1874 # ifdef LONG_OFF_T
1875 if (ul_oct((u_long)arcn->sb.st_size, hd->size,
1876 sizeof(hd->size), term_char)) {
1877 # else
1878 if (uqd_oct((u_quad_t)arcn->sb.st_size, hd->size,
1879 sizeof(hd->size), term_char)) {
1880 # endif
1881 paxwarn(1,"File is too long for pax %s",arcn->org_name);
1882 return(1);
1883 }
1884 break;
1885 }
1886
1887 strncpy(hd->magic, TMAGIC, TMAGLEN);
1888 strncpy(hd->version, TVERSION, TVERSLEN);
1889
1890 /*
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)....
1893 */
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)
1897 goto out;
1898 }
1899 if (uid_warn != arcn->sb.st_uid) {
1900 uid_warn = arcn->sb.st_uid;
1901 paxwarn(1,
1902 "Pax header field is too small for uid %lu, "
1903 "using nobody", (u_long)arcn->sb.st_uid);
1904 }
1905 if (ul_oct((u_long)uid_nobody, hd->uid, sizeof(hd->uid), term_char))
1906 goto out;
1907 }
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)
1911 goto out;
1912 }
1913 if (gid_warn != arcn->sb.st_gid) {
1914 gid_warn = arcn->sb.st_gid;
1915 paxwarn(1,
1916 "Pax header field is too small for gid %lu, "
1917 "using nobody", (u_long)arcn->sb.st_gid);
1918 }
1919 if (ul_oct((u_long)gid_nobody, hd->gid, sizeof(hd->gid), term_char))
1920 goto out;
1921 }
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))
1927 goto out;
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));
1930
1931 /*
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
1935 */
1936 if (ul_oct(pax_chksm(hdblk, sizeof(HD_USTAR)), hd->chksum,
1937 sizeof(hd->chksum), term_char))
1938 goto out;
1939 if (wr_rdbuf(hdblk, sizeof(HD_USTAR)) < 0)
1940 return(-1);
1941 if (wr_skip((off_t)(BLKMULT - sizeof(HD_USTAR))) < 0)
1942 return(-1);
1943 if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG))
1944 return(0);
1945 return(1);
1946
1947 out:
1948 /*
1949 * header field is out of range
1950 */
1951 paxwarn(1, "Pax header field is too small for %s", arcn->org_name);
1952 return(1);
1953 }
1954
1955 #if 0
1956 /*
1957 * name_split()
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 /
1961 * Return
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
1966 */
1967
1968 static char *
1969 name_split(char *name, int len)
1970 {
1971 char *start;
1972
1973 /*
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.
1976 */
1977 if (len <= TNMSZ)
1978 return(name);
1979 if (len > (TPFSZ + TNMSZ))
1980 return(NULL);
1981
1982 /*
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)
1987 */
1988 start = name + len - TNMSZ -1;
1989 while ((*start != '\0') && (*start != '/'))
1990 ++start;
1991
1992 /*
1993 * if we hit the end of the string, this name cannot be split, so we
1994 * cannot store this file.
1995 */
1996 if (*start == '\0')
1997 return(NULL);
1998 len = start - name;
1999
2000 /*
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.
2005 */
2006 if ((len >= TPFSZ) || (len == 0))
2007 return(NULL);
2008
2009 /*
2010 * ok have a split point, return it to the caller
2011 */
2012 return(start);
2013 }
2014 #endif /* if 0 */
2015
2016 static size_t
2017 expandname(char *buf, size_t len, char **gnu_name, const char *name, size_t name_len)
2018 {
2019 size_t nlen;
2020
2021 if (*gnu_name) {
2022 if ((nlen = strlcpy(buf, *gnu_name, len)) >= len)
2023 nlen = len - 1;
2024 free(*gnu_name);
2025 *gnu_name = NULL;
2026 } else {
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)
2031 nlen = name_len;
2032 } else {
2033 if ((nlen = strlcpy(buf, name, len)) >= len)
2034 nlen = len - 1;
2035 }
2036 }
2037 return(nlen);
2038 }