[PATCH 2/5] Add extended attribute support to mtree
From: Matthew Garrett <matthew.garrett@google.com>
Add support for parsing extended attributes out of mtree data.
---
lib/mtree/misc.c | 10 +++++++++-
lib/mtree/mtree.h | 26 +++++++++++++++++---------
lib/mtree/spec.c | 18 ++++++++++++++++++
3 files changed, 44 insertions(+), 10 deletions(-)
diff --git a/lib/mtree/misc.c b/lib/mtree/misc.c
index fc2124f2b..207158565 100644
--- a/lib/mtree/misc.c
+++ b/lib/mtree/misc.c
@@ -51,6 +51,7 @@ typedef struct _key {
u_int val; /* value */
#define NEEDVALUE 0x01
+#define PREFIX 0x02
u_int flags;
} KEY;
@@ -72,6 +73,7 @@ static KEY keylist[] = {
{"type", F_TYPE, NEEDVALUE},
{"uid", F_UID, NEEDVALUE},
{"uname", F_UNAME, NEEDVALUE},
+ {"xattr", F_XATTR, NEEDVALUE|PREFIX},
};
int keycompare(const void *, const void *);
@@ -95,7 +97,13 @@ parsekey(char *name, int *needvaluep)
int
keycompare(const void *a, const void *b)
{
- return (strcmp(((const KEY *)a)->name, ((const KEY *)b)->name));
+ const KEY *k = (const KEY *)b;
+
+ if (k->flags & PREFIX)
+ return (strncmp(((const KEY *)a)->name, k->name,
+ strlen(k->name)));
+ else
+ return (strcmp(((const KEY *)a)->name, k->name));
}
char *
diff --git a/lib/mtree/mtree.h b/lib/mtree/mtree.h
index e78a4fa6c..fb66b3c45 100644
--- a/lib/mtree/mtree.h
+++ b/lib/mtree/mtree.h
@@ -45,6 +45,11 @@
#define MISMATCHEXIT 2
+struct xattr {
+ char *name;
+ char *value;
+};
+
typedef struct _node {
struct _node *parent, *child; /* up, down */
struct _node *prev, *next; /* left, right */
@@ -53,6 +58,8 @@ typedef struct _node {
u_long cksum; /* check sum */
char *md5digest; /* MD5 digest */
char *slink; /* symbolic link reference */
+ struct xattr *xattrs; /* extended attributes */
+ int xattr_num; /* number of xattrs */
uid_t st_uid; /* uid */
gid_t st_gid; /* gid */
#define MBITS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)
@@ -68,15 +75,16 @@ typedef struct _node {
#define F_MAGIC 0x000020 /* name has magic chars */
#define F_MODE 0x000040 /* mode */
#define F_NLINK 0x000080 /* number of hardlinks */
-#define F_SIZE 0x000100 /* size */
-#define F_SLINK 0x000200 /* symbolic link path */
-#define F_TIME 0x000400 /* modification time */
-#define F_TYPE 0x000800 /* file type */
-#define F_UID 0x001000 /* uid */
-#define F_UNAME 0x002000 /* user name */
-#define F_VISIT 0x004000 /* file visited */
-#define F_MD5 0x008000 /* MD5 digest */
-#define F_NOCHANGE 0x010000 /* If owner/mode "wrong", do */
+#define F_XATTR 0x000100 /* extended attribute */
+#define F_SIZE 0x000200 /* size */
+#define F_SLINK 0x000400 /* symbolic link path */
+#define F_TIME 0x000800 /* modification time */
+#define F_TYPE 0x001000 /* file type */
+#define F_UID 0x002000 /* uid */
+#define F_UNAME 0x004000 /* user name */
+#define F_VISIT 0x008000 /* file visited */
+#define F_MD5 0x010000 /* MD5 digest */
+#define F_NOCHANGE 0x020000 /* If owner/mode "wrong", do */
/* not change */
#define F_FLAGS 0x080000 /* file flags */
#define F_OPT 0x200000 /* existence optional */
diff --git a/lib/mtree/spec.c b/lib/mtree/spec.c
index 47d2bc636..fb2ea78a5 100644
--- a/lib/mtree/spec.c
+++ b/lib/mtree/spec.c
@@ -294,6 +294,24 @@ set(char *t, NODE *ip)
errx(1, "line %d: unknown user %s", lineno, val);
ip->st_uid = pw->pw_uid;
break;
+ case F_XATTR:
+ /* Verify that there's an actual xattr name */
+ if (strlen(kw) < strlen("xattr."))
+ continue;
+ ip->xattrs = realloc(ip->xattrs, (ip->xattr_num + 1)
+ * sizeof(struct xattr));
+ if (!ip->xattrs)
+ errx(1, "realloc");
+ /* Skip the prefix when setting the name */
+ ip->xattrs[ip->xattr_num].name = strdup(kw +
+ strlen("xattr."));
+ if(!ip->xattrs[ip->xattr_num].name)
+ errx(1, "strdup");
+ ip->xattrs[ip->xattr_num].value = strdup(val);
+ if(!ip->xattrs[ip->xattr_num].value)
+ errx(1, "strdup");
+ ip->xattr_num++;
+ break;
}
}
}
--
2.17.0.441.gb46fe60e1d-goog
Reply to: