tar.c revision 85618
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 85618 2001-10-28 02:51:43Z dillon $";
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 '0' 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-- = '0';
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 '0' 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-- = '0';
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(arcn->name) - 1);
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#ifdef NET2_STAT
463	arcn->sb.st_size = (off_t)asc_ul(hd->size, sizeof(hd->size), OCT);
464	arcn->sb.st_mtime = (time_t)asc_ul(hd->mtime, sizeof(hd->mtime), OCT);
465#else
466	arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT);
467	arcn->sb.st_mtime = (time_t)asc_uqd(hd->mtime, sizeof(hd->mtime), OCT);
468#endif
469	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
470
471	/*
472	 * have to look at the last character, it may be a '/' and that is used
473	 * to encode this as a directory
474	 */
475	pt = &(arcn->name[arcn->nlen - 1]);
476	arcn->pad = 0;
477	arcn->skip = 0;
478	switch(hd->linkflag) {
479	case SYMTYPE:
480		/*
481		 * symbolic link, need to get the link name and set the type in
482		 * the st_mode so -v printing will look correct.
483		 */
484		arcn->type = PAX_SLK;
485		arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname,
486			sizeof(arcn->ln_name) - 1);
487		arcn->ln_name[arcn->ln_nlen] = '\0';
488		arcn->sb.st_mode |= S_IFLNK;
489		break;
490	case LNKTYPE:
491		/*
492		 * hard link, need to get the link name, set the type in the
493		 * st_mode and st_nlink so -v printing will look better.
494		 */
495		arcn->type = PAX_HLK;
496		arcn->sb.st_nlink = 2;
497		arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname,
498			sizeof(arcn->ln_name) - 1);
499		arcn->ln_name[arcn->ln_nlen] = '\0';
500
501		/*
502		 * no idea of what type this thing really points at, but
503		 * we set something for printing only.
504		 */
505		arcn->sb.st_mode |= S_IFREG;
506		break;
507	case DIRTYPE:
508		/*
509		 * It is a directory, set the mode for -v printing
510		 */
511		arcn->type = PAX_DIR;
512		arcn->sb.st_mode |= S_IFDIR;
513		arcn->sb.st_nlink = 2;
514		arcn->ln_name[0] = '\0';
515		arcn->ln_nlen = 0;
516		break;
517	case AREGTYPE:
518	case REGTYPE:
519	default:
520		/*
521		 * If we have a trailing / this is a directory and NOT a file.
522		 */
523		arcn->ln_name[0] = '\0';
524		arcn->ln_nlen = 0;
525		if (*pt == '/') {
526			/*
527			 * it is a directory, set the mode for -v printing
528			 */
529			arcn->type = PAX_DIR;
530			arcn->sb.st_mode |= S_IFDIR;
531			arcn->sb.st_nlink = 2;
532		} else {
533			/*
534			 * have a file that will be followed by data. Set the
535			 * skip value to the size field and calculate the size
536			 * of the padding.
537			 */
538			arcn->type = PAX_REG;
539			arcn->sb.st_mode |= S_IFREG;
540			arcn->pad = TAR_PAD(arcn->sb.st_size);
541			arcn->skip = arcn->sb.st_size;
542		}
543		break;
544	}
545
546	/*
547	 * strip off any trailing slash.
548	 */
549	if (*pt == '/') {
550		*pt = '\0';
551		--arcn->nlen;
552	}
553	return(0);
554}
555
556/*
557 * tar_wr()
558 *	write a tar header for the file specified in the ARCHD to the archive.
559 *	Have to check for file types that cannot be stored and file names that
560 *	are too long. Be careful of the term (last arg) to ul_oct, each field
561 *	of tar has it own spec for the termination character(s).
562 *	ASSUMED: space after header in header block is zero filled
563 * Return:
564 *	0 if file has data to be written after the header, 1 if file has NO
565 *	data to write after the header, -1 if archive write failed
566 */
567
568#ifdef __STDC__
569int
570tar_wr(register ARCHD *arcn)
571#else
572int
573tar_wr(arcn)
574	register ARCHD *arcn;
575#endif
576{
577	register HD_TAR *hd;
578	int len;
579	char hdblk[sizeof(HD_TAR)];
580
581	/*
582	 * check for those file system types which tar cannot store
583	 */
584	switch(arcn->type) {
585	case PAX_DIR:
586		/*
587		 * user asked that dirs not be written to the archive
588		 */
589		if (tar_nodir)
590			return(1);
591		break;
592	case PAX_CHR:
593		paxwarn(1, "Tar cannot archive a character device %s",
594		    arcn->org_name);
595		return(1);
596	case PAX_BLK:
597		paxwarn(1, "Tar cannot archive a block device %s", arcn->org_name);
598		return(1);
599	case PAX_SCK:
600		paxwarn(1, "Tar cannot archive a socket %s", arcn->org_name);
601		return(1);
602	case PAX_FIF:
603		paxwarn(1, "Tar cannot archive a fifo %s", arcn->org_name);
604		return(1);
605	case PAX_SLK:
606	case PAX_HLK:
607	case PAX_HRG:
608		if (arcn->ln_nlen > sizeof(hd->linkname)) {
609			paxwarn(1,"Link name too long for tar %s", arcn->ln_name);
610			return(1);
611		}
612		break;
613	case PAX_REG:
614	case PAX_CTG:
615	default:
616		break;
617	}
618
619	/*
620	 * check file name len, remember extra char for dirs (the / at the end)
621	 */
622	len = arcn->nlen;
623	if (arcn->type == PAX_DIR)
624		++len;
625	if (len >= sizeof(hd->name)) {
626		paxwarn(1, "File name too long for tar %s", arcn->name);
627		return(1);
628	}
629
630	/*
631	 * copy the data out of the ARCHD into the tar header based on the type
632	 * of the file. Remember many tar readers want the unused fields to be
633	 * padded with zero. We set the linkflag field (type), the linkname
634	 * (or zero if not used),the size, and set the padding (if any) to be
635	 * added after the file data (0 for all other types, as they only have
636	 * a header)
637	 */
638	hd = (HD_TAR *)hdblk;
639	l_strncpy(hd->name, arcn->name, sizeof(hd->name) - 1);
640	hd->name[sizeof(hd->name) - 1] = '\0';
641	arcn->pad = 0;
642
643	if (arcn->type == PAX_DIR) {
644		/*
645		 * directories are the same as files, except have a filename
646		 * that ends with a /, we add the slash here. No data follows,
647		 * dirs, so no pad.
648		 */
649		hd->linkflag = AREGTYPE;
650		memset(hd->linkname, 0, sizeof(hd->linkname));
651		hd->name[len-1] = '/';
652		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1))
653			goto out;
654	} else if (arcn->type == PAX_SLK) {
655		/*
656		 * no data follows this file, so no pad
657		 */
658		hd->linkflag = SYMTYPE;
659		l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1);
660		hd->linkname[sizeof(hd->linkname) - 1] = '\0';
661		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1))
662			goto out;
663	} else if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) {
664		/*
665		 * no data follows this file, so no pad
666		 */
667		hd->linkflag = LNKTYPE;
668		l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1);
669		hd->linkname[sizeof(hd->linkname) - 1] = '\0';
670		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1))
671			goto out;
672	} else {
673		/*
674		 * data follows this file, so set the pad
675		 */
676		hd->linkflag = AREGTYPE;
677		memset(hd->linkname, 0, sizeof(hd->linkname));
678#		ifdef NET2_STAT
679		if (ul_oct((u_long)arcn->sb.st_size, hd->size,
680		    sizeof(hd->size), 1)) {
681#		else
682		if (uqd_oct((u_quad_t)arcn->sb.st_size, hd->size,
683		    sizeof(hd->size), 1)) {
684#		endif
685			paxwarn(1,"File is too large for tar %s", arcn->org_name);
686			return(1);
687		}
688		arcn->pad = TAR_PAD(arcn->sb.st_size);
689	}
690
691	/*
692	 * copy those fields that are independent of the type
693	 */
694	if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 0) ||
695	    ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 0) ||
696	    ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 0) ||
697	    ul_oct((u_long)arcn->sb.st_mtime, hd->mtime, sizeof(hd->mtime), 1))
698		goto out;
699
700	/*
701	 * calculate and add the checksum, then write the header. A return of
702	 * 0 tells the caller to now write the file data, 1 says no data needs
703	 * to be written
704	 */
705	if (ul_oct(tar_chksm(hdblk, sizeof(HD_TAR)), hd->chksum,
706	    sizeof(hd->chksum), 3))
707		goto out;
708	if (wr_rdbuf(hdblk, sizeof(HD_TAR)) < 0)
709		return(-1);
710	if (wr_skip((off_t)(BLKMULT - sizeof(HD_TAR))) < 0)
711		return(-1);
712	if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG))
713		return(0);
714	return(1);
715
716    out:
717	/*
718	 * header field is out of range
719	 */
720	paxwarn(1, "Tar header field is too small for %s", arcn->org_name);
721	return(1);
722}
723
724/*
725 * Routines for POSIX ustar
726 */
727
728/*
729 * ustar_strd()
730 *	initialization for ustar read
731 * Return:
732 *	0 if ok, -1 otherwise
733 */
734
735#ifdef __STDC__
736int
737ustar_strd(void)
738#else
739int
740ustar_strd()
741#endif
742{
743	if ((usrtb_start() < 0) || (grptb_start() < 0))
744		return(-1);
745	return(0);
746}
747
748/*
749 * ustar_stwr()
750 *	initialization for ustar write
751 * Return:
752 *	0 if ok, -1 otherwise
753 */
754
755#ifdef __STDC__
756int
757ustar_stwr(void)
758#else
759int
760ustar_stwr()
761#endif
762{
763	if ((uidtb_start() < 0) || (gidtb_start() < 0))
764		return(-1);
765	return(0);
766}
767
768/*
769 * ustar_id()
770 *	determine if a block given to us is a valid ustar header. We have to
771 *	be on the lookout for those pesky blocks of all zero's
772 * Return:
773 *	0 if a ustar header, -1 otherwise
774 */
775
776#ifdef __STDC__
777int
778ustar_id(char *blk, int size)
779#else
780int
781ustar_id(blk, size)
782	char *blk;
783	int size;
784#endif
785{
786	register HD_USTAR *hd;
787
788	if (size < BLKMULT)
789		return(-1);
790	hd = (HD_USTAR *)blk;
791
792	/*
793	 * check for block of zero's first, a simple and fast test then check
794	 * ustar magic cookie. We should use TMAGLEN, but some USTAR archive
795	 * programs are fouled up and create archives missing the \0. Last we
796	 * check the checksum. If ok we have to assume it is a valid header.
797	 */
798	if (hd->name[0] == '\0')
799		return(-1);
800	if (strncmp(hd->magic, TMAGIC, TMAGLEN - 1) != 0)
801		return(-1);
802	if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != tar_chksm(blk,BLKMULT))
803		return(-1);
804	return(0);
805}
806
807/*
808 * ustar_rd()
809 *	extract the values out of block already determined to be a ustar header.
810 *	store the values in the ARCHD parameter.
811 * Return:
812 *	0
813 */
814
815#ifdef __STDC__
816int
817ustar_rd(register ARCHD *arcn, register char *buf)
818#else
819int
820ustar_rd(arcn, buf)
821	register ARCHD *arcn;
822	register char *buf;
823#endif
824{
825	register HD_USTAR *hd;
826	register char *dest;
827	register int cnt = 0;
828	dev_t devmajor;
829	dev_t devminor;
830
831	/*
832	 * we only get proper sized buffers
833	 */
834	if (ustar_id(buf, BLKMULT) < 0)
835		return(-1);
836	arcn->org_name = arcn->name;
837	arcn->sb.st_nlink = 1;
838	arcn->pat = NULL;
839	arcn->nlen = 0;
840	hd = (HD_USTAR *)buf;
841
842	/*
843	 * see if the filename is split into two parts. if, so joint the parts.
844	 * we copy the prefix first and add a / between the prefix and name.
845	 */
846	dest = arcn->name;
847	if (*(hd->prefix) != '\0') {
848		cnt = l_strncpy(dest, hd->prefix, sizeof(arcn->name) - 2);
849		dest += cnt;
850		*dest++ = '/';
851		cnt++;
852	}
853	arcn->nlen = cnt + l_strncpy(dest, hd->name, sizeof(arcn->name) - cnt);
854	arcn->name[arcn->nlen] = '\0';
855
856	/*
857	 * follow the spec to the letter. we should only have mode bits, strip
858	 * off all other crud we may be passed.
859	 */
860	arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode, sizeof(hd->mode), OCT) &
861	    0xfff);
862#ifdef NET2_STAT
863	arcn->sb.st_size = (off_t)asc_ul(hd->size, sizeof(hd->size), OCT);
864	arcn->sb.st_mtime = (time_t)asc_ul(hd->mtime, sizeof(hd->mtime), OCT);
865#else
866	arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT);
867	arcn->sb.st_mtime = (time_t)asc_uqd(hd->mtime, sizeof(hd->mtime), OCT);
868#endif
869	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
870
871	/*
872	 * If we can find the ascii names for gname and uname in the password
873	 * and group files we will use the uid's and gid they bind. Otherwise
874	 * we use the uid and gid values stored in the header. (This is what
875	 * the POSIX spec wants).
876	 */
877	hd->gname[sizeof(hd->gname) - 1] = '\0';
878	if (gid_name(hd->gname, &(arcn->sb.st_gid)) < 0)
879		arcn->sb.st_gid = (gid_t)asc_ul(hd->gid, sizeof(hd->gid), OCT);
880	hd->uname[sizeof(hd->uname) - 1] = '\0';
881	if (uid_name(hd->uname, &(arcn->sb.st_uid)) < 0)
882		arcn->sb.st_uid = (uid_t)asc_ul(hd->uid, sizeof(hd->uid), OCT);
883
884	/*
885	 * set the defaults, these may be changed depending on the file type
886	 */
887	arcn->ln_name[0] = '\0';
888	arcn->ln_nlen = 0;
889	arcn->pad = 0;
890	arcn->skip = 0;
891	arcn->sb.st_rdev = (dev_t)0;
892
893	/*
894	 * set the mode and PAX type according to the typeflag in the header
895	 */
896	switch(hd->typeflag) {
897	case FIFOTYPE:
898		arcn->type = PAX_FIF;
899		arcn->sb.st_mode |= S_IFIFO;
900		break;
901	case DIRTYPE:
902		arcn->type = PAX_DIR;
903		arcn->sb.st_mode |= S_IFDIR;
904		arcn->sb.st_nlink = 2;
905
906		/*
907		 * Some programs that create ustar archives append a '/'
908		 * to the pathname for directories. This clearly violates
909		 * ustar specs, but we will silently strip it off anyway.
910		 */
911		if (arcn->name[arcn->nlen - 1] == '/')
912			arcn->name[--arcn->nlen] = '\0';
913		break;
914	case BLKTYPE:
915	case CHRTYPE:
916		/*
917		 * this type requires the rdev field to be set.
918		 */
919		if (hd->typeflag == BLKTYPE) {
920			arcn->type = PAX_BLK;
921			arcn->sb.st_mode |= S_IFBLK;
922		} else {
923			arcn->type = PAX_CHR;
924			arcn->sb.st_mode |= S_IFCHR;
925		}
926		devmajor = (dev_t)asc_ul(hd->devmajor,sizeof(hd->devmajor),OCT);
927		devminor = (dev_t)asc_ul(hd->devminor,sizeof(hd->devminor),OCT);
928		arcn->sb.st_rdev = TODEV(devmajor, devminor);
929		break;
930	case SYMTYPE:
931	case LNKTYPE:
932		if (hd->typeflag == SYMTYPE) {
933			arcn->type = PAX_SLK;
934			arcn->sb.st_mode |= S_IFLNK;
935		} else {
936			arcn->type = PAX_HLK;
937			/*
938			 * so printing looks better
939			 */
940			arcn->sb.st_mode |= S_IFREG;
941			arcn->sb.st_nlink = 2;
942		}
943		/*
944		 * copy the link name
945		 */
946		arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname,
947			sizeof(arcn->ln_name) - 1);
948		arcn->ln_name[arcn->ln_nlen] = '\0';
949		break;
950	case CONTTYPE:
951	case AREGTYPE:
952	case REGTYPE:
953	default:
954		/*
955		 * these types have file data that follows. Set the skip and
956		 * pad fields.
957		 */
958		arcn->type = PAX_REG;
959		arcn->pad = TAR_PAD(arcn->sb.st_size);
960		arcn->skip = arcn->sb.st_size;
961		arcn->sb.st_mode |= S_IFREG;
962		break;
963	}
964	return(0);
965}
966
967/*
968 * ustar_wr()
969 *	write a ustar header for the file specified in the ARCHD to the archive
970 *	Have to check for file types that cannot be stored and file names that
971 *	are too long. Be careful of the term (last arg) to ul_oct, we only use
972 *	'\0' for the termination character (this is different than picky tar)
973 *	ASSUMED: space after header in header block is zero filled
974 * Return:
975 *	0 if file has data to be written after the header, 1 if file has NO
976 *	data to write after the header, -1 if archive write failed
977 */
978
979#ifdef __STDC__
980int
981ustar_wr(register ARCHD *arcn)
982#else
983int
984ustar_wr(arcn)
985	register ARCHD *arcn;
986#endif
987{
988	register HD_USTAR *hd;
989	register char *pt;
990	char hdblk[sizeof(HD_USTAR)];
991
992	/*
993	 * check for those file system types ustar cannot store
994	 */
995	if (arcn->type == PAX_SCK) {
996		paxwarn(1, "Ustar cannot archive a socket %s", arcn->org_name);
997		return(1);
998	}
999
1000	/*
1001	 * check the length of the linkname
1002	 */
1003	if (((arcn->type == PAX_SLK) || (arcn->type == PAX_HLK) ||
1004	    (arcn->type == PAX_HRG)) && (arcn->ln_nlen >= sizeof(hd->linkname))){
1005		paxwarn(1, "Link name too long for ustar %s", arcn->ln_name);
1006		return(1);
1007	}
1008
1009	/*
1010	 * split the path name into prefix and name fields (if needed). if
1011	 * pt != arcn->name, the name has to be split
1012	 */
1013	if ((pt = name_split(arcn->name, arcn->nlen)) == NULL) {
1014		paxwarn(1, "File name too long for ustar %s", arcn->name);
1015		return(1);
1016	}
1017	hd = (HD_USTAR *)hdblk;
1018	arcn->pad = 0L;
1019
1020	/*
1021	 * split the name, or zero out the prefix
1022	 */
1023	if (pt != arcn->name) {
1024		/*
1025		 * name was split, pt points at the / where the split is to
1026		 * occur, we remove the / and copy the first part to the prefix
1027		 */
1028		*pt = '\0';
1029		l_strncpy(hd->prefix, arcn->name, sizeof(hd->prefix) - 1);
1030		*pt++ = '/';
1031	} else
1032		memset(hd->prefix, 0, sizeof(hd->prefix));
1033
1034	/*
1035	 * copy the name part. this may be the whole path or the part after
1036	 * the prefix
1037	 */
1038	l_strncpy(hd->name, pt, sizeof(hd->name) - 1);
1039	hd->name[sizeof(hd->name) - 1] = '\0';
1040
1041	/*
1042	 * set the fields in the header that are type dependent
1043	 */
1044	switch(arcn->type) {
1045	case PAX_DIR:
1046		hd->typeflag = DIRTYPE;
1047		memset(hd->linkname, 0, sizeof(hd->linkname));
1048		memset(hd->devmajor, 0, sizeof(hd->devmajor));
1049		memset(hd->devminor, 0, sizeof(hd->devminor));
1050		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
1051			goto out;
1052		break;
1053	case PAX_CHR:
1054	case PAX_BLK:
1055		if (arcn->type == PAX_CHR)
1056			hd->typeflag = CHRTYPE;
1057		else
1058			hd->typeflag = BLKTYPE;
1059		memset(hd->linkname, 0, sizeof(hd->linkname));
1060		if (ul_oct((u_long)MAJOR(arcn->sb.st_rdev), hd->devmajor,
1061		   sizeof(hd->devmajor), 3) ||
1062		   ul_oct((u_long)MINOR(arcn->sb.st_rdev), hd->devminor,
1063		   sizeof(hd->devminor), 3) ||
1064		   ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
1065			goto out;
1066		break;
1067	case PAX_FIF:
1068		hd->typeflag = FIFOTYPE;
1069		memset(hd->linkname, 0, sizeof(hd->linkname));
1070		memset(hd->devmajor, 0, sizeof(hd->devmajor));
1071		memset(hd->devminor, 0, sizeof(hd->devminor));
1072		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
1073			goto out;
1074		break;
1075	case PAX_SLK:
1076	case PAX_HLK:
1077	case PAX_HRG:
1078		if (arcn->type == PAX_SLK)
1079			hd->typeflag = SYMTYPE;
1080		else
1081			hd->typeflag = LNKTYPE;
1082		l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1);
1083		hd->linkname[sizeof(hd->linkname) - 1] = '\0';
1084		memset(hd->devmajor, 0, sizeof(hd->devmajor));
1085		memset(hd->devminor, 0, sizeof(hd->devminor));
1086		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
1087			goto out;
1088		break;
1089	case PAX_REG:
1090	case PAX_CTG:
1091	default:
1092		/*
1093		 * file data with this type, set the padding
1094		 */
1095		if (arcn->type == PAX_CTG)
1096			hd->typeflag = CONTTYPE;
1097		else
1098			hd->typeflag = REGTYPE;
1099		memset(hd->linkname, 0, sizeof(hd->linkname));
1100		memset(hd->devmajor, 0, sizeof(hd->devmajor));
1101		memset(hd->devminor, 0, sizeof(hd->devminor));
1102		arcn->pad = TAR_PAD(arcn->sb.st_size);
1103#		ifdef NET2_STAT
1104		if (ul_oct((u_long)arcn->sb.st_size, hd->size,
1105		    sizeof(hd->size), 3)) {
1106#		else
1107		if (uqd_oct((u_quad_t)arcn->sb.st_size, hd->size,
1108		    sizeof(hd->size), 3)) {
1109#		endif
1110			paxwarn(1,"File is too long for ustar %s",arcn->org_name);
1111			return(1);
1112		}
1113		break;
1114	}
1115
1116	l_strncpy(hd->magic, TMAGIC, TMAGLEN);
1117	l_strncpy(hd->version, TVERSION, TVERSLEN);
1118
1119	/*
1120	 * set the remaining fields. Some versions want all 16 bits of mode
1121	 * we better humor them (they really do not meet spec though)....
1122	 */
1123	if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 3) ||
1124	    ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 3)  ||
1125	    ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3) ||
1126	    ul_oct((u_long)arcn->sb.st_mtime,hd->mtime,sizeof(hd->mtime),3))
1127		goto out;
1128	l_strncpy(hd->uname,name_uid(arcn->sb.st_uid, 0),sizeof(hd->uname));
1129	l_strncpy(hd->gname,name_gid(arcn->sb.st_gid, 0),sizeof(hd->gname));
1130
1131	/*
1132	 * calculate and store the checksum write the header to the archive
1133	 * return 0 tells the caller to now write the file data, 1 says no data
1134	 * needs to be written
1135	 */
1136	if (ul_oct(tar_chksm(hdblk, sizeof(HD_USTAR)), hd->chksum,
1137	   sizeof(hd->chksum), 3))
1138		goto out;
1139	if (wr_rdbuf(hdblk, sizeof(HD_USTAR)) < 0)
1140		return(-1);
1141	if (wr_skip((off_t)(BLKMULT - sizeof(HD_USTAR))) < 0)
1142		return(-1);
1143	if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG))
1144		return(0);
1145	return(1);
1146
1147    out:
1148    	/*
1149	 * header field is out of range
1150	 */
1151	paxwarn(1, "Ustar header field is too small for %s", arcn->org_name);
1152	return(1);
1153}
1154
1155/*
1156 * name_split()
1157 *	see if the name has to be split for storage in a ustar header. We try
1158 *	to fit the entire name in the name field without splitting if we can.
1159 *	The split point is always at a /
1160 * Return
1161 *	character pointer to split point (always the / that is to be removed
1162 *	if the split is not needed, the points is set to the start of the file
1163 *	name (it would violate the spec to split there). A NULL is returned if
1164 *	the file name is too long
1165 */
1166
1167#ifdef __STDC__
1168static char *
1169name_split(register char *name, register int len)
1170#else
1171static char *
1172name_split(name, len)
1173	register char *name;
1174	register int len;
1175#endif
1176{
1177	register char *start;
1178
1179	/*
1180	 * check to see if the file name is small enough to fit in the name
1181	 * field. if so just return a pointer to the name.
1182	 */
1183	if (len < TNMSZ)
1184		return(name);
1185	if (len > (TPFSZ + TNMSZ))
1186		return(NULL);
1187
1188	/*
1189	 * we start looking at the biggest sized piece that fits in the name
1190	 * field. We walk forward looking for a slash to split at. The idea is
1191	 * to find the biggest piece to fit in the name field (or the smallest
1192	 * prefix we can find)
1193	 */
1194	start = name + len - TNMSZ;
1195	while ((*start != '\0') && (*start != '/'))
1196		++start;
1197
1198	/*
1199	 * if we hit the end of the string, this name cannot be split, so we
1200	 * cannot store this file.
1201	 */
1202	if (*start == '\0')
1203		return(NULL);
1204	len = start - name;
1205
1206	/*
1207	 * NOTE: /str where the length of str == TNMSZ can not be stored under
1208	 * the p1003.1-1990 spec for ustar. We could force a prefix of / and
1209	 * the file would then expand on extract to //str. The len == 0 below
1210	 * makes this special case follow the spec to the letter.
1211	 */
1212	if ((len >= TPFSZ) || (len == 0))
1213		return(NULL);
1214
1215	/*
1216	 * ok have a split point, return it to the caller
1217	 */
1218	return(start);
1219}
1220