src/server/util/libxattr.c

Wed, 05 Jun 2024 19:50:44 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 05 Jun 2024 19:50:44 +0200
changeset 537
ad44e72fbf50
parent 480
9f69e4b8b695
permissions
-rw-r--r--

add extra nullptr check in the event loop to handle the case when the finish ptr is set to NULL after it was already scheduled

480
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
3 *
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
4 * Copyright 2018 Olaf Wintermann. All rights reserved.
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
5 *
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
8 *
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
11 *
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
15 *
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27 */
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
29 #define _GNU_SOURCE
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
30
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
31 #include <stdio.h>
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
32 #include <stdlib.h>
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
33
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
34 #include "libxattr.h"
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
35
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
36 #include <errno.h>
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
37 #include <sys/types.h>
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
38
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
39 #include <string.h>
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
40
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
41 #define LIST_BUF_LEN 1024
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
42 #define LIST_ARRAY_LEN 8
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
43 #define ATTR_BUF_LEN 1024
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
44
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
45 #define ARRAY_ADD(array, pos, len, obj) if(pos >= len) { \
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
46 len *= 2; /* TODO: missing error handling for realloc() */ \
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
47 array = realloc(array, len * sizeof(char*)); \
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
48 } \
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
49 array[pos] = obj; \
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
50 pos++;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
51
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
52 static void* libxattr_malloc(void *unused, size_t size) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
53 return malloc(size);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
54 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
55
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
56 static void libxattr_free(void *unused, void *ptr) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
57 free(ptr);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
58 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
59
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
60
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
61 #ifdef __linux__
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
62 #define XATTR_SUPPORTED
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
63 #include <sys/xattr.h>
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
64
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
65 static char ** parse_xattrlist(char *buf, ssize_t length, ssize_t *nelm) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
66 size_t arraylen = LIST_ARRAY_LEN;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
67 size_t arraypos = 0;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
68 char **array = malloc(LIST_ARRAY_LEN * sizeof(char*));
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
69
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
70 char *begin = buf;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
71 char *name = NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
72 for(int i=0;i<length;i++) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
73 if(!name && buf[i] == '.') {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
74 int nslen = (buf+i-begin);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
75 //printf("%.*s\n", nslen, begin);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
76 name = buf + i + 1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
77 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
78 if(buf[i] == '\0') {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
79 char *attrname = strdup(name);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
80 ARRAY_ADD(array, arraypos, arraylen, attrname);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
81 begin = buf + i + 1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
82 name = 0;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
83 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
84 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
85
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
86 if(arraypos == 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
87 free(array);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
88 array = NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
89 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
90
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
91 *nelm = arraypos;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
92 return array;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
93 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
94
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
95 char ** xattr_list(const char *path, ssize_t *nelm) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
96 char *list = malloc(LIST_BUF_LEN);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
97 ssize_t len = listxattr(path, list, LIST_BUF_LEN);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
98 if(len == -1) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
99 switch(errno) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
100 case ERANGE: {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
101 // buffer too, get size of attribute list
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
102 ssize_t newlen = listxattr(path, NULL, 0);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
103 if(newlen > 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
104 // second try
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
105 list = realloc(list, newlen);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
106 len = listxattr(path, list, newlen);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
107 if(len != -1) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
108 // this time it worked
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
109 break;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
110 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
111 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
112 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
113 default: {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
114 free(list);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
115 *nelm = -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
116 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
117 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
118 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
119 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
120
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
121 char **ret = parse_xattrlist(list, len, nelm);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
122 free(list);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
123 return ret;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
124 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
125
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
126 static char* name2nsname(const char *name) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
127 // add the 'user' namespace to the name
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
128 size_t namelen = strlen(name);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
129 char *attrname = malloc(8 + namelen);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
130 if(!attrname) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
131 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
132 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
133 memcpy(attrname, "user.", 5);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
134 memcpy(attrname+5, name, namelen + 1);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
135 return attrname;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
136 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
137
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
138 char * xattr_get_alloc(
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
139 void *pool,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
140 libxattr_malloc_func malloc_func,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
141 libxattr_free_func free_func,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
142 const char *path,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
143 const char *attr,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
144 ssize_t *len)
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
145 {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
146 char *buf = malloc_func(pool, ATTR_BUF_LEN);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
147 if(!buf) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
148 *len = -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
149 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
150 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
151
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
152 char *attrname = name2nsname(attr);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
153 if(!attrname) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
154 free_func(pool, buf);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
155 *len = -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
156 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
157 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
158
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
159 ssize_t vlen = getxattr(path, attrname, buf, ATTR_BUF_LEN - 1);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
160 if(vlen < 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
161 switch(errno) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
162 case ERANGE: {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
163 ssize_t attrlen = getxattr(path, attrname, NULL, 0);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
164 if(attrlen > 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
165 free_func(pool, buf);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
166 buf = malloc_func(pool, attrlen + 1);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
167 if(!buf) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
168 free(attrname);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
169 *len = -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
170 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
171 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
172 vlen = getxattr(path, attrname, buf, attrlen);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
173 if(vlen > 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
174 break;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
175 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
176 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
177 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
178 default: {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
179 *len = -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
180 free_func(pool, buf);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
181 free(attrname);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
182 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
183 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
184 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
185 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
186 buf[vlen] = 0;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
187
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
188 free(attrname);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
189 *len = vlen;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
190 return buf;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
191 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
192
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
193 int xattr_set(const char *path, const char *name, const void *value, size_t len) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
194 char *attrname = name2nsname(name);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
195 int ret = setxattr(path, attrname, value, len, 0);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
196 free(attrname);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
197 return ret;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
198 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
199
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
200 int xattr_remove(const char *path, const char *name) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
201 char *attrname = name2nsname(name);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
202 int ret = removexattr(path, attrname);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
203 free(attrname);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
204 return ret;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
205 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
206
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
207 #endif /* Linux */
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
208
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
209 #ifdef __APPLE__
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
210 #define XATTR_SUPPORTED
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
211 #include <sys/xattr.h>
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
212
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
213 static char ** parse_xattrlist(char *buf, ssize_t length, ssize_t *nelm) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
214 size_t arraylen = LIST_ARRAY_LEN;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
215 size_t arraypos = 0;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
216 char **array = malloc(LIST_ARRAY_LEN * sizeof(char*));
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
217
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
218 char *name = buf;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
219 for(int i=0;i<length;i++) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
220 if(buf[i] == '\0') {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
221 char *attrname = strdup(name);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
222 ARRAY_ADD(array, arraypos, arraylen, attrname);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
223 name = buf + i + 1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
224 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
225 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
226
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
227 if(arraypos == 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
228 free(array);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
229 array = NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
230 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
231
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
232 *nelm = arraypos;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
233 return array;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
234 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
235
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
236 char ** xattr_list(const char *path, ssize_t *nelm) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
237 char *list = malloc(LIST_BUF_LEN);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
238 ssize_t len = listxattr(path, list, LIST_BUF_LEN, 0);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
239 if(len == -1) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
240 switch(errno) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
241 case ERANGE: {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
242 // buffer too, get size of attribute list
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
243 ssize_t newlen = listxattr(path, NULL, 0, 0);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
244 if(newlen > 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
245 // second try
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
246 list = realloc(list, newlen);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
247 len = listxattr(path, list, newlen, 0);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
248 if(len != -1) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
249 // this time it worked
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
250 break;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
251 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
252 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
253 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
254 default: {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
255 free(list);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
256 *nelm = -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
257 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
258 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
259 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
260 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
261
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
262 char **ret = parse_xattrlist(list, len, nelm);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
263 free(list);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
264 return ret;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
265 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
266
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
267 char * xattr_get_alloc(
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
268 void *pool,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
269 libxattr_malloc_func malloc_func,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
270 libxattr_free_func free_func,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
271 const char *path,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
272 const char *attr,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
273 ssize_t *len)
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
274 {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
275 // get attribute length
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
276 ssize_t attrlen = getxattr(path, attr, NULL, 0, 0, 0);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
277 if(attrlen < 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
278 *len = -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
279 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
280 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
281
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
282 char *buf = malloc_func(pool, attrlen + 1);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
283 if(!buf) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
284 *len = -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
285 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
286 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
287
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
288 ssize_t vlen = getxattr(path, attr, buf, attrlen, 0, 0);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
289 if(vlen < 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
290 *len = -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
291 free_func(pool, buf);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
292 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
293 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
294 buf[attrlen] = 0;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
295
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
296 *len = vlen;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
297 return buf;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
298 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
299
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
300 int xattr_set(const char *path, const char *name, const void *value, size_t len) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
301 int ret = setxattr(path, name, value, len, 0, 0);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
302 return ret;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
303 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
304
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
305 int xattr_remove(const char *path, const char *name) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
306 return removexattr(path, name, 0);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
307 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
308
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
309 #endif /* Apple */
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
310
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
311 #ifdef __sun
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
312 #define XATTR_SUPPORTED
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
313 #include <unistd.h>
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
314 #include <sys/types.h>
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
315 #include <sys/stat.h>
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
316 #include <dirent.h>
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
317 #include <fcntl.h>
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
318
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
319 static int open_attrfile(const char *path, const char *attr, int oflag) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
320 int file = open(path, O_RDONLY);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
321 if(file == -1) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
322 return -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
323 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
324
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
325 int attrfile = openat(file, attr, oflag, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
326 close(file);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
327 return attrfile;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
328 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
329
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
330 char ** xattr_list(const char *path, ssize_t *nelm) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
331 *nelm = -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
332
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
333 int attrdir = open_attrfile(path, ".", O_RDONLY|O_XATTR);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
334 if(attrdir == -1) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
335 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
336 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
337
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
338 DIR *dir = fdopendir(attrdir);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
339 if(!dir) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
340 close(attrdir);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
341 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
342 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
343
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
344 size_t arraylen = LIST_ARRAY_LEN;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
345 size_t arraypos = 0;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
346 char **array = malloc(LIST_ARRAY_LEN * sizeof(char*));
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
347
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
348 struct dirent *ent;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
349 while((ent = readdir(dir)) != NULL) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
350 if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..") || !strcmp(ent->d_name, "SUNWattr_ro") || !strcmp(ent->d_name, "SUNWattr_rw")) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
351 continue;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
352 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
353 char *name = strdup(ent->d_name);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
354 ARRAY_ADD(array, arraypos, arraylen, name);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
355 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
356 closedir(dir);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
357
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
358 *nelm = arraypos;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
359 return array;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
360 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
361
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
362 char * xattr_get_alloc(
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
363 void *pool,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
364 libxattr_malloc_func malloc_func,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
365 libxattr_free_func free_func,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
366 const char *path,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
367 const char *attr,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
368 ssize_t *len)
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
369 {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
370 *len = -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
371
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
372 int attrfile = open_attrfile(path, attr, O_RDONLY|O_XATTR);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
373 if(attrfile == -1) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
374 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
375 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
376
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
377 struct stat s;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
378 if(fstat(attrfile, &s)) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
379 close(attrfile);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
380 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
381 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
382
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
383 size_t bufsize = (size_t)s.st_size;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
384 char *buf = malloc_func(pool, bufsize);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
385
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
386 char *b = buf;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
387 size_t cur = 0;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
388 while(cur < bufsize) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
389 ssize_t r = read(attrfile, buf + cur, bufsize - cur);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
390 if(r <= 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
391 break;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
392 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
393 cur += r;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
394 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
395
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
396 close(attrfile);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
397 if(cur != bufsize) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
398 free_func(pool, buf);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
399 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
400 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
401
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
402 *len = (ssize_t)bufsize;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
403 return buf;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
404 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
405
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
406 int xattr_set(const char *path, const char *name, const void *value, size_t len) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
407 int attrfile = open_attrfile(path, name, O_CREAT|O_WRONLY|O_XATTR|O_TRUNC);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
408 if(attrfile == -1) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
409 return -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
410 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
411
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
412 const char *p = value;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
413 size_t remaining = len;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
414 while(remaining > 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
415 ssize_t w = write(attrfile, p, remaining);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
416 if(w <= 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
417 break;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
418 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
419 p += w;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
420 remaining -= w;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
421 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
422
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
423 close(attrfile);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
424
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
425 return remaining > 0 ? -1 : 0;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
426 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
427
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
428 int xattr_remove(const char *path, const char *name) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
429 int attrdir = open_attrfile(path, ".", O_RDONLY|O_XATTR);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
430 if(attrdir == -1) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
431 return -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
432 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
433
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
434 int ret = unlinkat(attrdir, name, 0);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
435 close(attrdir);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
436 return ret;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
437 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
438
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
439 #endif /* Sun */
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
440
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
441
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
442 #ifdef __FreeBSD__
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
443 #define XATTR_SUPPORTED
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
444
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
445 #include <sys/types.h>
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
446 #include <sys/extattr.h>
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
447
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
448 static char ** parse_xattrlist(char *buf, ssize_t length, ssize_t *nelm) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
449 size_t arraylen = LIST_ARRAY_LEN;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
450 size_t arraypos = 0;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
451 char **array = malloc(LIST_ARRAY_LEN * sizeof(char*));
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
452
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
453 char *name = buf;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
454 for(int i=0;i<length;i++) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
455 char namelen = buf[i];
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
456 char *name = buf + i + 1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
457 char *attrname = malloc(namelen + 1);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
458 memcpy(attrname, name, namelen);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
459 attrname[namelen] = 0;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
460 ARRAY_ADD(array, arraypos, arraylen, attrname);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
461 i += namelen;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
462 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
463
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
464 if(arraypos == 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
465 free(array);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
466 array = NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
467 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
468
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
469 *nelm = arraypos;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
470 return array;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
471 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
472
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
473 char ** xattr_list(const char *path, ssize_t *nelm) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
474 *nelm = -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
475 ssize_t lslen = extattr_list_file(path, EXTATTR_NAMESPACE_USER, NULL, 0);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
476 if(lslen <= 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
477 if(lslen == 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
478 *nelm = 0;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
479 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
480 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
481 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
482
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
483 char *list = malloc(lslen);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
484 ssize_t len = extattr_list_file(path, EXTATTR_NAMESPACE_USER, list, lslen);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
485 if(len == -1) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
486 free(list);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
487 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
488 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
489
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
490 char **ret = parse_xattrlist(list, len, nelm);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
491 free(list);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
492 return ret;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
493 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
494
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
495 char * xattr_get_alloc(
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
496 void *pool,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
497 libxattr_malloc_func malloc_func,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
498 libxattr_free_func free_func,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
499 const char *path,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
500 const char *attr,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
501 ssize_t *len)
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
502 {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
503 // get attribute length
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
504 ssize_t attrlen = extattr_get_file(path, EXTATTR_NAMESPACE_USER, attr, NULL, 0);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
505 if(attrlen < 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
506 *len = -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
507 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
508 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
509
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
510 char *buf = malloc_func(pool, attrlen + 1);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
511 ssize_t vlen = extattr_get_file(path, EXTATTR_NAMESPACE_USER, attr, buf, attrlen);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
512 if(vlen < 0) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
513 *len = -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
514 free_func(pool, buf);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
515 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
516 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
517 buf[attrlen] = 0;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
518
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
519 *len = vlen;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
520 return buf;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
521 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
522
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
523 int xattr_set(const char *path, const char *name, const void *value, size_t len) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
524 int ret = extattr_set_file(path, EXTATTR_NAMESPACE_USER, name, value, len);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
525 return ret;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
526 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
527
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
528 int xattr_remove(const char *path, const char *name) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
529 return extattr_delete_file(path, EXTATTR_NAMESPACE_USER, name);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
530 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
531
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
532 #endif /* FreeBSD */
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
533
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
534
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
535 #ifndef XATTR_SUPPORTED
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
536
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
537 char ** xattr_list(const char *path, ssize_t *nelm) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
538 *nelm = -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
539 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
540 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
541
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
542 char * xattr_get_alloc(
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
543 void *pool,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
544 libxattr_malloc_func malloc_func,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
545 libxattr_free_func free_func,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
546 const char *path,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
547 const char *attr,
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
548 ssize_t *len)
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
549 {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
550 *len = -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
551 return NULL;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
552 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
553
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
554 int xattr_set(const char *path, const char *name, const void *value, size_t len) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
555 return -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
556 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
557
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
558 int xattr_remove(const char *path, const char *name) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
559 return -1;
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
560 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
561
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
562 #endif /* unsupported platform */
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
563
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
564
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
565 char * xattr_get(const char *path, const char *attr, ssize_t *len) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
566 return xattr_get_alloc(NULL, libxattr_malloc, libxattr_free, path, attr, len);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
567 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
568
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
569 void xattr_free_list(char **attrnames, ssize_t nelm) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
570 if(attrnames) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
571 for(int i=0;i<nelm;i++) {
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
572 free(attrnames[i]);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
573 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
574 free(attrnames);
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
575 }
9f69e4b8b695 add libxattr
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
576 }

mercurial