Print this page
6128 tar should check prefix field when detecting EOT
6129 tar debug output should be available in all builds
Reviewed by: Robert Mustacchi <rm@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/tar/tar.c
          +++ new/usr/src/cmd/tar/tar.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   * Copyright 2012 Milan Jurik. All rights reserved.
  24      - * Copyright (c) 2013, Joyent, Inc. All rights reserved.
       24 + * Copyright 2015 Joyent, Inc.
  25   25   */
  26   26  
  27   27  /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T     */
  28   28  /*        All Rights Reserved   */
  29   29  
  30   30  /*      Copyright (c) 1987, 1988 Microsoft Corporation  */
  31   31  /*        All Rights Reserved   */
  32   32  
  33   33  /*
  34   34   * Portions of this source code were derived from Berkeley 4.3 BSD
↓ open down ↓ 82 lines elided ↑ open up ↑
 117  117  int utimes(const char *path, const struct timeval timeval_ptr[]);
 118  118  
 119  119  #ifndef MINSIZE
 120  120  #define MINSIZE 250
 121  121  #endif
 122  122  #define DEF_FILE "/etc/default/tar"
 123  123  
 124  124  #define min(a, b)  ((a) < (b) ? (a) : (b))
 125  125  #define max(a, b)  ((a) > (b) ? (a) : (b))
 126  126  
 127      -/* -DDEBUG      ONLY for debugging */
 128      -#ifdef  DEBUG
 129      -#undef  DEBUG
 130      -#define DEBUG(a, b, c)\
 131      -        (void) fprintf(stderr, "DEBUG - "), (void) fprintf(stderr, a, b, c)
 132      -#endif
 133      -
 134  127  #define TBLOCK  512     /* tape block size--should be universal */
 135  128  
 136  129  #ifdef  BSIZE
 137  130  #define SYS_BLOCK BSIZE /* from sys/param.h:  secondary block size */
 138  131  #else   /* BSIZE */
 139  132  #define SYS_BLOCK 512   /* default if no BSIZE in param.h */
 140  133  #endif  /* BSIZE */
 141  134  
 142  135  #define NBLOCK  20
 143  136  #define NAMSIZ  100
↓ open down ↓ 331 lines elided ↑ open up ↑
 475  468  static int bcheck(char *bstr);
 476  469  static int checkdir(char *name);
 477  470  static int checksum(union hblock *dblockp);
 478  471  #ifdef  EUC
 479  472  static int checksum_signed(union hblock *dblockp);
 480  473  #endif  /* EUC */
 481  474  static int checkupdate(char *arg);
 482  475  static int checkw(char c, char *name);
 483  476  static int cmp(char *b, char *s, int n);
 484  477  static int defset(char *arch);
 485      -static int endtape(void);
      478 +static boolean_t endtape(void);
 486  479  static int is_in_table(file_list_t *table[], char *str);
 487  480  static int notsame(void);
 488  481  static int is_prefix(char *s1, char *s2);
 489  482  static int response(void);
 490  483  static int build_dblock(const char *, const char *, const char,
 491  484          const int filetype, const struct stat *, const dev_t, const char *);
 492  485  static unsigned int hash(char *str);
 493  486  
 494  487  static blkcnt_t kcheck(char *kstr);
 495  488  static off_t bsrch(char *s, int n, off_t l, off_t h);
↓ open down ↓ 55 lines elided ↑ open up ↑
 551  544  static pid_t uncompress_file(void);
 552  545  static void *compress_malloc(size_t);
 553  546  static void check_compression(void);
 554  547  static char *bz_suffix(void);
 555  548  static char *gz_suffix(void);
 556  549  static char *xz_suffix(void);
 557  550  static char *add_suffix();
 558  551  static void wait_pid(pid_t);
 559  552  static void verify_compress_opt(const char *t);
 560  553  static void detect_compress(void);
      554 +static void dlog(const char *, ...);
      555 +static boolean_t should_enable_debug(void);
 561  556  
 562  557  static  struct stat stbuf;
 563  558  
 564  559  static  char    *myname;
 565  560  static  char    *xtract_chdir = NULL;
 566  561  static  int     checkflag = 0;
 567  562  static  int     Xflag, Fflag, iflag, hflag, Bflag, Iflag;
 568  563  static  int     rflag, xflag, vflag, tflag, mt, cflag, mflag, pflag;
 569  564  static  int     uflag;
 570  565  static  int     errflag;
↓ open down ↓ 55 lines elided ↑ open up ↑
 626  621  
 627  622  static  int     mulvol;         /* multi-volume option selected */
 628  623  static  blkcnt_t        blocklim; /* number of blocks to accept per volume */
 629  624  static  blkcnt_t        tapepos; /* current block number to be written */
 630  625  static  int     NotTape;        /* true if tape is a disk */
 631  626  static  int     dumping;        /* true if writing a tape or other archive */
 632  627  static  int     extno;          /* number of extent:  starts at 1 */
 633  628  static  int     extotal;        /* total extents in this file */
 634  629  static  off_t   extsize;        /* size of current extent during extraction */
 635  630  static  ushort_t        Oumask = 0;     /* old umask value */
 636      -static  int is_posix;   /* true if archive we're reading is POSIX-conformant */
      631 +static  boolean_t is_posix;     /* true if archive is POSIX-conformant */
 637  632  static  const   char    *magic_type = "ustar";
 638  633  static  size_t  xrec_size = 8 * PATH_MAX;       /* extended rec initial size */
 639  634  static  char    *xrec_ptr;
 640  635  static  off_t   xrec_offset = 0;
 641  636  static  int     Xhdrflag;
 642  637  static  int     charset_type = 0;
 643  638  
 644  639  static  u_longlong_t    xhdr_flgs;      /* Bits set determine which items */
 645  640                                          /*   need to be in extended header. */
 646  641  static  pid_t   comp_pid = 0;
 647  642  
      643 +static boolean_t debug_output = B_FALSE;
      644 +
 648  645  #define _X_DEVMAJOR     0x1
 649  646  #define _X_DEVMINOR     0x2
 650  647  #define _X_GID          0x4
 651  648  #define _X_GNAME        0x8
 652  649  #define _X_LINKPATH     0x10
 653  650  #define _X_PATH         0x20
 654  651  #define _X_SIZE         0x40
 655  652  #define _X_UID          0x80
 656  653  #define _X_UNAME        0x100
 657  654  #define _X_ATIME        0x200
↓ open down ↓ 71 lines elided ↑ open up ↑
 729  726          pid_t           thispid;
 730  727  
 731  728          (void) setlocale(LC_ALL, "");
 732  729  #if !defined(TEXT_DOMAIN)       /* Should be defined by cc -D */
 733  730  #define TEXT_DOMAIN "SYS_TEST"  /* Use this only if it weren't */
 734  731  #endif
 735  732          (void) textdomain(TEXT_DOMAIN);
 736  733          if (argc < 2)
 737  734                  usage();
 738  735  
      736 +        debug_output = should_enable_debug();
      737 +
 739  738          tfile = NULL;
 740  739          if ((myname = strdup(argv[0])) == NULL) {
 741  740                  (void) fprintf(stderr, gettext(
 742  741                      "tar: cannot allocate program name\n"));
 743  742                  exit(1);
 744  743          }
 745  744  
 746  745          if (init_yes() < 0) {
 747  746                  (void) fprintf(stderr, gettext(ERR_MSG_INIT_YES),
 748  747                      strerror(errno));
↓ open down ↓ 437 lines elided ↑ open up ↑
1186 1185          }
1187 1186          else
1188 1187                  usage();
1189 1188  
1190 1189          done(Errflg);
1191 1190  
1192 1191          /* Not reached:  keep compiler quiet */
1193 1192          return (1);
1194 1193  }
1195 1194  
     1195 +static boolean_t
     1196 +should_enable_debug(void)
     1197 +{
     1198 +        const char *val;
     1199 +        const char *truth[] = {
     1200 +                "true",
     1201 +                "1",
     1202 +                "yes",
     1203 +                "y",
     1204 +                "please",
     1205 +                NULL
     1206 +        };
     1207 +        unsigned int i;
     1208 +
     1209 +        if ((val = getenv("DEBUG_TAR")) == NULL) {
     1210 +                return (B_FALSE);
     1211 +        }
     1212 +
     1213 +        for (i = 0; truth[i] != NULL; i++) {
     1214 +                if (strcmp(val, truth[i]) == 0) {
     1215 +                        return (B_TRUE);
     1216 +                }
     1217 +        }
     1218 +
     1219 +        return (B_FALSE);
     1220 +}
     1221 +
     1222 +/*PRINTFLIKE1*/
1196 1223  static void
     1224 +dlog(const char *format, ...)
     1225 +{
     1226 +        va_list ap;
     1227 +
     1228 +        if (!debug_output) {
     1229 +                return;
     1230 +        }
     1231 +
     1232 +        va_start(ap, format);
     1233 +        (void) fprintf(stderr, "tar: DEBUG: ");
     1234 +        (void) vfprintf(stderr, format, ap);
     1235 +        va_end(ap);
     1236 +}
     1237 +
     1238 +static void
