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; +}