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