tar.c revision 1.4 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 /*static char sccsid[] = "from: @(#)tar.c 8.2 (Berkeley) 4/18/94";*/
40 static char *rcsid = "$Id: tar.c,v 1.4 1994/09/23 11:35:13 mycroft Exp $";
41 #endif /* not lint */
42
43 #include <sys/types.h>
44 #include <sys/time.h>
45 #include <sys/stat.h>
46 #include <sys/param.h>
47 #include <string.h>
48 #include <stdio.h>
49 #include <ctype.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
60 static u_long tar_chksm __P((register char *, register int));
61 static char *name_split __P((register char *, register int));
62 static int ul_oct __P((u_long, register char *, register int, int));
63 #ifndef NET2_STAT
64 static 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
71 static 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__
81 int
82 tar_endwr(void)
83 #else
84 int
85 tar_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__
99 off_t
100 tar_endrd(void)
101 #else
102 off_t
103 tar_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__
121 int
122 tar_trail(register char *buf, register int in_resync, register int *cnt)
123 #else
124 int
125 tar_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__
172 static int
173 ul_oct(u_long val, register char *str, register int len, int term)
174 #else
175 static int
176 ul_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__
236 static int
237 uqd_oct(u_quad_t val, register char *str, register int len, int term)
238 #else
239 static int
240 uqd_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__
299 static u_long
300 tar_chksm(register char *blk, register int len)
301 #else
302 static u_long
303 tar_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__
347 int
348 tar_id(register char *blk, int size)
349 #else
350 int
351 tar_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__
388 int
389 tar_opt(void)
390 #else
391 int
392 tar_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__
430 int
431 tar_rd(register ARCHD *arcn, register char *buf)
432 #else
433 int
434 tar_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__
553 int
554 tar_wr(register ARCHD *arcn)
555 #else
556 int
557 tar_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 memset(hd->linkname, 0, 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 memset(hd->linkname, 0, 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__
717 int
718 ustar_strd(void)
719 #else
720 int
721 ustar_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__
737 int
738 ustar_stwr(void)
739 #else
740 int
741 ustar_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__
758 int
759 ustar_id(char *blk, int size)
760 #else
761 int
762 ustar_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__
797 int
798 ustar_rd(register ARCHD *arcn, register char *buf)
799 #else
800 int
801 ustar_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__
955 int
956 ustar_wr(register ARCHD *arcn)
957 #else
958 int
959 ustar_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 memset(hd->prefix, 0, 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 memset(hd->linkname, 0, sizeof(hd->linkname));
1022 memset(hd->devmajor, 0, sizeof(hd->devmajor));
1023 memset(hd->devminor, 0, 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 memset(hd->linkname, 0, 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 memset(hd->linkname, 0, sizeof(hd->linkname));
1044 memset(hd->devmajor, 0, sizeof(hd->devmajor));
1045 memset(hd->devminor, 0, 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 memset(hd->devmajor, 0, sizeof(hd->devmajor));
1058 memset(hd->devminor, 0, 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 memset(hd->linkname, 0, sizeof(hd->linkname));
1073 memset(hd->devmajor, 0, sizeof(hd->devmajor));
1074 memset(hd->devminor, 0, 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__
1141 static char *
1142 name_split(register char *name, register int len)
1143 #else
1144 static char *
1145 name_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