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