summaryrefslogtreecommitdiffstats
path: root/lib/libarchive/archive_entry.c
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2006-03-21 16:55:46 +0000
committerkientzle <kientzle@FreeBSD.org>2006-03-21 16:55:46 +0000
commit537ab73b2f9d8cc3e849014fd44738b6a48f6c99 (patch)
treec3aca38252d2ed10ab3875ada2f51f284743c856 /lib/libarchive/archive_entry.c
parentb09a8950a1301d97aef8e2975e34a3ba5bc451c3 (diff)
downloadFreeBSD-src-537ab73b2f9d8cc3e849014fd44738b6a48f6c99.zip
FreeBSD-src-537ab73b2f9d8cc3e849014fd44738b6a48f6c99.tar.gz
POSIX.1e-style Extended Attribute support
This commit implements storing/reading POSIX.1e-style extended attribute information in "pax" format archives. An outline of the storage format is in the tar.5 manpage. The archive_read_extract() function has code to restore those archives to disk for Linux; FreeBSD implementation is forthcoming. Many thanks to Jaakko Heinonen for finding flaws in earlier proposals and doing the bulk of the coding in this work.
Diffstat (limited to 'lib/libarchive/archive_entry.c')
-rw-r--r--lib/libarchive/archive_entry.c113
1 files changed, 109 insertions, 4 deletions
diff --git a/lib/libarchive/archive_entry.c b/lib/libarchive/archive_entry.c
index de7238d..c67c64b 100644
--- a/lib/libarchive/archive_entry.c
+++ b/lib/libarchive/archive_entry.c
@@ -59,13 +59,13 @@ static size_t wcslen(const wchar_t *s)
static wchar_t * wcscpy(wchar_t *s1, const wchar_t *s2)
{
wchar_t *dest = s1;
- while((*s1 = *s2) != L'\0')
+ while ((*s1 = *s2) != L'\0')
++s1, ++s2;
return dest;
}
-#define wmemcpy(a,b,i) (wchar_t *)memcpy((a),(b),(i)*sizeof(wchar_t))
+#define wmemcpy(a,b,i) (wchar_t *)memcpy((a), (b), (i) * sizeof(wchar_t))
/* Good enough for simple equality testing, but not for sorting. */
-#define wmemcmp(a,b,i) memcmp((a),(b),(i)*sizeof(wchar_t))
+#define wmemcmp(a,b,i) memcmp((a), (b), (i) * sizeof(wchar_t))
#endif
#include "archive.h"
@@ -97,6 +97,14 @@ struct ae_acl {
struct aes name; /* uname/gname */
};
+struct ae_xattr {
+ struct ae_xattr *next;
+
+ char *name;
+ void *value;
+ size_t size;
+};
+
static void aes_clean(struct aes *);
static void aes_copy(struct aes *dest, struct aes *src);
static const char * aes_get_mbs(struct aes *);
@@ -170,6 +178,9 @@ struct archive_entry {
struct ae_acl *acl_p;
int acl_state; /* See acl_next for details. */
wchar_t *acl_text_w;
+
+ struct ae_xattr *xattr_head;
+ struct ae_xattr *xattr_p;
};
static void
@@ -332,6 +343,7 @@ archive_entry_clear(struct archive_entry *entry)
aes_clean(&entry->ae_symlink);
aes_clean(&entry->ae_uname);
archive_entry_acl_clear(entry);
+ archive_entry_xattr_clear(entry);
memset(entry, 0, sizeof(*entry));
return entry;
}
@@ -358,6 +370,7 @@ archive_entry_clone(struct archive_entry *entry)
aes_copy(&entry2->ae_uname, &entry->ae_uname);
/* XXX TODO: Copy ACL data over as well. XXX */
+ /* XXX TODO: Copy xattr data over as well. XXX */
return (entry2);
}
@@ -1054,7 +1067,7 @@ archive_entry_acl_text_w(struct archive_entry *entry, int flags)
length ++; /* colon */
length += 3; /* rwx */
length += 1; /* colon */
- length += max(sizeof(uid_t),sizeof(gid_t)) * 3 + 1;
+ length += max(sizeof(uid_t), sizeof(gid_t)) * 3 + 1;
length ++; /* newline */
}
ap = ap->next;
@@ -1346,6 +1359,98 @@ fail:
}
/*
+ * extended attribute handling
+ */
+
+void
+archive_entry_xattr_clear(struct archive_entry *entry)
+{
+ struct ae_xattr *xp;
+
+ while (entry->xattr_head != NULL) {
+ xp = entry->xattr_head->next;
+ free(entry->xattr_head->name);
+ free(entry->xattr_head->value);
+ free(entry->xattr_head);
+ entry->xattr_head = xp;
+ }
+
+ entry->xattr_head = NULL;
+}
+
+void
+archive_entry_xattr_add_entry(struct archive_entry *entry,
+ const char *name, const void *value, size_t size)
+{
+ struct ae_xattr *xp;
+
+ for (xp = entry->xattr_head; xp != NULL; xp = xp->next)
+ ;
+
+ if ((xp = malloc(sizeof(struct ae_xattr))) == NULL)
+ /* XXX Error XXX */
+ return;
+
+ xp->name = strdup(name);
+ if ((xp -> value = malloc(size)) != NULL) {
+ memcpy(xp -> value, value, size);
+ xp -> size = size;
+ } else
+ xp -> size = 0;
+
+ xp->next = entry->xattr_head;
+ entry->xattr_head = xp;
+}
+
+
+/*
+ * returns number of the extended attribute entries
+ */
+int
+archive_entry_xattr_count(struct archive_entry *entry)
+{
+ struct ae_xattr *xp;
+ int count = 0;
+
+ for (xp = entry->xattr_head; xp != NULL; xp = xp->next)
+ count++;
+
+ return count;
+}
+
+int
+archive_entry_xattr_reset(struct archive_entry * entry)
+{
+ entry->xattr_p = entry->xattr_head;
+
+ return archive_entry_xattr_count(entry);
+}
+
+int
+archive_entry_xattr_next(struct archive_entry * entry,
+ const char **name, const void **value, size_t *size)
+{
+ if (entry->xattr_p) {
+ *name = entry->xattr_p->name;
+ *value = entry->xattr_p->value;
+ *size = entry->xattr_p->size;
+
+ entry->xattr_p = entry->xattr_p->next;
+
+ return (ARCHIVE_OK);
+ } else {
+ *name = NULL;
+ *name = NULL;
+ *size = (size_t)0;
+ return (ARCHIVE_WARN);
+ }
+}
+
+/*
+ * end of xattr handling
+ */
+
+/*
* Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated
* to point to just after the separator. *start points to the first
* character of the matched text and *end just after the last
OpenPOWER on IntegriCloud