summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/compat.c')
-rw-r--r--libglusterfs/src/compat.c383
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 */