[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[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: