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