mds/dev-libs/apr/files/apr-xattr-impl.patch

1234 lines
37 KiB
Diff

Index: xattr/unix/xattr.c
===================================================================
--- xattr/unix/xattr.c (revision 0)
+++ xattr/unix/xattr.c (revision 0)
@@ -0,0 +1,165 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_private.h"
+#include "apr_tables.h"
+
+#if USE_XATTR_DARWIN || USE_XATTR_FREEBSD || USE_XATTR_LINUX || \
+ USE_XATTR_SOLARIS
+
+#include "apr_arch_file_io.h"
+#include "apr_arch_xattr.h"
+
+#include "apr_file_xattr.h"
+
+
+static apr_status_t xattr_cleanup(void *xattr)
+{
+ close(((apr_xattr_t*)xattr)->fd);
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_open_path(apr_xattr_t **new,
+ const char *pathname,
+ apr_pool_t *p)
+{
+ int fd;
+ int osflags = 0;
+
+ fd = open(pathname, XATTR_OPEN_FLAGS);
+ if (fd < 0) {
+ return errno;
+ }
+
+ *new = apr_palloc(p, sizeof(apr_xattr_t));
+ (*new)->fd = fd;
+ (*new)->flags = 0;
+ (*new)->pool = p;
+
+ apr_pool_cleanup_register((*new)->pool, (void *)(*new),
+ xattr_cleanup, xattr_cleanup);
+
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_open_file(apr_xattr_t **new,
+ apr_file_t *file,
+ apr_pool_t *p)
+{
+ *new = apr_palloc(p, sizeof(apr_xattr_t));
+ (*new)->fd = file->filedes;
+ (*new)->flags = APR_FILE_NOCLEANUP;
+ (*new)->pool = p;
+
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_open_dir(apr_xattr_t **new,
+ apr_dir_t *dir,
+ apr_pool_t *p)
+{
+ *new = apr_palloc(p, sizeof(apr_xattr_t));
+ (*new)->fd = dirfd(dir->dirstruct);
+ (*new)->flags = APR_FILE_NOCLEANUP;
+ (*new)->pool = p;
+
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_destroy(apr_xattr_t *xattr)
+{
+ if (!(xattr->flags & APR_FILE_NOCLEANUP)) {
+ return apr_pool_cleanup_run(xattr->pool, xattr, xattr_cleanup);
+ }
+ return APR_SUCCESS;
+}
+
+#else
+
+#include "apr_file_xattr.h"
+
+
+APR_DECLARE(apr_status_t) apr_xattr_open_path(apr_xattr_t **new,
+ const char *pathname,
+ apr_pool_t *p)
+{
+ *new = NULL;
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_open_file(apr_xattr_t **new,
+ apr_file_t *file,
+ apr_pool_t *p)
+{
+ *new = NULL;
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_open_dir(apr_xattr_t **new,
+ apr_dir_t *dir,
+ apr_pool_t *p)
+{
+ *new = NULL;
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_destroy(apr_xattr_t *xattr)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_set(const apr_xattr_t *xattr,
+ const char *name,
+ const void *value,
+ apr_size_t size,
+ apr_uint32_t flags)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_get(const apr_xattr_t *xattr,
+ const char *name,
+ void **value,
+ apr_size_t *size,
+ apr_uint32_t flags)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_exists(const apr_xattr_t *xattr,
+ const char *name,
+ int *exists,
+ apr_uint32_t flags)
+{
+ *exists = 0;
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_list(const apr_xattr_t *xattr,
+ apr_array_header_t **list,
+ apr_uint32_t flags)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_remove(const apr_xattr_t *xattr,
+ const char *name,
+ apr_uint32_t flags)
+{
+ return APR_ENOTIMPL;
+}
+
+#endif
Index: xattr/unix/darwin.c
===================================================================
--- xattr/unix/darwin.c (revision 0)
+++ xattr/unix/darwin.c (revision 0)
@@ -0,0 +1,143 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_private.h"
+
+#if USE_XATTR_DARWIN
+
+#include "apr_arch_xattr.h"
+
+#include "apr_strings.h"
+#include "apr_tables.h"
+#include "apr_file_xattr.h"
+
+
+APR_DECLARE(apr_status_t) apr_xattr_set(const apr_xattr_t *xattr,
+ const char *name,
+ const void *value,
+ apr_size_t size,
+ apr_uint32_t flags)
+{
+ int ret;
+ int osflags = 0;
+
+ if (flags & APR_XATTR_CREATE) {
+ osflags |= XATTR_CREATE;
+ }
+ if (flags & APR_XATTR_REPLACE) {
+ osflags |= XATTR_REPLACE;
+ }
+
+ ret = fsetxattr(xattr->fd, name, value, size, 0, osflags);
+
+ if (ret < 0) {
+ return errno;
+ }
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_get(const apr_xattr_t *xattr,
+ const char *name,
+ void **value,
+ apr_size_t *size,
+ apr_uint32_t flags)
+{
+ apr_ssize_t ret;
+
+ ret = fgetxattr(xattr->fd, name, NULL, 0, 0, 0);
+
+ if (ret < 0) {
+ return errno;
+ }
+ *value = apr_palloc(xattr->pool, ret);
+
+ ret = fgetxattr(xattr->fd, name, *value, ret, 0, 0);
+
+ if (ret < 0) {
+ return errno;
+ }
+ *size = ret;
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_exists(const apr_xattr_t *xattr,
+ const char *name,
+ int *exists,
+ apr_uint32_t flags)
+{
+ apr_ssize_t ret;
+
+ ret = fgetxattr(xattr->fd, name, NULL, 0, 0, 0);
+
+ if (ret < 0) {
+ *exists = 0;
+ if (errno == ENOATTR) {
+ return APR_SUCCESS;
+ }
+ return errno;
+ }
+ *exists = 1;
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_list(const apr_xattr_t *xattr,
+ apr_array_header_t **list,
+ apr_uint32_t flags)
+{
+ apr_ssize_t lsize;
+ char *listbuf, *listp;
+
+ lsize = flistxattr(xattr->fd, NULL, 0, 0);
+
+ if (lsize < 0) {
+ return errno;
+ }
+ if (lsize == 0) {
+ *list = apr_array_make(xattr->pool, 0, sizeof(char*));
+ return APR_SUCCESS;
+ }
+ listbuf = apr_palloc(xattr->pool, lsize);
+
+ lsize = flistxattr(xattr->fd, listbuf, lsize, 0);
+
+ if (lsize < 0) {
+ return errno;
+ }
+ *list = apr_array_make(xattr->pool, 1, sizeof(char*));
+ listp = listbuf;
+ while (listp < listbuf + lsize) {
+ int attrlen = strlen(listp) + 1;
+ *(char**)apr_array_push(*list) = listp;
+ listp += attrlen;
+ }
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_remove(const apr_xattr_t *xattr,
+ const char *name,
+ apr_uint32_t flags)
+{
+ int ret;
+
+ ret = fremovexattr(xattr->fd, name, 0);
+
+ if (ret < 0) {
+ return errno;
+ }
+ return APR_SUCCESS;
+}
+
+#endif /* USE_XATTR_DARWIN */
Index: xattr/unix/linux.c
===================================================================
--- xattr/unix/linux.c (revision 0)
+++ xattr/unix/linux.c (revision 0)
@@ -0,0 +1,156 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_private.h"
+
+#if USE_XATTR_LINUX
+
+#include "apr_arch_xattr.h"
+
+#include "apr_strings.h"
+#include "apr_tables.h"
+#include "apr_file_xattr.h"
+
+static const char* user_ns_prefix = "user.";
+
+
+APR_DECLARE(apr_status_t) apr_xattr_set(const apr_xattr_t *xattr,
+ const char *name,
+ const void *value,
+ apr_size_t size,
+ apr_uint32_t flags)
+{
+ int ret;
+ int osflags = 0;
+
+ char *tmpname = apr_pstrcat(xattr->pool, user_ns_prefix, name, NULL);
+
+ if (flags & APR_XATTR_CREATE) {
+ osflags |= XATTR_CREATE;
+ }
+ if (flags & APR_XATTR_REPLACE) {
+ osflags |= XATTR_REPLACE;
+ }
+
+ ret = fsetxattr(xattr->fd, tmpname, value, size, osflags);
+
+ if (ret < 0) {
+ return errno;
+ }
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_get(const apr_xattr_t *xattr,
+ const char *name,
+ void **value,
+ apr_size_t *size,
+ apr_uint32_t flags)
+{
+ apr_ssize_t ret;
+ char *tmpname = apr_pstrcat(xattr->pool, user_ns_prefix, name, NULL);
+
+ ret = fgetxattr(xattr->fd, tmpname, NULL, 0);
+
+ if (ret < 0) {
+ return errno;
+ }
+ *value = apr_palloc(xattr->pool, ret);
+
+ ret = fgetxattr(xattr->fd, tmpname, *value, ret);
+
+ if (ret < 0) {
+ return errno;
+ }
+ *size = ret;
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_exists(const apr_xattr_t *xattr,
+ const char *name,
+ int *exists,
+ apr_uint32_t flags)
+{
+ apr_ssize_t ret;
+ char *tmpname = apr_pstrcat(xattr->pool, user_ns_prefix, name, NULL);
+
+ ret = fgetxattr(xattr->fd, tmpname, NULL, 0);
+
+ if (ret < 0) {
+ *exists = 0;
+ if (errno == ENODATA) {
+ return APR_SUCCESS;
+ }
+ return errno;
+ }
+ *exists = 1;
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_list(const apr_xattr_t *xattr,
+ apr_array_header_t **list,
+ apr_uint32_t flags)
+{
+ apr_ssize_t lsize;
+ char *listbuf, *listp;
+
+ lsize = flistxattr(xattr->fd, NULL, 0);
+
+ if (lsize < 0) {
+ return errno;
+ }
+ if (lsize == 0) {
+ *list = apr_array_make(xattr->pool, 0, sizeof(char*));
+ return APR_SUCCESS;
+ }
+ listbuf = apr_palloc(xattr->pool, lsize);
+
+ lsize = flistxattr(xattr->fd, listbuf, lsize);
+
+ if (lsize < 0) {
+ return errno;
+ }
+ *list = apr_array_make(xattr->pool, 1, sizeof(char*));
+ listp = listbuf;
+ while (listp < listbuf + lsize) {
+ int attrlen = strlen(listp) + 1;
+ int user_ns_prefix_len = strlen(user_ns_prefix);
+ if (strncmp(listp, user_ns_prefix, user_ns_prefix_len) != 0) {
+ continue;
+ }
+ listp += user_ns_prefix_len;
+ attrlen -= user_ns_prefix_len;
+ *(char**)apr_array_push(*list) = listp;
+ listp += attrlen;
+ }
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_remove(const apr_xattr_t *xattr,
+ const char *name,
+ apr_uint32_t flags)
+{
+ int ret;
+ char *tmpname = apr_pstrcat(xattr->pool, user_ns_prefix, name, NULL);
+
+ ret = fremovexattr(xattr->fd, tmpname);
+
+ if (ret < 0) {
+ return errno;
+ }
+ return APR_SUCCESS;
+}
+
+#endif /* USE_XATTR_LINUX */
Index: xattr/unix/freebsd.c
===================================================================
--- xattr/unix/freebsd.c (revision 0)
+++ xattr/unix/freebsd.c (revision 0)
@@ -0,0 +1,162 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_private.h"
+
+#if USE_XATTR_FREEBSD
+
+#include "apr_arch_xattr.h"
+
+#include "apr_strings.h"
+#include "apr_tables.h"
+#include "apr_file_xattr.h"
+
+
+APR_DECLARE(apr_status_t) apr_xattr_set(const apr_xattr_t *xattr,
+ const char *name,
+ const void *value,
+ apr_size_t size,
+ apr_uint32_t flags)
+{
+ int ret;
+
+ if ((flags & APR_XATTR_CREATE) && (flags & APR_XATTR_REPLACE)) {
+ return APR_EINVAL;
+ }
+
+ if ((flags & APR_XATTR_CREATE) || (flags & APR_XATTR_REPLACE)) {
+
+ ret = extattr_get_fd(xattr->fd, EXTATTR_NAMESPACE_USER, name, NULL, 0);
+
+ if (ret >= 0 && (flags & APR_XATTR_CREATE)) {
+ return APR_EEXIST;
+ }
+ else if (ret == -1 && errno == ENOATTR) {
+ if (flags & APR_XATTR_REPLACE) {
+ return APR_ENOATTR;
+ }
+ }
+ else if (ret == -1) {
+ return errno;
+ }
+ }
+
+ ret = extattr_set_fd(xattr->fd, EXTATTR_NAMESPACE_USER, name, value, size);
+
+ if (ret < 0) {
+ return errno;
+ }
+
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_get(const apr_xattr_t *xattr,
+ const char *name,
+ void **value,
+ apr_size_t *size,
+ apr_uint32_t flags)
+{
+ int ret;
+
+ ret = extattr_get_fd(xattr->fd, EXTATTR_NAMESPACE_USER, name, NULL, 0);
+
+ if (ret < 0) {
+ return errno;
+ }
+ *value = apr_palloc(xattr->pool, ret);
+
+ ret = extattr_get_fd(xattr->fd, EXTATTR_NAMESPACE_USER, name, *value, ret);
+
+ if (ret < 0) {
+ return errno;
+ }
+ *size = ret;
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_exists(const apr_xattr_t *xattr,
+ const char *name,
+ int *exists,
+ apr_uint32_t flags)
+{
+ int ret;
+
+ ret = extattr_get_fd(xattr->fd, EXTATTR_NAMESPACE_USER, name, NULL, 0);
+
+ if (ret < 0) {
+ *exists = 0;
+ if (errno == ENOATTR) {
+ return APR_SUCCESS;
+ }
+ return errno;
+ }
+ *exists = 1;
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_list(const apr_xattr_t *xattr,
+ apr_array_header_t **list,
+ apr_uint32_t flags)
+{
+ int lsize;
+ char *listbuf, *listp;
+
+ lsize = extattr_list_fd(xattr->fd, EXTATTR_NAMESPACE_USER, NULL, 0);
+
+ if (lsize < 0) {
+ return errno;
+ }
+ if (lsize == 0) {
+ *list = apr_array_make(xattr->pool, 0, sizeof(char*));
+ return APR_SUCCESS;
+ }
+ listbuf = apr_palloc(xattr->pool, lsize);
+
+ lsize = extattr_list_fd(xattr->fd, EXTATTR_NAMESPACE_USER, listbuf, lsize);
+
+ if (lsize < 0) {
+ return errno;
+ }
+
+ *list = apr_array_make(xattr->pool, 1, sizeof(char*));
+ listp = listbuf;
+ while(listp < listbuf + lsize) {
+ /* first byte is the length of the attribute name and the
+ strings are not null terminated, so we copy them */
+ int attrlen = (int)*listp;
+ *(char**)apr_array_push(*list) = apr_pstrndup(xattr->pool, listp+1,
+ attrlen);
+ listp += (attrlen + 1);
+ }
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_remove(const apr_xattr_t *xattr,
+ const char *name,
+ apr_uint32_t flags)
+{
+ int ret;
+
+ ret = extattr_delete_fd(xattr->fd, EXTATTR_NAMESPACE_USER, name);
+
+ if (ret < 0) {
+ return errno;
+ }
+
+ return APR_SUCCESS;
+}
+
+#endif /* USE_XATTR_FREEBSD */
Index: xattr/unix/solaris.c
===================================================================
--- xattr/unix/solaris.c (revision 0)
+++ xattr/unix/solaris.c (revision 0)
@@ -0,0 +1,300 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_private.h"
+
+#if USE_XATTR_SOLARIS
+
+#include "apr_arch_xattr.h"
+#include "apr_arch_file_io.h"
+
+#include "apr_strings.h"
+#include "apr_tables.h"
+#include "apr_file_xattr.h"
+
+
+/* The following code is for escaping and unescaping '/' chars
+ (and '%' as it is used as an escape character) in attribute names.
+
+ This is because '/' can't be used in Solaris subfile names and doing
+ so could present a security risk as files could be opened elsewhere.
+*/
+
+static char nibble_to_hex(register char c)
+{
+ if (c >= 0 && c <= 9) return '0' + c;
+ if (c >= 10 && c <= 15) return 'a' + c - 10;
+ else return 0;
+}
+
+static char hex_to_nibble(register char c)
+{
+ if (c >= '0' && c <= '9') return c - '0';
+ if (c >= 'a' && c <= 'f') return c - 'a' + 10;
+ else if(c >= 'A' && c <= 'F') return c - 'A' + 10;
+ else return 0;
+}
+
+static const char* escape_attr_name(const char *name, apr_pool_t *p)
+{
+ const char *namep;
+ int hasspecial = 0;
+ apr_array_header_t *arr;
+
+ /* fastpath if atttrname contains no characters that need escaping */
+ if(strchr(name, '/') == NULL && strchr(name, '%') == NULL) {
+ return name;
+ }
+
+ /* start with a conservative amount of additional space */
+ arr = apr_array_make(p, strlen(name) + 16, sizeof(char));
+ namep = name;
+ while (*namep) {
+ if(*namep == '/' || *namep == '%') {
+ *(char*)apr_array_push(arr) = '%';
+ *(char*)apr_array_push(arr) = nibble_to_hex(*namep >> 4);
+ *(char*)apr_array_push(arr) = nibble_to_hex(*namep & 0x0f);
+ } else {
+ *(char*)apr_array_push(arr) = *namep;
+ }
+ namep++;
+ }
+ *(char*)apr_array_push(arr) = '\0';
+
+ return arr->elts;
+}
+
+static const char* unescape_attr_name(const char *name, apr_pool_t *p)
+{
+ const char *namep;
+ int hasspecial = 0;
+ apr_array_header_t *arr;
+
+ /* fastpath if atttrname contains no escaped characters */
+ if(strchr(name, '%') == NULL) {
+ return name;
+ }
+
+ /* start with a conservative amount of additional space */
+ arr = apr_array_make(p, strlen(name) + 16, sizeof(char));
+ namep = name;
+ while (*namep) {
+ if(*namep == '%' && *(namep+1) != 0 && *(namep+2) != 0) {
+ namep++;
+ *(char*)apr_array_push(arr) =
+ hex_to_nibble(*namep++) << 4 | hex_to_nibble(*namep++);
+ } else {
+ *(char*)apr_array_push(arr) = *namep++;
+ }
+ }
+ *(char*)apr_array_push(arr) = '\0';
+
+ return arr->elts;
+}
+
+
+APR_DECLARE(apr_status_t) apr_xattr_set(const apr_xattr_t *xattr,
+ const char *name,
+ const void *value,
+ apr_size_t size,
+ apr_uint32_t flags)
+{
+ int ret, fd, osflags;
+ struct_stat statbuf;
+
+ if (strncmp(name, "SUNW", 4) == 0) {
+ /* don't clash with sun namespace */
+ return EINVAL;
+ } else if (flags & APR_XATTR_CREATE && flags & APR_XATTR_REPLACE) {
+ return EINVAL;
+ } else if (flags & APR_XATTR_CREATE) {
+ osflags = O_CREAT | O_EXCL;
+ } else if (flags & APR_XATTR_REPLACE) {
+ osflags = 0;
+ } else {
+ osflags = O_CREAT;
+ }
+
+ fd = openat(xattr->fd, escape_attr_name(name, xattr->pool),
+ osflags | O_XATTR | O_TRUNC | O_WRONLY, 0666);
+
+ if (fd < 0) {
+ if(errno == ENOENT) {
+ return APR_ENOATTR;
+ }
+ return errno;
+ }
+
+ do {
+ ret = write(fd, value, size);
+ } while(ret < 0 && errno == EINTR);
+
+ if (ret < 0) {
+ ret = errno;
+ }
+ else if (ret != size) {
+ ret = APR_EGENERAL;
+ }
+ else {
+ ret = APR_SUCCESS;
+ }
+ close(fd);
+ return ret;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_get(const apr_xattr_t *xattr,
+ const char *name,
+ void **value,
+ apr_size_t *size,
+ apr_uint32_t flags)
+{
+ int ret, fd;
+ ssize_t rsize;
+ struct_stat statbuf;
+
+ fd = openat(xattr->fd, escape_attr_name(name, xattr->pool),
+ O_RDONLY | O_XATTR);
+ if (fd < 0) {
+ if(errno == ENOENT) {
+ return APR_ENOATTR;
+ }
+ return errno;
+ }
+
+ ret = fstat(fd, &statbuf);
+
+ if (ret < 0) {
+ ret = errno;
+ close(fd);
+ return ret;
+ }
+ *value = apr_palloc(xattr->pool, statbuf.st_size);
+
+ do {
+ rsize = read(fd, *value, statbuf.st_size);
+ } while(rsize < 0 && errno == EINTR);
+
+ if (rsize < 0) {
+ ret = errno;
+ }
+ else if (rsize != statbuf.st_size) {
+ ret = APR_EGENERAL;
+ }
+ else {
+ ret = APR_SUCCESS;
+ *size = rsize;
+ }
+ close(fd);
+ return ret;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_exists(const apr_xattr_t *xattr,
+ const char *name,
+ int *exists,
+ apr_uint32_t flags)
+{
+ int ret, fd;
+ ssize_t rsize;
+ struct_stat statbuf;
+
+ fd = openat(xattr->fd, escape_attr_name(name, xattr->pool),
+ O_RDONLY | O_XATTR);
+ if (fd < 0) {
+ *exists = 0;
+ if(errno == ENOENT) {
+ /* non-existant attribute does not return an error */
+ return APR_SUCCESS;
+ }
+ return errno;
+ }
+ *exists = 1;
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_list(const apr_xattr_t *xattr,
+ apr_array_header_t **list,
+ apr_uint32_t flags)
+{
+ int ret, fd;
+ DIR *dirp;
+ struct dirent *ent, *retent;
+ apr_size_t dirent_size =
+ sizeof(*ent) + (sizeof(ent->d_name) > 1 ? 0 : 255);
+
+ fd = openat(xattr->fd, ".", O_RDONLY | O_XATTR);
+
+ if (fd < 0) {
+ return errno;
+ }
+ dirp = fdopendir(fd);
+ if (dirp == NULL) {
+ ret = errno;
+ close(fd);
+ return ret;
+ }
+
+ *list = apr_array_make(xattr->pool, 1, sizeof(char*));
+ ent = apr_palloc(xattr->pool, dirent_size);
+ while ((ret = readdir_r(dirp, ent, &retent)) == 0 && retent) {
+ const char *name;
+ if (strncmp(ent->d_name, "SUNW", 4) == 0 || /* private */
+ strcmp(ent->d_name, ".") == 0 ||
+ strcmp(ent->d_name, "..") == 0) continue;
+
+ name = unescape_attr_name(ent->d_name, xattr->pool);
+ /* we don't need to copy if the name has been unescaped as it
+ is pool allocated memory already */
+ *(const char**)apr_array_push(*list) =
+ (name != ent->d_name) ?
+ name : apr_pstrdup(xattr->pool, ent->d_name);
+ }
+
+ if (ret < 0) {
+ ret = errno;
+ }
+ else {
+ ret = APR_SUCCESS;
+ }
+ closedir(dirp);
+ return ret;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_remove(const apr_xattr_t *xattr,
+ const char *name,
+ apr_uint32_t flags)
+{
+ int ret, fd;
+ struct_stat statbuf;
+
+ fd = openat(xattr->fd, ".", O_XATTR | O_RDONLY);
+
+ if (fd < 0) {
+ return errno;
+ }
+
+ ret = unlinkat(fd, escape_attr_name(name, xattr->pool), 0);
+
+ if (ret < 0) {
+ ret = (errno == ENOENT) ? APR_ENOATTR : errno;
+ }
+ else {
+ ret = APR_SUCCESS;
+ }
+ close(fd);
+ return ret;
+}
+
+#endif /* USE_XATTR_SOLARIS */
Index: xattr/netware/xattr.c
===================================================================
--- xattr/netware/xattr.c (revision 0)
+++ xattr/netware/xattr.c (revision 0)
@@ -0,0 +1,89 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_tables.h"
+#include "apr_file_xattr.h"
+
+
+APR_DECLARE(apr_status_t) apr_xattr_open_path(apr_xattr_t **new,
+ const char *pathname,
+ apr_pool_t *p)
+{
+ *new = NULL;
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_open_file(apr_xattr_t **new,
+ apr_file_t *file,
+ apr_pool_t *p)
+{
+ *new = NULL;
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_open_dir(apr_xattr_t **new,
+ apr_dir_t *dir,
+ apr_pool_t *p)
+{
+ *new = NULL;
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_destroy(apr_xattr_t *xattr)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_set(const apr_xattr_t *xattr,
+ const char *name,
+ const void *value,
+ apr_size_t size,
+ apr_uint32_t flags)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_get(const apr_xattr_t *xattr,
+ const char *name,
+ void **value,
+ apr_size_t *size,
+ apr_uint32_t flags)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_exists(const apr_xattr_t *xattr,
+ const char *name,
+ int *exists,
+ apr_uint32_t flags)
+{
+ *exists = 0;
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_list(const apr_xattr_t *xattr,
+ apr_array_header_t **list,
+ apr_uint32_t flags)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_remove(const apr_xattr_t *xattr,
+ const char *name,
+ apr_uint32_t flags)
+{
+ return APR_ENOTIMPL;
+}
Index: xattr/os2/xattr.c
===================================================================
--- xattr/os2/xattr.c (revision 0)
+++ xattr/os2/xattr.c (revision 0)
@@ -0,0 +1,89 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_tables.h"
+#include "apr_file_xattr.h"
+
+
+APR_DECLARE(apr_status_t) apr_xattr_open_path(apr_xattr_t **new,
+ const char *pathname,
+ apr_pool_t *p)
+{
+ *new = NULL;
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_open_file(apr_xattr_t **new,
+ apr_file_t *file,
+ apr_pool_t *p)
+{
+ *new = NULL;
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_open_dir(apr_xattr_t **new,
+ apr_dir_t *dir,
+ apr_pool_t *p)
+{
+ *new = NULL;
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_destroy(apr_xattr_t *xattr)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_set(const apr_xattr_t *xattr,
+ const char *name,
+ const void *value,
+ apr_size_t size,
+ apr_uint32_t flags)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_get(const apr_xattr_t *xattr,
+ const char *name,
+ void **value,
+ apr_size_t *size,
+ apr_uint32_t flags)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_exists(const apr_xattr_t *xattr,
+ const char *name,
+ int *exists,
+ apr_uint32_t flags)
+{
+ *exists = 0;
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_list(const apr_xattr_t *xattr,
+ apr_array_header_t **list,
+ apr_uint32_t flags)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_remove(const apr_xattr_t *xattr,
+ const char *name,
+ apr_uint32_t flags)
+{
+ return APR_ENOTIMPL;
+}
Index: xattr/win32/xattr.c
===================================================================
--- xattr/win32/xattr.c (revision 0)
+++ xattr/win32/xattr.c (revision 0)
@@ -0,0 +1,89 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_tables.h"
+#include "apr_file_xattr.h"
+
+
+APR_DECLARE(apr_status_t) apr_xattr_open_path(apr_xattr_t **new,
+ const char *pathname,
+ apr_pool_t *p)
+{
+ *new = NULL;
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_open_file(apr_xattr_t **new,
+ apr_file_t *file,
+ apr_pool_t *p)
+{
+ *new = NULL;
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_open_dir(apr_xattr_t **new,
+ apr_dir_t *dir,
+ apr_pool_t *p)
+{
+ *new = NULL;
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_destroy(apr_xattr_t *xattr)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_set(const apr_xattr_t *xattr,
+ const char *name,
+ const void *value,
+ apr_size_t size,
+ apr_uint32_t flags)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_get(const apr_xattr_t *xattr,
+ const char *name,
+ void **value,
+ apr_size_t *size,
+ apr_uint32_t flags)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_exists(const apr_xattr_t *xattr,
+ const char *name,
+ int *exists,
+ apr_uint32_t flags)
+{
+ *exists = 0;
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_list(const apr_xattr_t *xattr,
+ apr_array_header_t **list,
+ apr_uint32_t flags)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_xattr_remove(const apr_xattr_t *xattr,
+ const char *name,
+ apr_uint32_t flags)
+{
+ return APR_ENOTIMPL;
+}