xref: /dragonfly/bin/pax/tar.c (revision 1de703da)
1 /*-
2  * Copyright (c) 1992 Keith Muller.
3  * Copyright (c) 1992, 1993
4  *	The Regents of the University of California.  All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * Keith Muller of the University of California, San Diego.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *	This product includes software developed by the University of
20  *	California, Berkeley and its contributors.
21  * 4. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  * @(#)tar.c	8.2 (Berkeley) 4/18/94
38  * $FreeBSD: src/bin/pax/tar.c,v 1.13.2.1 2001/08/01 05:03:12 obrien Exp $
39  * $DragonFly: src/bin/pax/tar.c,v 1.2 2003/06/17 04:22:50 dillon Exp $
40  */
41 
42 #include <sys/types.h>
43 #include <sys/time.h>
44 #include <sys/stat.h>
45 #include <string.h>
46 #include <stdio.h>
47 #include <unistd.h>
48 #include <stdlib.h>
49 #include "pax.h"
50 #include "extern.h"
51 #include "tar.h"
52 
53 /*
54  * Routines for reading, writing and header identify of various versions of tar
55  */
56 
57 static u_long tar_chksm __P((register char *, register int));
58 static char *name_split __P((register char *, register int));
59 static int ul_oct __P((u_long, register char *, register int, int));
60 #ifndef NET2_STAT
61 static int uqd_oct __P((u_quad_t, register char *, register int, int));
62 #endif
63 
64 /*
65  * Routines common to all versions of tar
66  */
67 
68 static int tar_nodir;			/* do not write dirs under old tar */
69 
70 /*
71  * tar_endwr()
72  *	add the tar trailer of two null blocks
73  * Return:
74  *	0 if ok, -1 otherwise (what wr_skip returns)
75  */
76 
77 #ifdef __STDC__
78 int
79 tar_endwr(void)
80 #else
81 int
82 tar_endwr()
83 #endif
84 {
85 	return(wr_skip((off_t)(NULLCNT*BLKMULT)));
86 }
87 
88 /*
89  * tar_endrd()
90  *	no cleanup needed here, just return size of trailer (for append)
91  * Return:
92  *	size of trailer (2 * BLKMULT)
93  */
94 
95 #ifdef __STDC__
96 off_t
97 tar_endrd(void)
98 #else
99 off_t
100 tar_endrd()
101 #endif
102 {
103 	return((off_t)(NULLCNT*BLKMULT));
104 }
105 
106 /*
107  * tar_trail()
108  *	Called to determine if a header block is a valid trailer. We are passed
109  *	the block, the in_sync flag (which tells us we are in resync mode;
110  *	looking for a valid header), and cnt (which starts at zero) which is
111  *	used to count the number of empty blocks we have seen so far.
112  * Return:
113  *	0 if a valid trailer, -1 if not a valid trailer, or 1 if the block
114  *	could never contain a header.
115  */
116 
117 #ifdef __STDC__
118 int
119 tar_trail(register char *buf, register int in_resync, register int *cnt)
120 #else
121 int
122 tar_trail(buf, in_resync, cnt)
123 	register char *buf;
124 	register int in_resync;
125 	register int *cnt;
126 #endif
127 {
128 	register int i;
129 
130 	/*
131 	 * look for all zero, trailer is two consecutive blocks of zero
132 	 */
133 	for (i = 0; i < BLKMULT; ++i) {
134 		if (buf[i] != '\0')
135 			break;
136 	}
137 
138 	/*
139 	 * if not all zero it is not a trailer, but MIGHT be a header.
140 	 */
141 	if (i != BLKMULT)
142 		return(-1);
143 
144 	/*
145 	 * When given a zero block, we must be careful!
146 	 * If we are not in resync mode, check for the trailer. Have to watch
147 	 * out that we do not mis-identify file data as the trailer, so we do
148 	 * NOT try to id a trailer during resync mode. During resync mode we
149 	 * might as well throw this block out since a valid header can NEVER be
150 	 * a block of all 0 (we must have a valid file name).
151 	 */
152 	if (!in_resync && (++*cnt >= NULLCNT))
153 		return(0);
154 	return(1);
155 }
156 
157 /*
158  * ul_oct()
159  *	convert an unsigned long to an octal string. many oddball field
160  *	termination characters are used by the various versions of tar in the
161  *	different fields. term selects which kind to use. str is '0' padded
162  *	at the front to len. we are unable to use only one format as many old
163  *	tar readers are very cranky about this.
164  * Return:
165  *	0 if the number fit into the string, -1 otherwise
166  */
167 
168 #ifdef __STDC__
169 static int
170 ul_oct(u_long val, register char *str, register int len, int term)
171 #else
172 static int
173 ul_oct(val, str, len, term)
174 	u_long val;
175 	register char *str;
176 	register int len;
177 	int term;
178 #endif
179 {
180 	register char *pt;
181 
182 	/*
183 	 * term selects the appropriate character(s) for the end of the string
184 	 */
185 	pt = str + len - 1;
186 	switch(term) {
187 	case 3:
188 		*pt-- = '\0';
189 		break;
190 	case 2:
191 		*pt-- = ' ';
192 		*pt-- = '\0';
193 		break;
194 	case 1:
195 		*pt-- = ' ';
196 		break;
197 	case 0:
198 	default:
199 		*pt-- = '\0';
200 		*pt-- = ' ';
201 		break;
202 	}
203 
204 	/*
205 	 * convert and blank pad if there is space
206 	 */
207 	while (pt >= str) {
208 		*pt-- = '0' + (char)(val & 0x7);
209 		if ((val = val >> 3) == (u_long)0)
210 			break;
211 	}
212 
213 	while (pt >= str)
214 		*pt-- = '0';
215 	if (val != (u_long)0)
216 		return(-1);
217 	return(0);
218 }
219 
220 #ifndef NET2_STAT
221 /*
222  * uqd_oct()
223  *	convert an u_quad_t to an octal string. one of many oddball field
224  *	termination characters are used by the various versions of tar in the
225  *	different fields. term selects which kind to use. str is '0' padded
226  *	at the front to len. we are unable to use only one format as many old
227  *	tar readers are very cranky about this.
228  * Return:
229  *	0 if the number fit into the string, -1 otherwise
230  */
231 
232 #ifdef __STDC__
233 static int
234 uqd_oct(u_quad_t val, register char *str, register int len, int term)
235 #else
236 static int
237 uqd_oct(val, str, len, term)
238 	u_quad_t val;
239 	register char *str;
240 	register int len;
241 	int term;
242 #endif
243 {
244 	register char *pt;
245 
246 	/*
247 	 * term selects the appropriate character(s) for the end of the string
248 	 */
249 	pt = str + len - 1;
250 	switch(term) {
251 	case 3:
252 		*pt-- = '\0';
253 		break;
254 	case 2:
255 		*pt-- = ' ';
256 		*pt-- = '\0';
257 		break;
258 	case 1:
259 		*pt-- = ' ';
260 		break;
261 	case 0:
262 	default:
263 		*pt-- = '\0';
264 		*pt-- = ' ';
265 		break;
266 	}
267 
268 	/*
269 	 * convert and blank pad if there is space
270 	 */
271 	while (pt >= str) {
272 		*pt-- = '0' + (char)(val & 0x7);
273 		if ((val = val >> 3) == 0)
274 			break;
275 	}
276 
277 	while (pt >= str)
278 		*pt-- = '0';
279 	if (val != (u_quad_t)0)
280 		return(-1);
281 	return(0);
282 }
283 #endif
284 
285 /*
286  * tar_chksm()
287  *	calculate the checksum for a tar block counting the checksum field as
288  *	all blanks (BLNKSUM is that value pre-calculated, the sum of 8 blanks).
289  *	NOTE: we use len to short circuit summing 0's on write since we ALWAYS
290  *	pad headers with 0.
291  * Return:
292  *	unsigned long checksum
293  */
294 
295 #ifdef __STDC__
296 static u_long
297 tar_chksm(register char *blk, register int len)
298 #else
299 static u_long
300 tar_chksm(blk, len)
301 	register char *blk;
302 	register int len;
303 #endif
304 {
305 	register char *stop;
306 	register char *pt;
307 	u_long chksm = BLNKSUM;	/* initial value is checksum field sum */
308 
309 	/*
310 	 * add the part of the block before the checksum field
311 	 */
312 	pt = blk;
313 	stop = blk + CHK_OFFSET;
314 	while (pt < stop)
315 		chksm += (u_long)(*pt++ & 0xff);
316 	/*
317 	 * move past the checksum field and keep going, spec counts the
318 	 * checksum field as the sum of 8 blanks (which is pre-computed as
319 	 * BLNKSUM).
320 	 * ASSUMED: len is greater than CHK_OFFSET. (len is where our 0 padding
321 	 * starts, no point in summing zero's)
322 	 */
323 	pt += CHK_LEN;
324 	stop = blk + len;
325 	while (pt < stop)
326 		chksm += (u_long)(*pt++ & 0xff);
327 	return(chksm);
328 }
329 
330 /*
331  * Routines for old BSD style tar (also made portable to sysV tar)
332  */
333 
334 /*
335  * tar_id()
336  *	determine if a block given to us is a valid tar header (and not a USTAR
337  *	header). We have to be on the lookout for those pesky blocks of	all
338  *	zero's.
339  * Return:
340  *	0 if a tar header, -1 otherwise
341  */
342 
343 #ifdef __STDC__
344 int
345 tar_id(register char *blk, int size)
346 #else
347 int
348 tar_id(blk, size)
349 	register char *blk;
350 	int size;
351 #endif
352 {
353 	register HD_TAR *hd;
354 	register HD_USTAR *uhd;
355 
356 	if (size < BLKMULT)
357 		return(-1);
358 	hd = (HD_TAR *)blk;
359 	uhd = (HD_USTAR *)blk;
360 
361 	/*
362 	 * check for block of zero's first, a simple and fast test, then make
363 	 * sure this is not a ustar header by looking for the ustar magic
364 	 * cookie. We should use TMAGLEN, but some USTAR archive programs are
365 	 * wrong and create archives missing the \0. Last we check the
366 	 * checksum. If this is ok we have to assume it is a valid header.
367 	 */
368 	if (hd->name[0] == '\0')
369 		return(-1);
370 	if (strncmp(uhd->magic, TMAGIC, TMAGLEN - 1) == 0)
371 		return(-1);
372 	if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != tar_chksm(blk,BLKMULT))
373 		return(-1);
374 	return(0);
375 }
376 
377 /*
378  * tar_opt()
379  *	handle tar format specific -o options
380  * Return:
381  *	0 if ok -1 otherwise
382  */
383 
384 #ifdef __STDC__
385 int
386 tar_opt(void)
387 #else
388 int
389 tar_opt()
390 #endif
391 {
392 	OPLIST *opt;
393 
394 	while ((opt = opt_next()) != NULL) {
395 		if (strcmp(opt->name, TAR_OPTION) ||
396 		    strcmp(opt->value, TAR_NODIR)) {
397 			paxwarn(1, "Unknown tar format -o option/value pair %s=%s",
398 			    opt->name, opt->value);
399 			paxwarn(1,"%s=%s is the only supported tar format option",
400 			    TAR_OPTION, TAR_NODIR);
401 			return(-1);
402 		}
403 
404 		/*
405 		 * we only support one option, and only when writing
406 		 */
407 		if ((act != APPND) && (act != ARCHIVE)) {
408 			paxwarn(1, "%s=%s is only supported when writing.",
409 			    opt->name, opt->value);
410 			return(-1);
411 		}
412 		tar_nodir = 1;
413 	}
414 	return(0);
415 }
416 
417 
418 /*
419  * tar_rd()
420  *	extract the values out of block already determined to be a tar header.
421  *	store the values in the ARCHD parameter.
422  * Return:
423  *	0
424  */
425 
426 #ifdef __STDC__
427 int
428 tar_rd(register ARCHD *arcn, register char *buf)
429 #else
430 int
431 tar_rd(arcn, buf)
432 	register ARCHD *arcn;
433 	register char *buf;
434 #endif
435 {
436 	register HD_TAR *hd;
437 	register char *pt;
438 
439 	/*
440 	 * we only get proper sized buffers passed to us
441 	 */
442 	if (tar_id(buf, BLKMULT) < 0)
443 		return(-1);
444 	arcn->org_name = arcn->name;
445 	arcn->sb.st_nlink = 1;
446 	arcn->pat = NULL;
447 
448 	/*
449 	 * copy out the name and values in the stat buffer
450 	 */
451 	hd = (HD_TAR *)buf;
452 	arcn->nlen = l_strncpy(arcn->name, hd->name, sizeof(arcn->name) - 1);
453 	arcn->name[arcn->nlen] = '\0';
454 	arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode,sizeof(hd->mode),OCT) &
455 	    0xfff);
456 	arcn->sb.st_uid = (uid_t)asc_ul(hd->uid, sizeof(hd->uid), OCT);
457 	arcn->sb.st_gid = (gid_t)asc_ul(hd->gid, sizeof(hd->gid), OCT);
458 #ifdef NET2_STAT
459 	arcn->sb.st_size = (off_t)asc_ul(hd->size, sizeof(hd->size), OCT);
460 #else
461 	arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT);
462 #endif
463 	arcn->sb.st_mtime = (time_t)asc_ul(hd->mtime, sizeof(hd->mtime), OCT);
464 	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
465 
466 	/*
467 	 * have to look at the last character, it may be a '/' and that is used
468 	 * to encode this as a directory
469 	 */
470 	pt = &(arcn->name[arcn->nlen - 1]);
471 	arcn->pad = 0;
472 	arcn->skip = 0;
473 	switch(hd->linkflag) {
474 	case SYMTYPE:
475 		/*
476 		 * symbolic link, need to get the link name and set the type in
477 		 * the st_mode so -v printing will look correct.
478 		 */
479 		arcn->type = PAX_SLK;
480 		arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname,
481 			sizeof(arcn->ln_name) - 1);
482 		arcn->ln_name[arcn->ln_nlen] = '\0';
483 		arcn->sb.st_mode |= S_IFLNK;
484 		break;
485 	case LNKTYPE:
486 		/*
487 		 * hard link, need to get the link name, set the type in the
488 		 * st_mode and st_nlink so -v printing will look better.
489 		 */
490 		arcn->type = PAX_HLK;
491 		arcn->sb.st_nlink = 2;
492 		arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname,
493 			sizeof(arcn->ln_name) - 1);
494 		arcn->ln_name[arcn->ln_nlen] = '\0';
495 
496 		/*
497 		 * no idea of what type this thing really points at, but
498 		 * we set something for printing only.
499 		 */
500 		arcn->sb.st_mode |= S_IFREG;
501 		break;
502 	case DIRTYPE:
503 		/*
504 		 * It is a directory, set the mode for -v printing
505 		 */
506 		arcn->type = PAX_DIR;
507 		arcn->sb.st_mode |= S_IFDIR;
508 		arcn->sb.st_nlink = 2;
509 		arcn->ln_name[0] = '\0';
510 		arcn->ln_nlen = 0;
511 		break;
512 	case AREGTYPE:
513 	case REGTYPE:
514 	default:
515 		/*
516 		 * If we have a trailing / this is a directory and NOT a file.
517 		 */
518 		arcn->ln_name[0] = '\0';
519 		arcn->ln_nlen = 0;
520 		if (*pt == '/') {
521 			/*
522 			 * it is a directory, set the mode for -v printing
523 			 */
524 			arcn->type = PAX_DIR;
525 			arcn->sb.st_mode |= S_IFDIR;
526 			arcn->sb.st_nlink = 2;
527 		} else {
528 			/*
529 			 * have a file that will be followed by data. Set the
530 			 * skip value to the size field and calculate the size
531 			 * of the padding.
532 			 */
533 			arcn->type = PAX_REG;
534 			arcn->sb.st_mode |= S_IFREG;
535 			arcn->pad = TAR_PAD(arcn->sb.st_size);
536 			arcn->skip = arcn->sb.st_size;
537 		}
538 		break;
539 	}
540 
541 	/*
542 	 * strip off any trailing slash.
543 	 */
544 	if (*pt == '/') {
545 		*pt = '\0';
546 		--arcn->nlen;
547 	}
548 	return(0);
549 }
550 
551 /*
552  * tar_wr()
553  *	write a tar header for the file specified in the ARCHD to the archive.
554  *	Have to check for file types that cannot be stored and file names that
555  *	are too long. Be careful of the term (last arg) to ul_oct, each field
556  *	of tar has it own spec for the termination character(s).
557  *	ASSUMED: space after header in header block is zero filled
558  * Return:
559  *	0 if file has data to be written after the header, 1 if file has NO
560  *	data to write after the header, -1 if archive write failed
561  */
562 
563 #ifdef __STDC__
564 int
565 tar_wr(register ARCHD *arcn)
566 #else
567 int
568 tar_wr(arcn)
569 	register ARCHD *arcn;
570 #endif
571 {
572 	register HD_TAR *hd;
573 	int len;
574 	char hdblk[sizeof(HD_TAR)];
575 
576 	/*
577 	 * check for those file system types which tar cannot store
578 	 */
579 	switch(arcn->type) {
580 	case PAX_DIR:
581 		/*
582 		 * user asked that dirs not be written to the archive
583 		 */
584 		if (tar_nodir)
585 			return(1);
586 		break;
587 	case PAX_CHR:
588 		paxwarn(1, "Tar cannot archive a character device %s",
589 		    arcn->org_name);
590 		return(1);
591 	case PAX_BLK:
592 		paxwarn(1, "Tar cannot archive a block device %s", arcn->org_name);
593 		return(1);
594 	case PAX_SCK:
595 		paxwarn(1, "Tar cannot archive a socket %s", arcn->org_name);
596 		return(1);
597 	case PAX_FIF:
598 		paxwarn(1, "Tar cannot archive a fifo %s", arcn->org_name);
599 		return(1);
600 	case PAX_SLK:
601 	case PAX_HLK:
602 	case PAX_HRG:
603 		if (arcn->ln_nlen > sizeof(hd->linkname)) {
604 			paxwarn(1,"Link name too long for tar %s", arcn->ln_name);
605 			return(1);
606 		}
607 		break;
608 	case PAX_REG:
609 	case PAX_CTG:
610 	default:
611 		break;
612 	}
613 
614 	/*
615 	 * check file name len, remember extra char for dirs (the / at the end)
616 	 */
617 	len = arcn->nlen;
618 	if (arcn->type == PAX_DIR)
619 		++len;
620 	if (len >= sizeof(hd->name)) {
621 		paxwarn(1, "File name too long for tar %s", arcn->name);
622 		return(1);
623 	}
624 
625 	/*
626 	 * copy the data out of the ARCHD into the tar header based on the type
627 	 * of the file. Remember many tar readers want the unused fields to be
628 	 * padded with zero. We set the linkflag field (type), the linkname
629 	 * (or zero if not used),the size, and set the padding (if any) to be
630 	 * added after the file data (0 for all other types, as they only have
631 	 * a header)
632 	 */
633 	hd = (HD_TAR *)hdblk;
634 	l_strncpy(hd->name, arcn->name, sizeof(hd->name) - 1);
635 	hd->name[sizeof(hd->name) - 1] = '\0';
636 	arcn->pad = 0;
637 
638 	if (arcn->type == PAX_DIR) {
639 		/*
640 		 * directories are the same as files, except have a filename
641 		 * that ends with a /, we add the slash here. No data follows,
642 		 * dirs, so no pad.
643 		 */
644 		hd->linkflag = AREGTYPE;
645 		memset(hd->linkname, 0, sizeof(hd->linkname));
646 		hd->name[len-1] = '/';
647 		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1))
648 			goto out;
649 	} else if (arcn->type == PAX_SLK) {
650 		/*
651 		 * no data follows this file, so no pad
652 		 */
653 		hd->linkflag = SYMTYPE;
654 		l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1);
655 		hd->linkname[sizeof(hd->linkname) - 1] = '\0';
656 		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1))
657 			goto out;
658 	} else if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) {
659 		/*
660 		 * no data follows this file, so no pad
661 		 */
662 		hd->linkflag = LNKTYPE;
663 		l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1);
664 		hd->linkname[sizeof(hd->linkname) - 1] = '\0';
665 		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1))
666 			goto out;
667 	} else {
668 		/*
669 		 * data follows this file, so set the pad
670 		 */
671 		hd->linkflag = AREGTYPE;
672 		memset(hd->linkname, 0, sizeof(hd->linkname));
673 #		ifdef NET2_STAT
674 		if (ul_oct((u_long)arcn->sb.st_size, hd->size,
675 		    sizeof(hd->size), 1)) {
676 #		else
677 		if (uqd_oct((u_quad_t)arcn->sb.st_size, hd->size,
678 		    sizeof(hd->size), 1)) {
679 #		endif
680 			paxwarn(1,"File is too large for tar %s", arcn->org_name);
681 			return(1);
682 		}
683 		arcn->pad = TAR_PAD(arcn->sb.st_size);
684 	}
685 
686 	/*
687 	 * copy those fields that are independent of the type
688 	 */
689 	if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 0) ||
690 	    ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 0) ||
691 	    ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 0) ||
692 	    ul_oct((u_long)arcn->sb.st_mtime, hd->mtime, sizeof(hd->mtime), 1))
693 		goto out;
694 
695 	/*
696 	 * calculate and add the checksum, then write the header. A return of
697 	 * 0 tells the caller to now write the file data, 1 says no data needs
698 	 * to be written
699 	 */
700 	if (ul_oct(tar_chksm(hdblk, sizeof(HD_TAR)), hd->chksum,
701 	    sizeof(hd->chksum), 3))
702 		goto out;
703 	if (wr_rdbuf(hdblk, sizeof(HD_TAR)) < 0)
704 		return(-1);
705 	if (wr_skip((off_t)(BLKMULT - sizeof(HD_TAR))) < 0)
706 		return(-1);
707 	if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG))
708 		return(0);
709 	return(1);
710 
711     out:
712 	/*
713 	 * header field is out of range
714 	 */
715 	paxwarn(1, "Tar header field is too small for %s", arcn->org_name);
716 	return(1);
717 }
718 
719 /*
720  * Routines for POSIX ustar
721  */
722 
723 /*
724  * ustar_strd()
725  *	initialization for ustar read
726  * Return:
727  *	0 if ok, -1 otherwise
728  */
729 
730 #ifdef __STDC__
731 int
732 ustar_strd(void)
733 #else
734 int
735 ustar_strd()
736 #endif
737 {
738 	if ((usrtb_start() < 0) || (grptb_start() < 0))
739 		return(-1);
740 	return(0);
741 }
742 
743 /*
744  * ustar_stwr()
745  *	initialization for ustar write
746  * Return:
747  *	0 if ok, -1 otherwise
748  */
749 
750 #ifdef __STDC__
751 int
752 ustar_stwr(void)
753 #else
754 int
755 ustar_stwr()
756 #endif
757 {
758 	if ((uidtb_start() < 0) || (gidtb_start() < 0))
759 		return(-1);
760 	return(0);
761 }
762 
763 /*
764  * ustar_id()
765  *	determine if a block given to us is a valid ustar header. We have to
766  *	be on the lookout for those pesky blocks of all zero's
767  * Return:
768  *	0 if a ustar header, -1 otherwise
769  */
770 
771 #ifdef __STDC__
772 int
773 ustar_id(char *blk, int size)
774 #else
775 int
776 ustar_id(blk, size)
777 	char *blk;
778 	int size;
779 #endif
780 {
781 	register HD_USTAR *hd;
782 
783 	if (size < BLKMULT)
784 		return(-1);
785 	hd = (HD_USTAR *)blk;
786 
787 	/*
788 	 * check for block of zero's first, a simple and fast test then check
789 	 * ustar magic cookie. We should use TMAGLEN, but some USTAR archive
790 	 * programs are fouled up and create archives missing the \0. Last we
791 	 * check the checksum. If ok we have to assume it is a valid header.
792 	 */
793 	if (hd->name[0] == '\0')
794 		return(-1);
795 	if (strncmp(hd->magic, TMAGIC, TMAGLEN - 1) != 0)
796 		return(-1);
797 	if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != tar_chksm(blk,BLKMULT))
798 		return(-1);
799 	return(0);
800 }
801 
802 /*
803  * ustar_rd()
804  *	extract the values out of block already determined to be a ustar header.
805  *	store the values in the ARCHD parameter.
806  * Return:
807  *	0
808  */
809 
810 #ifdef __STDC__
811 int
812 ustar_rd(register ARCHD *arcn, register char *buf)
813 #else
814 int
815 ustar_rd(arcn, buf)
816 	register ARCHD *arcn;
817 	register char *buf;
818 #endif
819 {
820 	register HD_USTAR *hd;
821 	register char *dest;
822 	register int cnt = 0;
823 	dev_t devmajor;
824 	dev_t devminor;
825 
826 	/*
827 	 * we only get proper sized buffers
828 	 */
829 	if (ustar_id(buf, BLKMULT) < 0)
830 		return(-1);
831 	arcn->org_name = arcn->name;
832 	arcn->sb.st_nlink = 1;
833 	arcn->pat = NULL;
834 	arcn->nlen = 0;
835 	hd = (HD_USTAR *)buf;
836 
837 	/*
838 	 * see if the filename is split into two parts. if, so joint the parts.
839 	 * we copy the prefix first and add a / between the prefix and name.
840 	 */
841 	dest = arcn->name;
842 	if (*(hd->prefix) != '\0') {
843 		cnt = l_strncpy(dest, hd->prefix, sizeof(arcn->name) - 2);
844 		dest += cnt;
845 		*dest++ = '/';
846 		cnt++;
847 	}
848 	arcn->nlen = cnt + l_strncpy(dest, hd->name, sizeof(arcn->name) - cnt);
849 	arcn->name[arcn->nlen] = '\0';
850 
851 	/*
852 	 * follow the spec to the letter. we should only have mode bits, strip
853 	 * off all other crud we may be passed.
854 	 */
855 	arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode, sizeof(hd->mode), OCT) &
856 	    0xfff);
857 #ifdef NET2_STAT
858 	arcn->sb.st_size = (off_t)asc_ul(hd->size, sizeof(hd->size), OCT);
859 #else
860 	arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT);
861 #endif
862 	arcn->sb.st_mtime = (time_t)asc_ul(hd->mtime, sizeof(hd->mtime), OCT);
863 	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
864 
865 	/*
866 	 * If we can find the ascii names for gname and uname in the password
867 	 * and group files we will use the uid's and gid they bind. Otherwise
868 	 * we use the uid and gid values stored in the header. (This is what
869 	 * the POSIX spec wants).
870 	 */
871 	hd->gname[sizeof(hd->gname) - 1] = '\0';
872 	if (gid_name(hd->gname, &(arcn->sb.st_gid)) < 0)
873 		arcn->sb.st_gid = (gid_t)asc_ul(hd->gid, sizeof(hd->gid), OCT);
874 	hd->uname[sizeof(hd->uname) - 1] = '\0';
875 	if (uid_name(hd->uname, &(arcn->sb.st_uid)) < 0)
876 		arcn->sb.st_uid = (uid_t)asc_ul(hd->uid, sizeof(hd->uid), OCT);
877 
878 	/*
879 	 * set the defaults, these may be changed depending on the file type
880 	 */
881 	arcn->ln_name[0] = '\0';
882 	arcn->ln_nlen = 0;
883 	arcn->pad = 0;
884 	arcn->skip = 0;
885 	arcn->sb.st_rdev = (dev_t)0;
886 
887 	/*
888 	 * set the mode and PAX type according to the typeflag in the header
889 	 */
890 	switch(hd->typeflag) {
891 	case FIFOTYPE:
892 		arcn->type = PAX_FIF;
893 		arcn->sb.st_mode |= S_IFIFO;
894 		break;
895 	case DIRTYPE:
896 		arcn->type = PAX_DIR;
897 		arcn->sb.st_mode |= S_IFDIR;
898 		arcn->sb.st_nlink = 2;
899 
900 		/*
901 		 * Some programs that create ustar archives append a '/'
902 		 * to the pathname for directories. This clearly violates
903 		 * ustar specs, but we will silently strip it off anyway.
904 		 */
905 		if (arcn->name[arcn->nlen - 1] == '/')
906 			arcn->name[--arcn->nlen] = '\0';
907 		break;
908 	case BLKTYPE:
909 	case CHRTYPE:
910 		/*
911 		 * this type requires the rdev field to be set.
912 		 */
913 		if (hd->typeflag == BLKTYPE) {
914 			arcn->type = PAX_BLK;
915 			arcn->sb.st_mode |= S_IFBLK;
916 		} else {
917 			arcn->type = PAX_CHR;
918 			arcn->sb.st_mode |= S_IFCHR;
919 		}
920 		devmajor = (dev_t)asc_ul(hd->devmajor,sizeof(hd->devmajor),OCT);
921 		devminor = (dev_t)asc_ul(hd->devminor,sizeof(hd->devminor),OCT);
922 		arcn->sb.st_rdev = TODEV(devmajor, devminor);
923 		break;
924 	case SYMTYPE:
925 	case LNKTYPE:
926 		if (hd->typeflag == SYMTYPE) {
927 			arcn->type = PAX_SLK;
928 			arcn->sb.st_mode |= S_IFLNK;
929 		} else {
930 			arcn->type = PAX_HLK;
931 			/*
932 			 * so printing looks better
933 			 */
934 			arcn->sb.st_mode |= S_IFREG;
935 			arcn->sb.st_nlink = 2;
936 		}
937 		/*
938 		 * copy the link name
939 		 */
940 		arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname,
941 			sizeof(arcn->ln_name) - 1);
942 		arcn->ln_name[arcn->ln_nlen] = '\0';
943 		break;
944 	case CONTTYPE:
945 	case AREGTYPE:
946 	case REGTYPE:
947 	default:
948 		/*
949 		 * these types have file data that follows. Set the skip and
950 		 * pad fields.
951 		 */
952 		arcn->type = PAX_REG;
953 		arcn->pad = TAR_PAD(arcn->sb.st_size);
954 		arcn->skip = arcn->sb.st_size;
955 		arcn->sb.st_mode |= S_IFREG;
956 		break;
957 	}
958 	return(0);
959 }
960 
961 /*
962  * ustar_wr()
963  *	write a ustar header for the file specified in the ARCHD to the archive
964  *	Have to check for file types that cannot be stored and file names that
965  *	are too long. Be careful of the term (last arg) to ul_oct, we only use
966  *	'\0' for the termination character (this is different than picky tar)
967  *	ASSUMED: space after header in header block is zero filled
968  * Return:
969  *	0 if file has data to be written after the header, 1 if file has NO
970  *	data to write after the header, -1 if archive write failed
971  */
972 
973 #ifdef __STDC__
974 int
975 ustar_wr(register ARCHD *arcn)
976 #else
977 int
978 ustar_wr(arcn)
979 	register ARCHD *arcn;
980 #endif
981 {
982 	register HD_USTAR *hd;
983 	register char *pt;
984 	char hdblk[sizeof(HD_USTAR)];
985 
986 	/*
987 	 * check for those file system types ustar cannot store
988 	 */
989 	if (arcn->type == PAX_SCK) {
990 		paxwarn(1, "Ustar cannot archive a socket %s", arcn->org_name);
991 		return(1);
992 	}
993 
994 	/*
995 	 * check the length of the linkname
996 	 */
997 	if (((arcn->type == PAX_SLK) || (arcn->type == PAX_HLK) ||
998 	    (arcn->type == PAX_HRG)) && (arcn->ln_nlen >= sizeof(hd->linkname))){
999 		paxwarn(1, "Link name too long for ustar %s", arcn->ln_name);
1000 		return(1);
1001 	}
1002 
1003 	/*
1004 	 * split the path name into prefix and name fields (if needed). if
1005 	 * pt != arcn->name, the name has to be split
1006 	 */
1007 	if ((pt = name_split(arcn->name, arcn->nlen)) == NULL) {
1008 		paxwarn(1, "File name too long for ustar %s", arcn->name);
1009 		return(1);
1010 	}
1011 	hd = (HD_USTAR *)hdblk;
1012 	arcn->pad = 0L;
1013 
1014 	/*
1015 	 * split the name, or zero out the prefix
1016 	 */
1017 	if (pt != arcn->name) {
1018 		/*
1019 		 * name was split, pt points at the / where the split is to
1020 		 * occur, we remove the / and copy the first part to the prefix
1021 		 */
1022 		*pt = '\0';
1023 		l_strncpy(hd->prefix, arcn->name, sizeof(hd->prefix) - 1);
1024 		*pt++ = '/';
1025 	} else
1026 		memset(hd->prefix, 0, sizeof(hd->prefix));
1027 
1028 	/*
1029 	 * copy the name part. this may be the whole path or the part after
1030 	 * the prefix
1031 	 */
1032 	l_strncpy(hd->name, pt, sizeof(hd->name) - 1);
1033 	hd->name[sizeof(hd->name) - 1] = '\0';
1034 
1035 	/*
1036 	 * set the fields in the header that are type dependent
1037 	 */
1038 	switch(arcn->type) {
1039 	case PAX_DIR:
1040 		hd->typeflag = DIRTYPE;
1041 		memset(hd->linkname, 0, sizeof(hd->linkname));
1042 		memset(hd->devmajor, 0, sizeof(hd->devmajor));
1043 		memset(hd->devminor, 0, sizeof(hd->devminor));
1044 		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
1045 			goto out;
1046 		break;
1047 	case PAX_CHR:
1048 	case PAX_BLK:
1049 		if (arcn->type == PAX_CHR)
1050 			hd->typeflag = CHRTYPE;
1051 		else
1052 			hd->typeflag = BLKTYPE;
1053 		memset(hd->linkname, 0, sizeof(hd->linkname));
1054 		if (ul_oct((u_long)MAJOR(arcn->sb.st_rdev), hd->devmajor,
1055 		   sizeof(hd->devmajor), 3) ||
1056 		   ul_oct((u_long)MINOR(arcn->sb.st_rdev), hd->devminor,
1057 		   sizeof(hd->devminor), 3) ||
1058 		   ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
1059 			goto out;
1060 		break;
1061 	case PAX_FIF:
1062 		hd->typeflag = FIFOTYPE;
1063 		memset(hd->linkname, 0, sizeof(hd->linkname));
1064 		memset(hd->devmajor, 0, sizeof(hd->devmajor));
1065 		memset(hd->devminor, 0, sizeof(hd->devminor));
1066 		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
1067 			goto out;
1068 		break;
1069 	case PAX_SLK:
1070 	case PAX_HLK:
1071 	case PAX_HRG:
1072 		if (arcn->type == PAX_SLK)
1073 			hd->typeflag = SYMTYPE;
1074 		else
1075 			hd->typeflag = LNKTYPE;
1076 		l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1);
1077 		hd->linkname[sizeof(hd->linkname) - 1] = '\0';
1078 		memset(hd->devmajor, 0, sizeof(hd->devmajor));
1079 		memset(hd->devminor, 0, sizeof(hd->devminor));
1080 		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
1081 			goto out;
1082 		break;
1083 	case PAX_REG:
1084 	case PAX_CTG:
1085 	default:
1086 		/*
1087 		 * file data with this type, set the padding
1088 		 */
1089 		if (arcn->type == PAX_CTG)
1090 			hd->typeflag = CONTTYPE;
1091 		else
1092 			hd->typeflag = REGTYPE;
1093 		memset(hd->linkname, 0, sizeof(hd->linkname));
1094 		memset(hd->devmajor, 0, sizeof(hd->devmajor));
1095 		memset(hd->devminor, 0, sizeof(hd->devminor));
1096 		arcn->pad = TAR_PAD(arcn->sb.st_size);
1097 #		ifdef NET2_STAT
1098 		if (ul_oct((u_long)arcn->sb.st_size, hd->size,
1099 		    sizeof(hd->size), 3)) {
1100 #		else
1101 		if (uqd_oct((u_quad_t)arcn->sb.st_size, hd->size,
1102 		    sizeof(hd->size), 3)) {
1103 #		endif
1104 			paxwarn(1,"File is too long for ustar %s",arcn->org_name);
1105 			return(1);
1106 		}
1107 		break;
1108 	}
1109 
1110 	l_strncpy(hd->magic, TMAGIC, TMAGLEN);
1111 	l_strncpy(hd->version, TVERSION, TVERSLEN);
1112 
1113 	/*
1114 	 * set the remaining fields. Some versions want all 16 bits of mode
1115 	 * we better humor them (they really do not meet spec though)....
1116 	 */
1117 	if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 3) ||
1118 	    ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 3)  ||
1119 	    ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3) ||
1120 	    ul_oct((u_long)arcn->sb.st_mtime,hd->mtime,sizeof(hd->mtime),3))
1121 		goto out;
1122 	l_strncpy(hd->uname,name_uid(arcn->sb.st_uid, 0),sizeof(hd->uname));
1123 	l_strncpy(hd->gname,name_gid(arcn->sb.st_gid, 0),sizeof(hd->gname));
1124 
1125 	/*
1126 	 * calculate and store the checksum write the header to the archive
1127 	 * return 0 tells the caller to now write the file data, 1 says no data
1128 	 * needs to be written
1129 	 */
1130 	if (ul_oct(tar_chksm(hdblk, sizeof(HD_USTAR)), hd->chksum,
1131 	   sizeof(hd->chksum), 3))
1132 		goto out;
1133 	if (wr_rdbuf(hdblk, sizeof(HD_USTAR)) < 0)
1134 		return(-1);
1135 	if (wr_skip((off_t)(BLKMULT - sizeof(HD_USTAR))) < 0)
1136 		return(-1);
1137 	if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG))
1138 		return(0);
1139 	return(1);
1140 
1141     out:
1142     	/*
1143 	 * header field is out of range
1144 	 */
1145 	paxwarn(1, "Ustar header field is too small for %s", arcn->org_name);
1146 	return(1);
1147 }
1148 
1149 /*
1150  * name_split()
1151  *	see if the name has to be split for storage in a ustar header. We try
1152  *	to fit the entire name in the name field without splitting if we can.
1153  *	The split point is always at a /
1154  * Return
1155  *	character pointer to split point (always the / that is to be removed
1156  *	if the split is not needed, the points is set to the start of the file
1157  *	name (it would violate the spec to split there). A NULL is returned if
1158  *	the file name is too long
1159  */
1160 
1161 #ifdef __STDC__
1162 static char *
1163 name_split(register char *name, register int len)
1164 #else
1165 static char *
1166 name_split(name, len)
1167 	register char *name;
1168 	register int len;
1169 #endif
1170 {
1171 	register char *start;
1172 
1173 	/*
1174 	 * check to see if the file name is small enough to fit in the name
1175 	 * field. if so just return a pointer to the name.
1176 	 */
1177 	if (len < TNMSZ)
1178 		return(name);
1179 	if (len > (TPFSZ + TNMSZ))
1180 		return(NULL);
1181 
1182 	/*
1183 	 * we start looking at the biggest sized piece that fits in the name
1184 	 * field. We walk forward looking for a slash to split at. The idea is
1185 	 * to find the biggest piece to fit in the name field (or the smallest
1186 	 * prefix we can find)
1187 	 */
1188 	start = name + len - TNMSZ;
1189 	while ((*start != '\0') && (*start != '/'))
1190 		++start;
1191 
1192 	/*
1193 	 * if we hit the end of the string, this name cannot be split, so we
1194 	 * cannot store this file.
1195 	 */
1196 	if (*start == '\0')
1197 		return(NULL);
1198 	len = start - name;
1199 
1200 	/*
1201 	 * NOTE: /str where the length of str == TNMSZ can not be stored under
1202 	 * the p1003.1-1990 spec for ustar. We could force a prefix of / and
1203 	 * the file would then expand on extract to //str. The len == 0 below
1204 	 * makes this special case follow the spec to the letter.
1205 	 */
1206 	if ((len >= TPFSZ) || (len == 0))
1207 		return(NULL);
1208 
1209 	/*
1210 	 * ok have a split point, return it to the caller
1211 	 */
1212 	return(start);
1213 }
1214