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