blob: fd4271b1e0ce49bd95243f7d56c948ac1cfde7b6 [file] [log] [blame]
/*
* Copyright (C) 2012, 2013 STRATO AG.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* Handling of extended attributes aka xattr or extattr is located in this
* file. It is different for Linux, SunOS and all the other operating systems.
* Refer to <http://en.wikipedia.org/wiki/Extended_file_attributes>.
* This current implementation supports Linux and SunOS.
* These functions are used internally in the far-rcv library.
*/
#include <sys/types.h>
#include <errno.h>
#if defined (__LINUX__)
#include <attr/xattr.h>
#else /* !defined (__LINUX__) */
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#endif /* !defined (__LINUX__) */
#include "far-xattr.h"
int far_rcv_lsetxattr(const char *path, const char *name, const void *value,
size_t size)
{
#if defined (__LINUX__)
if (lsetxattr(path, name, value, size, 0) < 0)
return -errno;
else
return 0;
#else /* !defined (__LINUX__) */
int fd = -1;
int ret = 0;
fd = attropen(path, name, O_TRUNC | O_WRONLY | O_CREAT);
if (fd < 0) {
ret = -errno;
fprintf(stderr,
"ERROR: attropen(%s, %s) for writing failed. %s\n",
path, name, strerror(-ret));
goto out;
}
while (size) {
ret = write(fd, value, size);
if (ret == -1 && errno == EINTR) {
continue;
} else if (ret == -1) {
ret = -errno;
fprintf(stderr,
"ERROR: write() xattr %s in %s failed. %s\n",
name, path, strerror(-ret));
goto out;
}
assert(ret > 0);
size -= ret;
value += ret;
ret = 0;
}
out:
if (fd != -1)
close(fd);
return ret;
#endif /* !defined (__LINUX__) */
}
int far_rcv_lremovexattr(const char *path, const char *name)
{
#if defined (__LINUX__)
if (lremovexattr(path, name) < 0)
return -errno;
else
return 0;
#else /* !defined (__LINUX__) */
int attrdirfd;
int ret = 0;
attrdirfd = attropen(path, ".", O_RDONLY);
if (attrdirfd < 0) {
ret = -errno;
fprintf(stderr,
"ERROR: attropen(%s, \".\") failed. %s\n", path,
strerror(-ret));
goto out;
}
if (unlinkat(attrdirfd, name, 0) < 0) {
ret = -errno;
fprintf(stderr,
"ERROR: unlinkat(%s) failed in %s. %s\n", name, path,
strerror(-ret));
goto out;
}
out:
if (attrdirfd != -1)
close(attrdirfd);
return ret;
#endif /* !defined (__LINUX__) */
}