Link Here
|
460 |
} |
460 |
} |
461 |
} |
461 |
} |
462 |
|
462 |
|
|
|
463 |
void xheader_xattr_init(struct tar_stat_info *st) |
464 |
{ |
465 |
st->xattr_map = NULL; |
466 |
st->xattr_map_size = 0; |
467 |
} |
468 |
|
469 |
void xheader_xattr_free(struct xattr_array *xattr_map, size_t xattr_map_size) |
470 |
{ |
471 |
size_t scan = 0; |
472 |
|
473 |
while (scan < xattr_map_size) |
474 |
{ |
475 |
free (xattr_map[scan].xkey); |
476 |
free (xattr_map[scan].xval_ptr); |
477 |
|
478 |
++scan; |
479 |
} |
480 |
free (xattr_map); |
481 |
} |
482 |
|
483 |
static void xheader_xattr__add(struct xattr_array **xattr_map, |
484 |
size_t *xattr_map_size, |
485 |
const char *key, const char *val, size_t len) |
486 |
{ |
487 |
size_t pos = (*xattr_map_size)++; |
488 |
|
489 |
*xattr_map = xrealloc (*xattr_map, |
490 |
*xattr_map_size * sizeof(struct xattr_array)); |
491 |
(*xattr_map)[pos].xkey = xstrdup (key); |
492 |
(*xattr_map)[pos].xval_ptr = xmemdup (val, len + 1); |
493 |
(*xattr_map)[pos].xval_len = len; |
494 |
} |
495 |
|
496 |
void xheader_xattr_add(struct tar_stat_info *st, |
497 |
const char *key, const char *val, size_t len) |
498 |
{ |
499 |
size_t klen = strlen (key); |
500 |
char *xkey = xmalloc (strlen("SCHILY.xattr.") + klen + 1); |
501 |
char *tmp = xkey; |
502 |
|
503 |
tmp = stpcpy (tmp, "SCHILY.xattr."); |
504 |
tmp = stpcpy (tmp, key); |
505 |
|
506 |
xheader_xattr__add (&st->xattr_map, &st->xattr_map_size, xkey, val, len); |
507 |
|
508 |
free (xkey); |
509 |
} |
510 |
|
511 |
void xheader_xattr_copy(const struct tar_stat_info *st, |
512 |
struct xattr_array **xattr_map, size_t *xattr_map_size) |
513 |
{ |
514 |
size_t scan = 0; |
515 |
|
516 |
*xattr_map = NULL; |
517 |
*xattr_map_size = 0; |
518 |
|
519 |
while (scan < st->xattr_map_size) |
520 |
{ |
521 |
char *key = st->xattr_map[scan].xkey; |
522 |
char *val = st->xattr_map[scan].xval_ptr; |
523 |
size_t len = st->xattr_map[scan].xval_len; |
524 |
|
525 |
xheader_xattr__add(xattr_map, xattr_map_size, key, val, len); |
526 |
|
527 |
++scan; |
528 |
} |
529 |
} |
530 |
|
463 |
|
531 |
|
464 |
/* General Interface */ |
532 |
/* General Interface */ |
465 |
|
533 |
|
Link Here
|
473 |
struct xheader *, void const *data); |
541 |
struct xheader *, void const *data); |
474 |
void (*decoder) (struct tar_stat_info *, char const *, char const *, size_t); |
542 |
void (*decoder) (struct tar_stat_info *, char const *, char const *, size_t); |
475 |
int flags; |
543 |
int flags; |
|
|
544 |
bool prefix; |
476 |
}; |
545 |
}; |
477 |
|
546 |
|
478 |
/* This declaration must be extern, because ISO C99 section 6.9.2 |
547 |
/* This declaration must be extern, because ISO C99 section 6.9.2 |
Link Here
|
489 |
struct xhdr_tab const *p; |
558 |
struct xhdr_tab const *p; |
490 |
|
559 |
|
491 |
for (p = xhdr_tab; p->keyword; p++) |
560 |
for (p = xhdr_tab; p->keyword; p++) |
492 |
if (strcmp (p->keyword, keyword) == 0) |
561 |
if (p->prefix) |
493 |
return p; |
562 |
{ |
|
|
563 |
if (strncmp (p->keyword, keyword, strlen(p->keyword)) == 0) |
564 |
return p; |
565 |
} |
566 |
else |
567 |
{ |
568 |
if (strcmp (p->keyword, keyword) == 0) |
569 |
return p; |
570 |
} |
571 |
|
494 |
return NULL; |
572 |
return NULL; |
495 |
} |
573 |
} |
496 |
|
574 |
|
Link Here
|
500 |
struct xhdr_tab const *p; |
578 |
struct xhdr_tab const *p; |
501 |
|
579 |
|
502 |
for (p = xhdr_tab; p->keyword; p++) |
580 |
for (p = xhdr_tab; p->keyword; p++) |
503 |
if ((p->flags & XHDR_PROTECTED) && fnmatch (pattern, p->keyword, 0) == 0) |
581 |
if (!p->prefix && (p->flags & XHDR_PROTECTED) && fnmatch (pattern, p->keyword, 0) == 0) |
504 |
return true; |
582 |
return true; |
505 |
return false; |
583 |
return false; |
506 |
} |
584 |
} |
Link Here
|
511 |
struct xhdr_tab const *p; |
589 |
struct xhdr_tab const *p; |
512 |
|
590 |
|
513 |
for (p = xhdr_tab; p->keyword; p++) |
591 |
for (p = xhdr_tab; p->keyword; p++) |
514 |
if ((p->flags & XHDR_PROTECTED) && strcmp (p->keyword, keyword) == 0) |
592 |
if (!p->prefix && (p->flags & XHDR_PROTECTED) && strcmp (p->keyword, keyword) == 0) |
515 |
return true; |
593 |
return true; |
516 |
return false; |
594 |
return false; |
517 |
} |
595 |
} |
Link Here
|
1470 |
} |
1548 |
} |
1471 |
|
1549 |
|
1472 |
static void |
1550 |
static void |
|
|
1551 |
xattr_selinux_coder (struct tar_stat_info const *st, char const *keyword, |
1552 |
struct xheader *xhdr, void const *data) |
1553 |
{ |
1554 |
code_string (st->cntx_name, keyword, xhdr); |
1555 |
} |
1556 |
|
1557 |
static void |
1558 |
xattr_selinux_decoder (struct tar_stat_info *st, |
1559 |
char const *keyword, char const *arg, size_t size) |
1560 |
{ |
1561 |
decode_string (&st->cntx_name, arg); |
1562 |
} |
1563 |
|
1564 |
static void |
1565 |
xattr_acls_a_coder (struct tar_stat_info const *st , char const *keyword, |
1566 |
struct xheader *xhdr, void const *data) |
1567 |
{ |
1568 |
xheader_print_n (xhdr, keyword, st->acls_a_ptr, st->acls_a_len); |
1569 |
} |
1570 |
|
1571 |
static void |
1572 |
xattr_acls_a_decoder (struct tar_stat_info *st, |
1573 |
char const *keyword, char const *arg, size_t size) |
1574 |
{ |
1575 |
st->acls_a_ptr = xmemdup (arg, size + 1); |
1576 |
st->acls_a_len = size; |
1577 |
} |
1578 |
|
1579 |
static void |
1580 |
xattr_acls_d_coder (struct tar_stat_info const *st , char const *keyword, |
1581 |
struct xheader *xhdr, void const *data) |
1582 |
{ |
1583 |
xheader_print_n (xhdr, keyword, st->acls_d_ptr, st->acls_d_len); |
1584 |
} |
1585 |
|
1586 |
static void |
1587 |
xattr_acls_d_decoder (struct tar_stat_info *st, |
1588 |
char const *keyword, char const *arg, size_t size) |
1589 |
{ |
1590 |
st->acls_d_ptr = xmemdup (arg, size + 1); |
1591 |
st->acls_d_len = size; |
1592 |
} |
1593 |
|
1594 |
static void |
1595 |
xattr_coder (struct tar_stat_info const *st , char const *keyword, |
1596 |
struct xheader *xhdr, void const *data) |
1597 |
{ |
1598 |
struct xattr_array *xattr_map = st->xattr_map; |
1599 |
const size_t *off = data; |
1600 |
xheader_print_n (xhdr, keyword, |
1601 |
xattr_map[*off].xval_ptr, xattr_map[*off].xval_len); |
1602 |
} |
1603 |
|
1604 |
static void |
1605 |
xattr_decoder (struct tar_stat_info *st, |
1606 |
char const *keyword, char const *arg, size_t size) |
1607 |
{ |
1608 |
char *xstr = NULL; |
1609 |
|
1610 |
xstr = xmemdup(arg, size + 1); |
1611 |
xheader_xattr_add(st, keyword + strlen("SCHILY.xattr."), xstr, size); |
1612 |
free(xstr); |
1613 |
} |
1614 |
|
1615 |
static void |
1473 |
sparse_major_coder (struct tar_stat_info const *st, char const *keyword, |
1616 |
sparse_major_coder (struct tar_stat_info const *st, char const *keyword, |
1474 |
struct xheader *xhdr, void const *data) |
1617 |
struct xheader *xhdr, void const *data) |
1475 |
{ |
1618 |
{ |
Link Here
|
1506 |
} |
1649 |
} |
1507 |
|
1650 |
|
1508 |
struct xhdr_tab const xhdr_tab[] = { |
1651 |
struct xhdr_tab const xhdr_tab[] = { |
1509 |
{ "atime", atime_coder, atime_decoder, 0 }, |
1652 |
{ "atime", atime_coder, atime_decoder, 0, false }, |
1510 |
{ "comment", dummy_coder, dummy_decoder, 0 }, |
1653 |
{ "comment", dummy_coder, dummy_decoder, 0, false }, |
1511 |
{ "charset", dummy_coder, dummy_decoder, 0 }, |
1654 |
{ "charset", dummy_coder, dummy_decoder, 0, false }, |
1512 |
{ "ctime", ctime_coder, ctime_decoder, 0 }, |
1655 |
{ "ctime", ctime_coder, ctime_decoder, 0, false }, |
1513 |
{ "gid", gid_coder, gid_decoder, 0 }, |
1656 |
{ "gid", gid_coder, gid_decoder, 0, false }, |
1514 |
{ "gname", gname_coder, gname_decoder, 0 }, |
1657 |
{ "gname", gname_coder, gname_decoder, 0, false }, |
1515 |
{ "linkpath", linkpath_coder, linkpath_decoder, 0 }, |
1658 |
{ "linkpath", linkpath_coder, linkpath_decoder, 0, false }, |
1516 |
{ "mtime", mtime_coder, mtime_decoder, 0 }, |
1659 |
{ "mtime", mtime_coder, mtime_decoder, 0, false }, |
1517 |
{ "path", path_coder, path_decoder, 0 }, |
1660 |
{ "path", path_coder, path_decoder, 0, false }, |
1518 |
{ "size", size_coder, size_decoder, 0 }, |
1661 |
{ "size", size_coder, size_decoder, 0, false }, |
1519 |
{ "uid", uid_coder, uid_decoder, 0 }, |
1662 |
{ "uid", uid_coder, uid_decoder, 0, false }, |
1520 |
{ "uname", uname_coder, uname_decoder, 0 }, |
1663 |
{ "uname", uname_coder, uname_decoder, 0, false }, |
1521 |
|
1664 |
|
1522 |
/* Sparse file handling */ |
1665 |
/* Sparse file handling */ |
1523 |
{ "GNU.sparse.name", path_coder, path_decoder, |
1666 |
{ "GNU.sparse.name", path_coder, path_decoder, |
1524 |
XHDR_PROTECTED }, |
1667 |
XHDR_PROTECTED, false }, |
1525 |
{ "GNU.sparse.major", sparse_major_coder, sparse_major_decoder, |
1668 |
{ "GNU.sparse.major", sparse_major_coder, sparse_major_decoder, |
1526 |
XHDR_PROTECTED }, |
1669 |
XHDR_PROTECTED, false }, |
1527 |
{ "GNU.sparse.minor", sparse_minor_coder, sparse_minor_decoder, |
1670 |
{ "GNU.sparse.minor", sparse_minor_coder, sparse_minor_decoder, |
1528 |
XHDR_PROTECTED }, |
1671 |
XHDR_PROTECTED, false }, |
1529 |
{ "GNU.sparse.realsize", sparse_size_coder, sparse_size_decoder, |
1672 |
{ "GNU.sparse.realsize", sparse_size_coder, sparse_size_decoder, |
1530 |
XHDR_PROTECTED }, |
1673 |
XHDR_PROTECTED, false }, |
1531 |
{ "GNU.sparse.numblocks", sparse_numblocks_coder, sparse_numblocks_decoder, |
1674 |
{ "GNU.sparse.numblocks", sparse_numblocks_coder, sparse_numblocks_decoder, |
1532 |
XHDR_PROTECTED }, |
1675 |
XHDR_PROTECTED, false }, |
1533 |
|
1676 |
|
1534 |
/* tar 1.14 - 1.15.90 keywords. */ |
1677 |
/* tar 1.14 - 1.15.90 keywords. */ |
1535 |
{ "GNU.sparse.size", sparse_size_coder, sparse_size_decoder, |
1678 |
{ "GNU.sparse.size", sparse_size_coder, sparse_size_decoder, |
1536 |
XHDR_PROTECTED }, |
1679 |
XHDR_PROTECTED, false }, |
1537 |
/* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x' |
1680 |
/* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x' |
1538 |
headers, and each of them was meaningful. It confilcted with POSIX specs, |
1681 |
headers, and each of them was meaningful. It confilcted with POSIX specs, |
1539 |
which requires that "when extended header records conflict, the last one |
1682 |
which requires that "when extended header records conflict, the last one |
1540 |
given in the header shall take precedence." */ |
1683 |
given in the header shall take precedence." */ |
1541 |
{ "GNU.sparse.offset", sparse_offset_coder, sparse_offset_decoder, |
1684 |
{ "GNU.sparse.offset", sparse_offset_coder, sparse_offset_decoder, |
1542 |
XHDR_PROTECTED }, |
1685 |
XHDR_PROTECTED, false }, |
1543 |
{ "GNU.sparse.numbytes", sparse_numbytes_coder, sparse_numbytes_decoder, |
1686 |
{ "GNU.sparse.numbytes", sparse_numbytes_coder, sparse_numbytes_decoder, |
1544 |
XHDR_PROTECTED }, |
1687 |
XHDR_PROTECTED, false }, |
1545 |
/* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */ |
1688 |
/* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */ |
1546 |
{ "GNU.sparse.map", NULL /* Unused, see pax_dump_header() */, |
1689 |
{ "GNU.sparse.map", NULL /* Unused, see pax_dump_header() */, |
1547 |
sparse_map_decoder, 0 }, |
1690 |
sparse_map_decoder, 0, false }, |
1548 |
|
1691 |
|
1549 |
{ "GNU.dumpdir", dumpdir_coder, dumpdir_decoder, |
1692 |
{ "GNU.dumpdir", dumpdir_coder, dumpdir_decoder, |
1550 |
XHDR_PROTECTED }, |
1693 |
XHDR_PROTECTED, false }, |
1551 |
|
1694 |
|
1552 |
/* Keeps the tape/volume label. May be present only in the global headers. |
1695 |
/* Keeps the tape/volume label. May be present only in the global headers. |
1553 |
Equivalent to GNUTYPE_VOLHDR. */ |
1696 |
Equivalent to GNUTYPE_VOLHDR. */ |
1554 |
{ "GNU.volume.label", volume_label_coder, volume_label_decoder, |
1697 |
{ "GNU.volume.label", volume_label_coder, volume_label_decoder, |
1555 |
XHDR_PROTECTED | XHDR_GLOBAL }, |
1698 |
XHDR_PROTECTED | XHDR_GLOBAL, false }, |
1556 |
|
1699 |
|
1557 |
/* These may be present in a first global header of the archive. |
1700 |
/* These may be present in a first global header of the archive. |
1558 |
They provide the same functionality as GNUTYPE_MULTIVOL header. |
1701 |
They provide the same functionality as GNUTYPE_MULTIVOL header. |
Link Here
|
1561 |
GNU.volume.offset keeps the offset of the start of this volume, |
1704 |
GNU.volume.offset keeps the offset of the start of this volume, |
1562 |
otherwise kept in oldgnu_header.offset. */ |
1705 |
otherwise kept in oldgnu_header.offset. */ |
1563 |
{ "GNU.volume.filename", volume_label_coder, volume_filename_decoder, |
1706 |
{ "GNU.volume.filename", volume_label_coder, volume_filename_decoder, |
1564 |
XHDR_PROTECTED | XHDR_GLOBAL }, |
1707 |
XHDR_PROTECTED | XHDR_GLOBAL, false }, |
1565 |
{ "GNU.volume.size", volume_size_coder, volume_size_decoder, |
1708 |
{ "GNU.volume.size", volume_size_coder, volume_size_decoder, |
1566 |
XHDR_PROTECTED | XHDR_GLOBAL }, |
1709 |
XHDR_PROTECTED | XHDR_GLOBAL, false }, |
1567 |
{ "GNU.volume.offset", volume_offset_coder, volume_offset_decoder, |
1710 |
{ "GNU.volume.offset", volume_offset_coder, volume_offset_decoder, |
1568 |
XHDR_PROTECTED | XHDR_GLOBAL }, |
1711 |
XHDR_PROTECTED | XHDR_GLOBAL, false }, |
|
|
1712 |
|
1713 |
/* We get the SELinux value from filecon, so add a namespace for SELinux |
1714 |
instead of storing it in SCHILY.xattr.* (which would be RAW). */ |
1715 |
{ "RHT.security.selinux", |
1716 |
xattr_selinux_coder, xattr_selinux_decoder, 0, false }, |
1717 |
|
1718 |
/* ACLs, use the star format... */ |
1719 |
{ "SCHILY.acl.access", |
1720 |
xattr_acls_a_coder, xattr_acls_a_decoder, 0, false }, |
1721 |
|
1722 |
{ "SCHILY.acl.default", |
1723 |
xattr_acls_d_coder, xattr_acls_d_decoder, 0, false }, |
1724 |
|
1725 |
/* FIXME: These are compat. for FC-6 ... we shipped a tar using the generic |
1726 |
header names by accident. */ |
1727 |
{ "SCHILY.xattr.security.selinux", |
1728 |
xattr_selinux_coder, xattr_selinux_decoder, 0, false }, |
1729 |
{ "SCHILY.xattr.system.posix_acl_access", |
1730 |
xattr_acls_a_coder, xattr_acls_a_decoder, 0, false }, |
1731 |
{ "SCHILY.xattr.system.posix_acl_default", |
1732 |
xattr_acls_d_coder, xattr_acls_d_decoder, 0, false }, |
1733 |
|
1734 |
/* xattrs use the star format. note we only save some variants... */ |
1735 |
{ "SCHILY.xattr.user", xattr_coder, xattr_decoder, 0, true }, |
1736 |
{ "SCHILY.xattr.trusted", xattr_coder, xattr_decoder, 0, true }, |
1737 |
{ "SCHILY.xattr.lustre", xattr_coder, xattr_decoder, 0, true }, |
1738 |
{ "SCHILY.xattr.security.NTACL", xattr_coder, xattr_decoder, 0, true }, |
1739 |
|
1740 |
/* ignore everything else in the xattr namespaces... */ |
1741 |
{ "SCHILY.xattr", dummy_coder, dummy_decoder, 0, true }, |
1569 |
|
1742 |
|
1570 |
{ NULL, NULL, NULL, 0 } |
1743 |
{ NULL, NULL, NULL, 0, false } |
1571 |
}; |
1744 |
}; |