1197 1239  usage(void)
1198 1240  {
1199 1241          (void) fprintf(stderr, gettext(
1200 1242  #if defined(O_XATTR)
1201 1243  #if defined(_PC_SATTR_ENABLED)
1202 1244              "Usage: tar {c|r|t|u|x}[BDeEFhilmnopPTvw@/[0-7]][bf][X...] "
1203 1245  #else
1204 1246              "Usage: tar {c|r|t|u|x}[BDeEFhilmnopPTvw@[0-7]][bf][X...] "
1205 1247  #endif  /* _PC_SATTR_ENABLED */
1206 1248  #else
↓ open down ↓ 213 lines elided ↑ open up ↑
1420 1462   *
1421 1463   *      endtape checks the entry in dblock.dbuf to see if its the
1422 1464   *      special EOT entry.  Endtape is usually called after getdir().
1423 1465   *
1424 1466   *      endtape used to call backtape; it no longer does, he who
1425 1467   *      wants it backed up must call backtape himself
1426 1468   *      RETURNS:        0 if not EOT, tape position unaffected
1427 1469   *                      1 if     EOT, tape position unaffected
1428 1470   */
1429 1471  
1430      -static int
     1472 +static boolean_t
1431 1473  endtape(void)
1432 1474  {
1433      -        if (dblock.dbuf.name[0] == '\0') {      /* null header = EOT */
1434      -                return (1);
1435      -        } else
1436      -                return (0);
     1475 +        if (dblock.dbuf.name[0] != '\0') {
     1476 +                /*
     1477 +                 * The name field is populated.
     1478 +                 */
     1479 +                return (B_FALSE);
     1480 +        }
     1481 +
     1482 +        if (is_posix && dblock.dbuf.prefix[0] != '\0') {
     1483 +                /*
     1484 +                 * This is a ustar/POSIX archive, and although the name
     1485 +                 * field is empty the prefix field is not.
     1486 +                 */
     1487 +                return (B_FALSE);
     1488 +        }
     1489 +
     1490 +        dlog("endtape(): found null header; EOT\n");
     1491 +        return (B_TRUE);
1437 1492  }
1438 1493  
1439 1494  /*
1440 1495   *      getdir - get directory entry from tar tape
1441 1496   *
1442 1497   *      getdir reads the next tarblock off the tape and cracks
1443 1498   *      it as a directory. The checksum must match properly.
1444 1499   *
1445 1500   *      If tfile is non-null getdir writes the file name and mod date
1446 1501   *      to tfile.
↓ open down ↓ 17 lines elided ↑ open up ↑
1464 1519          (void) sscanf(dblock.dbuf.gid, "%8lo", (ulong_t *)&Gen.g_gid);
1465 1520          (void) sscanf(dblock.dbuf.size, "%12" FMT_off_t_o, &Gen.g_filesz);
1466 1521          (void) sscanf(dblock.dbuf.mtime, "%12lo", (ulong_t *)&Gen.g_mtime);
1467 1522          (void) sscanf(dblock.dbuf.chksum, "%8o", &Gen.g_cksum);
1468 1523          (void) sscanf(dblock.dbuf.devmajor, "%8lo", &Gen.g_devmajor);
1469 1524          (void) sscanf(dblock.dbuf.devminor, "%8lo", &Gen.g_devminor);
1470 1525  
1471 1526          is_posix = (strcmp(dblock.dbuf.magic, magic_type) == 0);
1472 1527  
1473 1528          sp->st_mode = Gen.g_mode;
1474      -        if (is_posix && (sp->st_mode & S_IFMT) == 0)
     1529 +        if (is_posix && (sp->st_mode & S_IFMT) == 0) {
1475 1530                  switch (dblock.dbuf.typeflag) {
1476      -                case '0': case 0: case _XATTR_HDRTYPE:
     1531 +                case '0':
     1532 +                case 0:
     1533 +                case _XATTR_HDRTYPE:
1477 1534                          sp->st_mode |= S_IFREG;
1478 1535                          break;
1479 1536                  case '1':       /* hard link */
1480 1537                          break;
1481 1538                  case '2':
1482 1539                          sp->st_mode |= S_IFLNK;
1483 1540                          break;
1484 1541                  case '3':
1485 1542                          sp->st_mode |= S_IFCHR;
1486 1543                          break;
↓ open down ↓ 4 lines elided ↑ open up ↑
1491 1548                          sp->st_mode |= S_IFDIR;
1492 1549                          break;
1493 1550                  case '6':
1494 1551                          sp->st_mode |= S_IFIFO;
1495 1552                          break;
1496 1553                  default:
1497 1554                          if (convtoreg(Gen.g_filesz))
1498 1555                                  sp->st_mode |= S_IFREG;
1499 1556                          break;
1500 1557                  }
     1558 +        }
1501 1559  
1502 1560          if ((dblock.dbuf.typeflag == 'X') || (dblock.dbuf.typeflag == 'L')) {
1503 1561                  Xhdrflag = 1;   /* Currently processing extended header */
1504 1562          } else {
1505 1563                  Xhdrflag = 0;
1506 1564          }
1507 1565  
1508 1566          sp->st_uid = Gen.g_uid;
1509 1567          sp->st_gid = Gen.g_gid;
1510 1568          sp->st_size = Gen.g_filesz;
↓ open down ↓ 87 lines elided ↑ open up ↑
1598 1656  }
1599 1657  
1600 1658  
1601 1659  /*
1602 1660   *      passtape - skip over a file on the tape
1603 1661   *
1604 1662   *      passtape skips over the next data file on the tape.
1605 1663   *      The tape directory entry must be in dblock.dbuf. This
1606 1664   *      routine just eats the number of blocks computed from the
1607 1665   *      directory size entry; the tape must be (logically) positioned
1608      - *      right after thee directory info.
     1666 + *      right after the directory info.
1609 1667   */
1610 1668  
1611 1669  static void
1612 1670  passtape(void)
1613 1671  {
1614 1672          blkcnt_t blocks;
1615 1673          char buf[TBLOCK];
1616 1674  
1617 1675          /*
     1676 +         * Print some debugging information about the directory entry
     1677 +         * we are skipping over:
     1678 +         */
     1679 +        dlog("passtape: typeflag \"%c\"\n", dblock.dbuf.typeflag);
     1680 +        if (dblock.dbuf.name[0] != '\0') {
     1681 +                dlog("passtape: name \"%s\"\n", dblock.dbuf.name);
     1682 +        }
     1683 +        if (is_posix && dblock.dbuf.prefix[0] != '\0') {
     1684 +                dlog("passtape: prefix \"%s\"\n", dblock.dbuf.prefix);
     1685 +        }
     1686 +
     1687 +        /*
1618 1688           * Types link(1), sym-link(2), char special(3), blk special(4),
1619 1689           *  directory(5), and FIFO(6) do not have data blocks associated
1620 1690           *  with them so just skip reading the data block.
1621 1691           */
1622 1692          if (dblock.dbuf.typeflag == '1' || dblock.dbuf.typeflag == '2' ||
1623 1693              dblock.dbuf.typeflag == '3' || dblock.dbuf.typeflag == '4' ||
1624 1694              dblock.dbuf.typeflag == '5' || dblock.dbuf.typeflag == '6')
1625 1695                  return;
1626 1696          blocks = TBLOCKS(stbuf.st_size);
1627 1697  
     1698 +        dlog("passtape: block count %" FMT_blkcnt_t "\n", blocks);
     1699 +
1628 1700          /* if operating on disk, seek instead of reading */
1629 1701          if (NotTape)
1630 1702                  seekdisk(blocks);
1631 1703          else
1632 1704                  while (blocks-- > 0)
1633 1705                          readtape(buf);
1634 1706  }
1635 1707  
1636 1708  #if defined(O_XATTR)
1637 1709  static int
↓ open down ↓ 425 lines elided ↑ open up ↑
2063 2135  #else
2064 2136                          dblock.dbuf.typeflag = '5';
2065 2137  #endif
2066 2138  
2067 2139                          (void) sprintf(dblock.dbuf.chksum, "%07o",
2068 2140                              checksum(&dblock));
2069 2141  
2070 2142                          (void) writetbuf((char *)&dblock, 1);
2071 2143                  }
2072 2144                  if (vflag) {
2073      -#ifdef DEBUG
2074      -                        if (NotTape)
2075      -                                DEBUG("seek = %" FMT_blkcnt_t "K\t", K(tapepos),
2076      -                                    0);
2077      -#endif
     2145 +                        if (NotTape) {
     2146 +                                dlog("seek = %" FMT_blkcnt_t "K\n", K(tapepos));
     2147 +                        }
2078 2148                          if (filetype == XATTR_FILE && Hiddendir) {
2079 2149                                  (void) fprintf(vfile,
2080 2150                                      gettext("a %s attribute %s "),
2081 2151                                      longname, longattrname);
2082 2152  
2083 2153                          } else {
2084 2154                                  (void) fprintf(vfile, "a %s/ ", longname);
2085 2155                          }
2086      -                        if (NotTape)
     2156 +                        if (NotTape) {
2087 2157                                  (void) fprintf(vfile, "%" FMT_blkcnt_t "K\n",
2088 2158                                      K(blocks));
2089      -                        else
     2159 +                        } else {
2090 2160                                  (void) fprintf(vfile, gettext("%" FMT_blkcnt_t
2091 2161                                      " tape blocks\n"), blocks);
     2162 +                        }
2092 2163                  }
2093 2164  
2094 2165                  /*
2095 2166                   * If hidden dir then break now since xattrs_put() will do
2096 2167                   * the iterating of the directory.
2097 2168                   *
2098 2169                   * At the moment, there can only be system attributes on
2099 2170                   * attributes.  There can be no attributes on attributes or
2100 2171                   * directories within the attributes hidden directory hierarchy.
2101 2172                   */
↓ open down ↓ 161 lines elided ↑ open up ↑
2263 2334                          if (((blocklim - tapepos) >= EXTMIN) &&
2264 2335                              ((blocks + 1) >= blocklim/10)) {
2265 2336                                  splitfile(longname, infile,
2266 2337                                      name, prefix, filetype);
2267 2338                                  (void) close(dirfd);
2268 2339                                  (void) close(infile);
2269 2340                                  goto out;
2270 2341                          }
2271 2342                          newvol();       /* not worth it--just get new volume */
2272 2343                  }
2273      -#ifdef DEBUG
2274      -                DEBUG("putfile: %s wants %" FMT_blkcnt_t " blocks\n", longname,
     2344 +                dlog("putfile: %s wants %" FMT_blkcnt_t " blocks\n", longname,
2275 2345                      blocks);
2276      -#endif
2277 2346                  if (build_dblock(name, tchar, '0', filetype,
2278 2347                      &stbuf, stbuf.st_dev, prefix) != 0) {
2279 2348                          goto out;
2280 2349                  }
2281 2350                  if (vflag) {
2282      -#ifdef DEBUG
2283      -                        if (NotTape)
2284      -                                DEBUG("seek = %" FMT_blkcnt_t "K\t", K(tapepos),
2285      -                                    0);
2286      -#endif
     2351 +                        if (NotTape) {
     2352 +                                dlog("seek = %" FMT_blkcnt_t "K\n", K(tapepos));
     2353 +                        }
2287 2354                          (void) fprintf(vfile, "a %s%s%s%s ", longname,
2288 2355                              rw_sysattr ? gettext(" system") : "",
2289 2356                              (filetype == XATTR_FILE) ? gettext(
2290 2357                              " attribute ") : "",
2291 2358                              (filetype == XATTR_FILE) ?
2292 2359                              longattrname : "");
2293 2360                          if (NotTape)
2294 2361                                  (void) fprintf(vfile, "%" FMT_blkcnt_t "K\n",
2295 2362                                      K(blocks));
2296 2363                          else
↓ open down ↓ 63 lines elided ↑ open up ↑
2360 2427                          if (((blocklim - tapepos) >= EXTMIN) &&
2361 2428                              ((blocks + 1) >= blocklim/10)) {
2362 2429                                  splitfile(longname, infile, name,
2363 2430                                      prefix, filetype);
2364 2431                                  (void) close(dirfd);
2365 2432                                  (void) close(infile);
2366 2433                                  goto out;
2367 2434                          }
2368 2435                          newvol();
2369 2436                  }
2370      -#ifdef DEBUG
2371      -                DEBUG("putfile: %s wants %" FMT_blkcnt_t " blocks\n", longname,
     2437 +                dlog("putfile: %s wants %" FMT_blkcnt_t " blocks\n", longname,
2372 2438                      blocks);
2373      -#endif
2374 2439                  if (vflag) {
2375      -#ifdef DEBUG
2376      -                        if (NotTape)
2377      -                                DEBUG("seek = %" FMT_blkcnt_t "K\t", K(tapepos),
2378      -                                    0);
2379      -#endif
2380      -                        if (NotTape)
     2440 +                        if (NotTape) {
     2441 +                                dlog("seek = %" FMT_blkcnt_t "K\n", K(tapepos));
     2442 +
2381 2443                                  (void) fprintf(vfile, gettext("a %s %"
2382 2444                                      FMT_blkcnt_t "K\n "), longname, K(blocks));
2383      -                        else
     2445 +                        } else {
2384 2446                                  (void) fprintf(vfile, gettext(
2385 2447                                      "a %s %" FMT_blkcnt_t " tape blocks\n"),
2386 2448                                      longname, blocks);
     2449 +                        }
2387 2450                  }
2388 2451                  if (build_dblock(name, tchar, '6', filetype,
2389 2452                      &stbuf, stbuf.st_dev, prefix) != 0)
2390 2453                          goto out;
2391 2454  
2392 2455                  if (put_extra_attributes(longname, shortname, longattrname,
2393 2456                      prefix, filetype, '6') != 0)
2394 2457                          goto out;
2395 2458  
2396 2459                  (void) sprintf(dblock.dbuf.chksum, "%07o", checksum(&dblock));
↓ open down ↓ 14 lines elided ↑ open up ↑
2411 2474                  while (mulvol && tapepos + blocks + 1 > blocklim) {
2412 2475                          if (((blocklim - tapepos) >= EXTMIN) &&
2413 2476                              ((blocks + 1) >= blocklim/10)) {
2414 2477                                  splitfile(longname, infile, name,
2415 2478                                      prefix, filetype);
2416 2479                                  (void) close(dirfd);
2417 2480                                  goto out;
2418 2481                          }
2419 2482                          newvol();
2420 2483                  }
2421      -#ifdef DEBUG
2422      -                DEBUG("putfile: %s wants %" FMT_blkcnt_t " blocks\n", longname,
     2484 +                dlog("putfile: %s wants %" FMT_blkcnt_t " blocks\n", longname,
2423 2485                      blocks);
2424      -#endif
2425 2486                  if (vflag) {
2426      -#ifdef DEBUG
2427      -                        if (NotTape)
2428      -                                DEBUG("seek = %" FMT_blkcnt_t "K\t", K(tapepos),
2429      -                                    0);
2430      -#endif
2431      -                        if (NotTape)
     2487 +                        if (NotTape) {
     2488 +                                dlog("seek = %" FMT_blkcnt_t "K\t", K(tapepos));
     2489 +
2432 2490                                  (void) fprintf(vfile, gettext("a %s %"
2433 2491                                      FMT_blkcnt_t "K\n"), longname, K(blocks));
2434      -                        else
     2492 +                        } else {
2435 2493                                  (void) fprintf(vfile, gettext("a %s %"
2436 2494                                      FMT_blkcnt_t " tape blocks\n"), longname,
2437 2495                                      blocks);
     2496 +                        }
2438 2497                  }
2439 2498                  if (build_dblock(name, tchar, '3',
2440 2499                      filetype, &stbuf, stbuf.st_rdev, prefix) != 0)
2441 2500                          goto out;
2442 2501  
2443 2502                  if (put_extra_attributes(longname, shortname, longattrname,
2444 2503                      prefix, filetype, '3') != 0)
2445 2504                          goto out;
2446 2505  
2447 2506                  (void) sprintf(dblock.dbuf.chksum, "%07o", checksum(&dblock));
↓ open down ↓ 14 lines elided ↑ open up ↑
2462 2521                  while (mulvol && tapepos + blocks + 1 > blocklim) {
2463 2522                          if (((blocklim - tapepos) >= EXTMIN) &&
2464 2523                              ((blocks + 1) >= blocklim/10)) {
2465 2524                                  splitfile(longname, infile,
2466 2525                                      name, prefix, filetype);
2467 2526                                  (void) close(dirfd);
2468 2527                                  goto out;
2469 2528                          }
2470 2529                          newvol();
2471 2530                  }
2472      -#ifdef DEBUG
2473      -                DEBUG("putfile: %s wants %" FMT_blkcnt_t " blocks\n", longname,
     2531 +                dlog("putfile: %s wants %" FMT_blkcnt_t " blocks\n", longname,
2474 2532                      blocks);
2475      -#endif
2476 2533                  if (vflag) {
2477      -#ifdef DEBUG
2478      -                        if (NotTape)
2479      -                                DEBUG("seek = %" FMT_blkcnt_t "K\t", K(tapepos),
2480      -                                    0);
2481      -#endif
     2534 +                        if (NotTape) {
     2535 +                                dlog("seek = %" FMT_blkcnt_t "K\n", K(tapepos));
     2536 +                        }
     2537 +
2482 2538                          (void) fprintf(vfile, "a %s ", longname);
2483 2539                          if (NotTape)
2484 2540                                  (void) fprintf(vfile, "%" FMT_blkcnt_t "K\n",
2485 2541                                      K(blocks));
2486 2542                          else
2487 2543                                  (void) fprintf(vfile, gettext("%"
2488 2544                                      FMT_blkcnt_t " tape blocks\n"), blocks);
2489 2545                  }
2490 2546                  if (build_dblock(name, tchar, '4',
2491 2547                      filetype, &stbuf, stbuf.st_rdev, prefix) != 0)
↓ open down ↓ 2291 lines elided ↑ open up ↑
4783 4839   *                              for new volume, and waits.
4784 4840   *      if dumping, end-of-file is written onto the tape.
4785 4841   */
4786 4842  
4787 4843  static void
4788 4844  newvol(void)
4789 4845  {
4790 4846          int c;
4791 4847  
4792 4848          if (dumping) {
4793      -#ifdef DEBUG
4794      -                DEBUG("newvol called with 'dumping' set\n", 0, 0);
4795      -#endif
     4849 +                dlog("newvol called with 'dumping' set\n");
4796 4850                  putempty((blkcnt_t)2);  /* 2 EOT marks */
4797 4851                  closevol();
4798 4852                  flushtape();
4799 4853                  sync();
4800 4854                  tapepos = 0;
4801 4855          } else
4802 4856                  first = TRUE;
4803 4857          if (close(mt) != 0)
4804 4858                  vperror(2, gettext("close error"));
4805 4859          mt = 0;
↓ open down ↓ 12 lines elided ↑ open up ↑
4818 4872                  mt = dup(1);
4819 4873          } else {
4820 4874                  mt = open(usefile, dumping ? update : 0);
4821 4875          }
4822 4876  
4823 4877          if (mt < 0) {
4824 4878                  (void) fprintf(stderr, gettext(
4825 4879                      "tar: cannot reopen %s (%s)\n"),
4826 4880                      dumping ? gettext("output") : gettext("input"), usefile);
4827 4881  
4828      -#ifdef DEBUG
4829      -                DEBUG("update=%d, usefile=%s ", update, usefile);
4830      -                DEBUG("mt=%d, [%s]\n", mt, strerror(errno));
4831      -#endif
     4882 +                dlog("update=%d, usefile=%s ", update, usefile);
     4883 +                dlog("mt=%d, [%s]\n", mt, strerror(errno));
4832 4884  
4833 4885                  done(2);
4834 4886          }
4835 4887  }
4836 4888  
4837 4889  /*
4838 4890   * Write a trailer portion to close out the current output volume.
4839 4891   */
4840 4892  
4841 4893  static void
↓ open down ↓ 164 lines elided ↑ open up ↑
5006 5058  static void
5007 5059  seekdisk(blkcnt_t blocks)
5008 5060  {
5009 5061          off_t seekval;
5010 5062  #if SYS_BLOCK > TBLOCK
5011 5063          /* handle non-multiple of SYS_BLOCK */
5012 5064          blkcnt_t nxb;   /* # extra blocks */
5013 5065  #endif
5014 5066  
5015 5067          tapepos += blocks;
5016      -#ifdef DEBUG
5017      -        DEBUG("seekdisk(%" FMT_blkcnt_t ") called\n", blocks, 0);
5018      -#endif
     5068 +        dlog("seekdisk(%" FMT_blkcnt_t ") called\n", blocks);
5019 5069          if (recno + blocks <= nblock) {
5020 5070                  recno += blocks;
5021 5071                  return;
5022 5072          }
5023 5073          if (recno > nblock)
5024 5074                  recno = nblock;
5025 5075          seekval = (off_t)blocks - (nblock - recno);
5026 5076          recno = nblock; /* so readtape() reads next time through */
5027 5077  #if SYS_BLOCK > TBLOCK
5028 5078          nxb = (blkcnt_t)(seekval % (off_t)(SYS_BLOCK / TBLOCK));
5029      -#ifdef DEBUG
5030      -        DEBUG("xtrablks=%" FMT_blkcnt_t " seekval=%" FMT_blkcnt_t " blks\n",
     5079 +        dlog("xtrablks=%" FMT_blkcnt_t " seekval=%" FMT_blkcnt_t " blks\n",
5031 5080              nxb, seekval);
5032      -#endif
5033 5081          if (nxb && nxb > seekval) /* don't seek--we'll read */
5034 5082                  goto noseek;
5035 5083          seekval -=  nxb;        /* don't seek quite so far */
5036 5084  #endif
5037 5085          if (lseek(mt, (off_t)(TBLOCK * seekval), 1) == (off_t)-1) {
5038 5086                  (void) fprintf(stderr, gettext(
5039 5087                      "tar: device seek error\n"));
5040 5088                  done(3);
5041 5089          }
5042 5090  #if SYS_BLOCK > TBLOCK
5043 5091          /* read those extra blocks */
5044 5092  noseek:
5045 5093          if (nxb) {
5046      -#ifdef DEBUG
5047      -                DEBUG("reading extra blocks\n", 0, 0);
5048      -#endif
     5094 +                dlog("reading extra blocks\n", 0, 0);
5049 5095                  if (read(mt, tbuf, TBLOCK*nblock) < 0) {
5050 5096                          (void) fprintf(stderr, gettext(
5051 5097                              "tar: read error while skipping file\n"));
5052 5098                          done(8);
5053 5099                  }
5054 5100                  recno = nxb;    /* so we don't read in next readtape() */
5055 5101          }
5056 5102  #endif
5057 5103  }
5058 5104  
↓ open down ↓ 151 lines elided ↑ open up ↑
5210 5256   *      The proper way to backup the tape is through the use of mtio.
5211 5257   *      Earlier spins used lseek combined with reads in a confusing
5212 5258   *      maneuver that only worked on 4.x, but shouldn't have, even
5213 5259   *      there.  Lseeks are explicitly not supported for tape devices.
5214 5260   */
5215 5261  
5216 5262  static void
5217 5263  backtape(void)
5218 5264  {
5219 5265          struct mtop mtcmd;
5220      -#ifdef DEBUG
5221      -        DEBUG("backtape() called, recno=%" FMT_blkcnt_t " nblock=%d\n", recno,
     5266 +        dlog("backtape() called, recno=%" FMT_blkcnt_t " nblock=%d\n", recno,
5222 5267              nblock);
5223      -#endif
5224 5268          /*
5225 5269           * Backup to the position in the archive where the record
5226 5270           * currently sitting in the tbuf buffer is situated.
5227 5271           */
5228 5272  
5229 5273          if (NotTape) {
5230 5274                  /*
5231 5275                   * For non-tape devices, this means lseeking to the
5232 5276                   * correct position.  The absolute location tapepos-recno
5233 5277                   * should be the beginning of the current record.
↓ open down ↓ 37 lines elided ↑ open up ↑
5271 5315   *      recno points to next free block in tbuf.  If nonzero, a write is done.
5272 5316   *      Care is taken to write in multiples of SYS_BLOCK when device is
5273 5317   *      non-magtape in case raw i/o is used.
5274 5318   *
5275 5319   *      NOTE: this is called by writetape() to do the actual writing
5276 5320   */
5277 5321  
5278 5322  static void
5279 5323  flushtape(void)
5280 5324  {
5281      -#ifdef DEBUG
5282      -        DEBUG("flushtape() called, recno=%" FMT_blkcnt_t "\n", recno, 0);
5283      -#endif
     5325 +        dlog("flushtape() called, recno=%" FMT_blkcnt_t "\n", recno);
5284 5326          if (recno > 0) {        /* anything buffered? */
5285 5327                  if (NotTape) {
5286 5328  #if SYS_BLOCK > TBLOCK
5287 5329                          int i;
5288 5330  
5289 5331                          /*
5290 5332                           * an odd-block write can only happen when
5291 5333                           * we are at the end of a volume that is not a tape.
5292 5334                           * Here we round recno up to an even SYS_BLOCK
5293 5335                           * boundary.
5294 5336                           */
5295 5337                          if ((i = recno % (SYS_BLOCK / TBLOCK)) != 0) {
5296      -#ifdef DEBUG
5297      -                                DEBUG("flushtape() %d rounding blocks\n", i, 0);
5298      -#endif
     5338 +                                dlog("flushtape() %d rounding blocks\n", i);
5299 5339                                  recno += i;     /* round up to even SYS_BLOCK */
5300 5340                          }
5301 5341  #endif
5302 5342                          if (recno > nblock)
5303 5343                                  recno = nblock;
5304 5344                  }
5305      -#ifdef DEBUG
5306      -                DEBUG("writing out %" FMT_blkcnt_t " blocks of %" FMT_blkcnt_t
     5345 +                dlog("writing out %" FMT_blkcnt_t " blocks of %" FMT_blkcnt_t
5307 5346                      " bytes\n", (blkcnt_t)(NotTape ? recno : nblock),
5308 5347                      (blkcnt_t)(NotTape ? recno : nblock) * TBLOCK);
5309      -#endif
5310 5348                  if (write(mt, tbuf,
5311 5349                      (size_t)(NotTape ? recno : nblock) * TBLOCK) < 0) {
5312 5350                          (void) fprintf(stderr, gettext(
5313 5351                              "tar: tape write error\n"));
5314 5352                          done(2);
5315 5353                  }
5316 5354                  recno = 0;
5317 5355          }
5318 5356  }
5319 5357  
↓ open down ↓ 109 lines elided ↑ open up ↑
5429 5467                      "tar: size component missing in '%s' entry in %s.\n"),
5430 5468                      arch, DEF_FILE);
5431 5469                  return (FALSE);
5432 5470          }
5433 5471          blocklim = kcheck(bp);
5434 5472          if ((bp = strtok(NULL, " \t")) != NULL)
5435 5473                  NotTape = (*bp == 'n' || *bp == 'N');
5436 5474          else
5437 5475                  NotTape = (blocklim != 0);
5438 5476          (void) defopen(NULL);
5439      -#ifdef DEBUG
5440      -        DEBUG("defset: archive='%s'; usefile='%s'\n", arch, usefile);
5441      -        DEBUG("defset: nblock='%d'; blocklim='%" FMT_blkcnt_t "'\n",
     5477 +        dlog("defset: archive='%s'; usefile='%s'\n", arch, usefile);
     5478 +        dlog("defset: nblock='%d'; blocklim='%" FMT_blkcnt_t "'\n",
5442 5479              nblock, blocklim);
5443      -        DEBUG("defset: not tape = %d\n", NotTape, 0);
5444      -#endif
     5480 +        dlog("defset: not tape = %d\n", NotTape);
5445 5481          return (TRUE);
5446 5482  }
5447 5483  
5448 5484  
5449 5485  /*
5450 5486   * Following code handles excluded and included files.
5451 5487   * A hash table of file names to be {in,ex}cluded is built.
5452 5488   * For excluded files, before writing or extracting a file
5453 5489   * check to see if it is in the exclude_tbl.
5454 5490   * For included files, the wantit() procedure will check to
↓ open down ↓ 290 lines elided ↑ open up ↑
5745 5781  #endif
5746 5782  
5747 5783          /* sets *namep to point at the proper name */
5748 5784          if (check_prefix(namep, dirp, component) != 0) {
5749 5785                  passtape();
5750 5786                  return (0);
5751 5787          }
5752 5788  
5753 5789          if (endtape()) {
5754 5790                  if (Bflag) {
     5791 +                        ssize_t sz;
     5792 +                        size_t extra_blocks = 0;
     5793 +
5755 5794                          /*
5756 5795                           * Logically at EOT - consume any extra blocks
5757 5796                           * so that write to our stdin won't fail and
5758 5797                           * emit an error message; otherwise something
5759 5798                           * like "dd if=foo.tar | (cd bar; tar xvf -)"
5760 5799                           * will produce a bogus error message from "dd".
5761 5800                           */
5762 5801  
5763      -                        while (read(mt, tbuf, TBLOCK*nblock) > 0) {
5764      -                                /* empty body */
     5802 +                        while ((sz = read(mt, tbuf, TBLOCK*nblock)) > 0) {
     5803 +                                extra_blocks += sz;
5765 5804                          }
     5805 +                        dlog("wantit(): %d bytes of extra blocks\n",
     5806 +                            extra_blocks);
5766 5807                  }
     5808 +                dlog("wantit(): at end of tape.\n");
5767 5809                  return (-1);
5768 5810          }
5769 5811  
5770 5812          gotit = 0;
5771 5813  
5772 5814          if ((Iflag && is_in_table(include_tbl, *namep)) ||
5773 5815              (! Iflag && *argv == NULL)) {
5774 5816                  gotit = 1;
5775 5817          } else {
5776 5818                  for (cp = argv; *cp; cp++) {
↓ open down ↓ 2232 lines elided ↑ open up ↑
8009 8051                          (void) writetbuf((char *)&dblock, 1);
8010 8052                          /*
8011 8053                           * write_ancillary() is not needed here.
8012 8054                           * The first link is handled in the following
8013 8055                           * else statement. No need to process ACLs
8014 8056                           * for other hard links since they are the
8015 8057                           * same file.
8016 8058                           */
8017 8059  
8018 8060                          if (vflag) {
8019      -#ifdef DEBUG
8020 8061                                  if (NotTape)
8021      -                                        DEBUG("seek = %" FMT_blkcnt_t
8022      -                                            "K\t", K(tapepos), 0);
8023      -#endif
     8062 +                                        dlog("seek = %" FMT_blkcnt_t
     8063 +                                            "K\n", K(tapepos));
8024 8064                                  if (filetype == XATTR_FILE) {
8025 8065                                          (void) fprintf(vfile, gettext(
8026 8066                                              "a %s attribute %s link to "
8027 8067                                              "%s attribute %s\n"),
8028 8068                                              name, component, name,
8029 8069                                              lp->attrname);
8030 8070                                  } else {
8031 8071                                          (void) fprintf(vfile, gettext(
8032 8072                                              "a %s link to %s\n"),
8033 8073                                              longname, lp->pathname);
↓ open down ↓ 1439 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX