diff options
Diffstat (limited to 'libglusterfs/src/compat.c')
-rw-r--r-- | libglusterfs/src/compat.c | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/libglusterfs/src/compat.c b/libglusterfs/src/compat.c new file mode 100644 index 00000000000..71aeb32c780 --- /dev/null +++ b/libglusterfs/src/compat.c @@ -0,0 +1,383 @@ +/* + Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> + This file is part of GlusterFS. + + GlusterFS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3 of the License, + or (at your option) any later version. + + GlusterFS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see + <http://www.gnu.org/licenses/>. +*/ + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include <string.h> +#include <stdlib.h> +#include <stdarg.h> +#include <getopt.h> +#include <sys/types.h> +#include <dirent.h> + +#ifdef GF_SOLARIS_HOST_OS +#include "logging.h" +#endif /* GF_SOLARIS_HOST_OS */ + +#include "compat.h" +#include "common-utils.h" + +#ifdef GF_DARWIN_HOST_OS + +#define GF_FINDER_INFO_XATTR "com.apple.FinderInfo" +#define GF_RESOURCE_FORK_XATTR "com.apple.ResourceFork" +#define GF_FINDER_INFO_SIZE 32 + +static const char gf_finder_info_content[GF_FINDER_INFO_SIZE] = { + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +}; + + +int32_t +gf_darwin_compat_listxattr (int len, dict_t *dict, int size) +{ + data_t *data = NULL; + if (len == -1) + len = 0; + + data = dict_get (dict, GF_FINDER_INFO_XATTR); + if (!data) { + dict_set (dict, GF_FINDER_INFO_XATTR, + bin_to_data ((void *)gf_finder_info_content, + GF_FINDER_INFO_SIZE)); + len += strlen (GF_FINDER_INFO_XATTR); + } + + data = dict_get (dict, GF_RESOURCE_FORK_XATTR); + if (!data) { + dict_set (dict, GF_RESOURCE_FORK_XATTR, str_to_data ("")); + len += strlen (GF_RESOURCE_FORK_XATTR); + } + + return len; +} + +int32_t +gf_darwin_compat_getxattr (const char *key, dict_t *dict) +{ + data_t *data = NULL; + + if (strcmp(key, GF_FINDER_INFO_XATTR) == 0) { + data = dict_get (dict, GF_FINDER_INFO_XATTR); + if (!data) { + dict_set (dict, GF_FINDER_INFO_XATTR, + bin_to_data ((void *)gf_finder_info_content, + GF_FINDER_INFO_SIZE)); + return GF_FINDER_INFO_SIZE; + } + return 0; + } + + if (strcmp(key, GF_RESOURCE_FORK_XATTR) == 0) { + data = dict_get (dict, GF_RESOURCE_FORK_XATTR); + if (!data) { + /* Always null */ + dict_set (dict, GF_RESOURCE_FORK_XATTR, + str_to_data ("")); + return 0; + } + return 0; + } + return -1; +} + + +int32_t +gf_darwin_compat_setxattr (dict_t *dict) +{ + data_t *data = NULL; + + data = dict_get (dict, GF_FINDER_INFO_XATTR); + if (data) + return 0; + data = dict_get (dict, GF_RESOURCE_FORK_XATTR); + if (data) + return 0; + + return -1; +} + +#endif /* DARWIN */ + + +#ifdef GF_SOLARIS_HOST_OS + +int +solaris_fsetxattr(int fd, + const char* key, + const char *value, + size_t size, + int flags) +{ + int attrfd = -1; + int ret = 0; + + attrfd = openat (fd, key, flags|O_CREAT|O_WRONLY|O_XATTR, 0777); + if (attrfd >= 0) { + ftruncate (attrfd, 0); + ret = write (attrfd, value, size); + close (attrfd); + } else { + if (errno != ENOENT) + gf_log ("libglusterfs", GF_LOG_ERROR, + "Couldn't set extended attribute for %d (%d)", + fd, errno); + return -1; + } + + return 0; +} + + +int +solaris_fgetxattr(int fd, + const char* key, + char *value, + size_t size) +{ + int attrfd = -1; + int ret = 0; + + attrfd = openat (fd, key, O_RDONLY|O_XATTR); + if (attrfd >= 0) { + if (size == 0) { + struct stat buf; + fstat (attrfd, &buf); + ret = buf.st_size; + } else { + ret = read (attrfd, value, size); + } + close (attrfd); + } else { + if (errno == ENOENT) + errno = ENODATA; + if (errno != ENOENT) + gf_log ("libglusterfs", GF_LOG_DEBUG, + "Couldn't read extended attribute for the file %d (%d)", + fd, errno); + return -1; + } + + return ret; +} + + +int +solaris_setxattr(const char *path, + const char* key, + const char *value, + size_t size, + int flags) +{ + int attrfd = -1; + int ret = 0; + + attrfd = attropen (path, key, flags|O_CREAT|O_WRONLY, 0777); + if (attrfd >= 0) { + ftruncate (attrfd, 0); + ret = write (attrfd, value, size); + close (attrfd); + } else { + if (errno != ENOENT) + gf_log ("libglusterfs", GF_LOG_ERROR, + "Couldn't set extended attribute for %s (%d)", + path, errno); + return -1; + } + + return 0; +} + + +int +solaris_listxattr(const char *path, + char *list, + size_t size) +{ + int attrdirfd = -1; + ssize_t len = 0; + DIR *dirptr = NULL; + struct dirent *dent = NULL; + int newfd = -1; + + attrdirfd = attropen (path, ".", O_RDONLY, 0); + if (attrdirfd >= 0) { + newfd = dup(attrdirfd); + dirptr = fdopendir(newfd); + if (dirptr) { + while ((dent = readdir(dirptr))) { + size_t listlen = strlen(dent->d_name); + if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) { + /* we don't want "." and ".." here */ + continue; + } + if (size == 0) { + /* return the current size of the list of extended attribute names*/ + len += listlen + 1; + } else { + /* check size and copy entrie + nul into list. */ + if ((len + listlen + 1) > size) { + errno = ERANGE; + len = -1; + break; + } else { + strncpy(list + len, dent->d_name, listlen); + len += listlen; + list[len] = '\0'; + ++len; + } + } + } + + if (closedir(dirptr) == -1) { + close (attrdirfd); + return -1; + } + } else { + close (attrdirfd); + return -1; + } + close (attrdirfd); + } + return len; +} + +int +solaris_removexattr(const char *path, + const char* key) +{ + int ret = -1; + int attrfd = attropen (path, ".", O_RDONLY, 0); + if (attrfd >= 0) { + ret = unlinkat (attrfd, key, 0); + close (attrfd); + } else { + if (errno == ENOENT) + errno = ENODATA; + return -1; + } + + return ret; +} + +int +solaris_getxattr(const char *path, + const char* key, + char *value, + size_t size) +{ + int attrfd = -1; + int ret = 0; + + attrfd = attropen (path, key, O_RDONLY, 0); + if (attrfd >= 0) { + if (size == 0) { + struct stat buf; + fstat (attrfd, &buf); + ret = buf.st_size; + } else { + ret = read (attrfd, value, size); + } + close (attrfd); + } else { + if (errno == ENOENT) + errno = ENODATA; + if (errno != ENOENT) + gf_log ("libglusterfs", GF_LOG_DEBUG, + "Couldn't read extended attribute for the file %s (%d)", + path, errno); + return -1; + } + return ret; +} + + +int +asprintf(char **string_ptr, const char *format, ...) +{ + va_list arg; + char *str; + int size; + int rv; + + if (!string_ptr || !format) + return -1; + + va_start(arg, format); + size = vsnprintf(NULL, 0, format, arg); + size++; + va_start(arg, format); + str = MALLOC(size); + if (str == NULL) { + va_end(arg); + /* + * Strictly speaking, GNU asprintf doesn't do this, + * but the caller isn't checking the return value. + */ + gf_log ("libglusterfs", GF_LOG_CRITICAL, "failed to allocate memory"); + return -1; + } + rv = vsnprintf(str, size, format, arg); + va_end(arg); + + *string_ptr = str; + return (rv); +} + +char* strsep(char** str, const char* delims) +{ + char* token; + + if (*str==NULL) { + /* No more tokens */ + return NULL; + } + + token=*str; + while (**str!='\0') { + if (strchr(delims,**str)!=NULL) { + **str='\0'; + (*str)++; + return token; + } + (*str)++; + } + /* There is no other token */ + *str=NULL; + return token; +} + +#endif /* GF_SOLARIS_HOST_OS */ + +#ifndef HAVE_STRNLEN +size_t +strnlen(const char *string, size_t maxlen) +{ + int len = 0; + while ((len < maxlen) && string[len]) + len++; + return len; +} +#endif /* STRNLEN */ |