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_coder (struct tar_stat_info const *st , char const *keyword, |
1552 |
struct xheader *xhdr, void const *data) |
1553 |
{ |
1554 |
struct xattr_array *xattr_map = st->xattr_map; |
1555 |
const size_t *off = data; |
1556 |
xheader_print_n (xhdr, keyword, |
1557 |
xattr_map[*off].xval_ptr, xattr_map[*off].xval_len); |
1558 |
} |
1559 |
|
1560 |
static void |
1561 |
xattr_decoder (struct tar_stat_info *st, |
1562 |
char const *keyword, char const *arg, size_t size) |
1563 |
{ |
1564 |
char *xstr = NULL; |
1565 |
|
1566 |
xstr = xmemdup(arg, size + 1); |
1567 |
xheader_xattr_add(st, keyword + strlen("SCHILY.xattr."), xstr, size); |
1568 |
free(xstr); |
1569 |
} |
1570 |
|
1571 |
static void |
1473 |
sparse_major_coder (struct tar_stat_info const *st, char const *keyword, |
1572 |
sparse_major_coder (struct tar_stat_info const *st, char const *keyword, |
1474 |
struct xheader *xhdr, void const *data) |
1573 |
struct xheader *xhdr, void const *data) |
1475 |
{ |
1574 |
{ |
Link Here
|
1506 |
} |
1605 |
} |
1507 |
|
1606 |
|
1508 |
struct xhdr_tab const xhdr_tab[] = { |
1607 |
struct xhdr_tab const xhdr_tab[] = { |
1509 |
{ "atime", atime_coder, atime_decoder, 0 }, |
1608 |
{ "atime", atime_coder, atime_decoder, 0, false }, |
1510 |
{ "comment", dummy_coder, dummy_decoder, 0 }, |
1609 |
{ "comment", dummy_coder, dummy_decoder, 0, false }, |
1511 |
{ "charset", dummy_coder, dummy_decoder, 0 }, |
1610 |
{ "charset", dummy_coder, dummy_decoder, 0, false }, |
1512 |
{ "ctime", ctime_coder, ctime_decoder, 0 }, |
1611 |
{ "ctime", ctime_coder, ctime_decoder, 0, false }, |
1513 |
{ "gid", gid_coder, gid_decoder, 0 }, |
1612 |
{ "gid", gid_coder, gid_decoder, 0, false }, |
1514 |
{ "gname", gname_coder, gname_decoder, 0 }, |
1613 |
{ "gname", gname_coder, gname_decoder, 0, false }, |
1515 |
{ "linkpath", linkpath_coder, linkpath_decoder, 0 }, |
1614 |
{ "linkpath", linkpath_coder, linkpath_decoder, 0, false }, |
1516 |
{ "mtime", mtime_coder, mtime_decoder, 0 }, |
1615 |
{ "mtime", mtime_coder, mtime_decoder, 0, false }, |
1517 |
{ "path", path_coder, path_decoder, 0 }, |
1616 |
{ "path", path_coder, path_decoder, 0, false }, |
1518 |
{ "size", size_coder, size_decoder, 0 }, |
1617 |
{ "size", size_coder, size_decoder, 0, false }, |
1519 |
{ "uid", uid_coder, uid_decoder, 0 }, |
1618 |
{ "uid", uid_coder, uid_decoder, 0, false }, |
1520 |
{ "uname", uname_coder, uname_decoder, 0 }, |
1619 |
{ "uname", uname_coder, uname_decoder, 0, false }, |
1521 |
|
1620 |
|
1522 |
/* Sparse file handling */ |
1621 |
/* Sparse file handling */ |
1523 |
{ "GNU.sparse.name", path_coder, path_decoder, |
1622 |
{ "GNU.sparse.name", path_coder, path_decoder, |
1524 |
XHDR_PROTECTED }, |
1623 |
XHDR_PROTECTED, false }, |
1525 |
{ "GNU.sparse.major", sparse_major_coder, sparse_major_decoder, |
1624 |
{ "GNU.sparse.major", sparse_major_coder, sparse_major_decoder, |
1526 |
XHDR_PROTECTED }, |
1625 |
XHDR_PROTECTED, false }, |
1527 |
{ "GNU.sparse.minor", sparse_minor_coder, sparse_minor_decoder, |
1626 |
{ "GNU.sparse.minor", sparse_minor_coder, sparse_minor_decoder, |
1528 |
XHDR_PROTECTED }, |
1627 |
XHDR_PROTECTED, false }, |
1529 |
{ "GNU.sparse.realsize", sparse_size_coder, sparse_size_decoder, |
1628 |
{ "GNU.sparse.realsize", sparse_size_coder, sparse_size_decoder, |
1530 |
XHDR_PROTECTED }, |
1629 |
XHDR_PROTECTED, false }, |
1531 |
{ "GNU.sparse.numblocks", sparse_numblocks_coder, sparse_numblocks_decoder, |
1630 |
{ "GNU.sparse.numblocks", sparse_numblocks_coder, sparse_numblocks_decoder, |
1532 |
XHDR_PROTECTED }, |
1631 |
XHDR_PROTECTED, false }, |
1533 |
|
1632 |
|
1534 |
/* tar 1.14 - 1.15.90 keywords. */ |
1633 |
/* tar 1.14 - 1.15.90 keywords. */ |
1535 |
{ "GNU.sparse.size", sparse_size_coder, sparse_size_decoder, |
1634 |
{ "GNU.sparse.size", sparse_size_coder, sparse_size_decoder, |
1536 |
XHDR_PROTECTED }, |
1635 |
XHDR_PROTECTED, false }, |
1537 |
/* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x' |
1636 |
/* 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, |
1637 |
headers, and each of them was meaningful. It confilcted with POSIX specs, |
1539 |
which requires that "when extended header records conflict, the last one |
1638 |
which requires that "when extended header records conflict, the last one |
1540 |
given in the header shall take precedence." */ |
1639 |
given in the header shall take precedence." */ |
1541 |
{ "GNU.sparse.offset", sparse_offset_coder, sparse_offset_decoder, |
1640 |
{ "GNU.sparse.offset", sparse_offset_coder, sparse_offset_decoder, |
1542 |
XHDR_PROTECTED }, |
1641 |
XHDR_PROTECTED, false }, |
1543 |
{ "GNU.sparse.numbytes", sparse_numbytes_coder, sparse_numbytes_decoder, |
1642 |
{ "GNU.sparse.numbytes", sparse_numbytes_coder, sparse_numbytes_decoder, |
1544 |
XHDR_PROTECTED }, |
1643 |
XHDR_PROTECTED, false }, |
1545 |
/* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */ |
1644 |
/* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */ |
1546 |
{ "GNU.sparse.map", NULL /* Unused, see pax_dump_header() */, |
1645 |
{ "GNU.sparse.map", NULL /* Unused, see pax_dump_header() */, |
1547 |
sparse_map_decoder, 0 }, |
1646 |
sparse_map_decoder, 0, false }, |
1548 |
|
1647 |
|
1549 |
{ "GNU.dumpdir", dumpdir_coder, dumpdir_decoder, |
1648 |
{ "GNU.dumpdir", dumpdir_coder, dumpdir_decoder, |
1550 |
XHDR_PROTECTED }, |
1649 |
XHDR_PROTECTED, false }, |
1551 |
|
1650 |
|
1552 |
/* Keeps the tape/volume label. May be present only in the global headers. |
1651 |
/* Keeps the tape/volume label. May be present only in the global headers. |
1553 |
Equivalent to GNUTYPE_VOLHDR. */ |
1652 |
Equivalent to GNUTYPE_VOLHDR. */ |
1554 |
{ "GNU.volume.label", volume_label_coder, volume_label_decoder, |
1653 |
{ "GNU.volume.label", volume_label_coder, volume_label_decoder, |
1555 |
XHDR_PROTECTED | XHDR_GLOBAL }, |
1654 |
XHDR_PROTECTED | XHDR_GLOBAL, false }, |
1556 |
|
1655 |
|
1557 |
/* These may be present in a first global header of the archive. |
1656 |
/* These may be present in a first global header of the archive. |
1558 |
They provide the same functionality as GNUTYPE_MULTIVOL header. |
1657 |
They provide the same functionality as GNUTYPE_MULTIVOL header. |
Link Here
|
1561 |
GNU.volume.offset keeps the offset of the start of this volume, |
1660 |
GNU.volume.offset keeps the offset of the start of this volume, |
1562 |
otherwise kept in oldgnu_header.offset. */ |
1661 |
otherwise kept in oldgnu_header.offset. */ |
1563 |
{ "GNU.volume.filename", volume_label_coder, volume_filename_decoder, |
1662 |
{ "GNU.volume.filename", volume_label_coder, volume_filename_decoder, |
1564 |
XHDR_PROTECTED | XHDR_GLOBAL }, |
1663 |
XHDR_PROTECTED | XHDR_GLOBAL, false }, |
1565 |
{ "GNU.volume.size", volume_size_coder, volume_size_decoder, |
1664 |
{ "GNU.volume.size", volume_size_coder, volume_size_decoder, |
1566 |
XHDR_PROTECTED | XHDR_GLOBAL }, |
1665 |
XHDR_PROTECTED | XHDR_GLOBAL, false }, |
1567 |
{ "GNU.volume.offset", volume_offset_coder, volume_offset_decoder, |
1666 |
{ "GNU.volume.offset", volume_offset_coder, volume_offset_decoder, |
1568 |
XHDR_PROTECTED | XHDR_GLOBAL }, |
1667 |
XHDR_PROTECTED | XHDR_GLOBAL, false }, |
|
|
1668 |
|
1669 |
/* xattrs use the star format. note we only save some variants... */ |
1670 |
{ "SCHILY.xattr", xattr_coder, xattr_decoder, 0, true }, |
1569 |
|
1671 |
|
1570 |
{ NULL, NULL, NULL, 0 } |
1672 |
{ NULL, NULL, NULL, 0, false } |
1571 |
}; |
1673 |
}; |