1234 lines
37 KiB
Diff
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;
|
|
+}
|