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