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