diff options
author | nyov <nyov@nexnode.net> | 2018-07-04 16:45:21 +0000 |
---|---|---|
committer | nyov <nyov@nexnode.net> | 2018-07-04 16:45:21 +0000 |
commit | 61b5c3aeab7611f9e6dca719dbac08d4545b8f85 (patch) | |
tree | 050772f09bf1313d362779ae1d92127e2c0d82fe /xattr | |
parent | d713b973cbf27259d8d1dee9ffd1dcda5937565e (diff) | |
download | xattr-61b5c3aeab7611f9e6dca719dbac08d4545b8f85.tar.gz |
Extracted inline C code for syntax highlighting
Diffstat (limited to 'xattr')
-rw-r--r-- | xattr/lib.py | 4 | ||||
-rw-r--r-- | xattr/lib_build.c | 565 | ||||
-rw-r--r-- | xattr/lib_build.h | 17 | ||||
-rw-r--r-- | xattr/lib_build.py | 603 |
4 files changed, 594 insertions, 595 deletions
diff --git a/xattr/lib.py b/xattr/lib.py index b6245c1..fecc3bd 100644 --- a/xattr/lib.py +++ b/xattr/lib.py @@ -6,8 +6,8 @@ from .compat import fs_encode try: from ._lib import lib, ffi except ImportError: - from .lib_build import ffi, C_SRC - lib = ffi.verify(C_SRC) + from .lib_build import ffi, c_source + lib = ffi.verify(c_source) XATTR_NOFOLLOW = lib.XATTR_XATTR_NOFOLLOW XATTR_CREATE = lib.XATTR_XATTR_CREATE diff --git a/xattr/lib_build.c b/xattr/lib_build.c new file mode 100644 index 0000000..1d07b6a --- /dev/null +++ b/xattr/lib_build.c @@ -0,0 +1,565 @@ +#include "Python.h" +#ifdef __FreeBSD__ +#include <sys/extattr.h> +#elif defined(__SUN__) || defined(__sun__) || defined(__sun) +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <dirent.h> +#include <alloca.h> +#else +#include <sys/xattr.h> +#endif + +#ifdef __FreeBSD__ + +/* FreeBSD compatibility API */ +#define XATTR_XATTR_NOFOLLOW 0x0001 +#define XATTR_XATTR_CREATE 0x0002 +#define XATTR_XATTR_REPLACE 0x0004 +#define XATTR_XATTR_NOSECURITY 0x0008 + +#define XATTR_CREATE 0x1 +#define XATTR_REPLACE 0x2 + +/* Converts a freebsd format attribute list into a NULL terminated list. + * The first byte is the length of the following attribute. + */ +static void convert_bsd_list(char *namebuf, size_t size) +{ + size_t offset = 0; + while(offset < size) { + int length = (int) (unsigned char)namebuf[offset]; + memmove(namebuf+offset, namebuf+offset+1, length); + namebuf[offset+length] = '\0'; + offset += length+1; + } +} + +static ssize_t xattr_getxattr(const char *path, const char *name, + void *value, ssize_t size, u_int32_t position, + int options) +{ + if (position != 0 || + !(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { + return -1; + } + + if (options & XATTR_XATTR_NOFOLLOW) { + return extattr_get_link(path, EXTATTR_NAMESPACE_USER, + name, value, size); + } + else { + return extattr_get_file(path, EXTATTR_NAMESPACE_USER, + name, value, size); + } +} + +static ssize_t xattr_setxattr(const char *path, const char *name, + void *value, ssize_t size, u_int32_t position, + int options) +{ + int rv = 0; + int nofollow; + + if (position != 0) { + return -1; + } + + nofollow = options & XATTR_XATTR_NOFOLLOW; + options &= ~XATTR_XATTR_NOFOLLOW; + + if (options == XATTR_XATTR_CREATE || + options == XATTR_XATTR_REPLACE) { + + /* meh. FreeBSD doesn't really have this in its + * API... Oh well. + */ + } + else if (options != 0) { + return -1; + } + + if (nofollow) { + rv = extattr_set_link(path, EXTATTR_NAMESPACE_USER, + name, value, size); + } + else { + rv = extattr_set_file(path, EXTATTR_NAMESPACE_USER, + name, value, size); + } + + /* freebsd returns the written length on success, not zero. */ + if (rv >= 0) { + return 0; + } + else { + return rv; + } +} + +static ssize_t xattr_removexattr(const char *path, const char *name, + int options) +{ + if (!(options == 0 || + options == XATTR_XATTR_NOFOLLOW)) { + return -1; + } + + if (options & XATTR_XATTR_NOFOLLOW) { + return extattr_delete_link(path, EXTATTR_NAMESPACE_USER, name); + } + else { + return extattr_delete_file(path, EXTATTR_NAMESPACE_USER, name); + } +} + + +static ssize_t xattr_listxattr(const char *path, char *namebuf, + size_t size, int options) +{ + ssize_t rv = 0; + if (!(options == 0 || + options == XATTR_XATTR_NOFOLLOW)) { + return -1; + } + + if (options & XATTR_XATTR_NOFOLLOW) { + rv = extattr_list_link(path, EXTATTR_NAMESPACE_USER, namebuf, size); + } + else { + rv = extattr_list_file(path, EXTATTR_NAMESPACE_USER, namebuf, size); + } + + if (rv > 0 && namebuf) { + convert_bsd_list(namebuf, rv); + } + + return rv; +} + +static ssize_t xattr_fgetxattr(int fd, const char *name, void *value, + ssize_t size, u_int32_t position, int options) +{ + if (position != 0 || + !(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { + return -1; + } + + if (options & XATTR_XATTR_NOFOLLOW) { + return -1; + } + else { + return extattr_get_fd(fd, EXTATTR_NAMESPACE_USER, name, value, size); + } +} + +static ssize_t xattr_fsetxattr(int fd, const char *name, void *value, + ssize_t size, u_int32_t position, int options) +{ + int rv = 0; + int nofollow; + + if (position != 0) { + return -1; + } + + nofollow = options & XATTR_XATTR_NOFOLLOW; + options &= ~XATTR_XATTR_NOFOLLOW; + + if (options == XATTR_XATTR_CREATE || + options == XATTR_XATTR_REPLACE) { + /* freebsd noop */ + } + else if (options != 0) { + return -1; + } + + if (nofollow) { + return -1; + } + else { + rv = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, + name, value, size); + } + + /* freebsd returns the written length on success, not zero. */ + if (rv >= 0) { + return 0; + } + else { + return rv; + } +} + +static ssize_t xattr_fremovexattr(int fd, const char *name, int options) +{ + + if (!(options == 0 || + options == XATTR_XATTR_NOFOLLOW)) { + return -1; + } + + if (options & XATTR_XATTR_NOFOLLOW) { + return -1; + } + else { + return extattr_delete_fd(fd, EXTATTR_NAMESPACE_USER, name); + } +} + + +static ssize_t xattr_flistxattr(int fd, char *namebuf, size_t size, int options) +{ + ssize_t rv = 0; + + if (!(options == 0 || + options == XATTR_XATTR_NOFOLLOW)) { + return -1; + } + + if (options & XATTR_XATTR_NOFOLLOW) { + return -1; + } + else { + rv = extattr_list_fd(fd, EXTATTR_NAMESPACE_USER, namebuf, size); + } + + if (rv > 0 && namebuf) { + convert_bsd_list(namebuf, rv); + } + + return rv; +} + +#elif defined(__SUN__) || defined(__sun__) || defined(__sun) + +/* Solaris 9 and later compatibility API */ +#define XATTR_XATTR_NOFOLLOW 0x0001 +#define XATTR_XATTR_CREATE 0x0002 +#define XATTR_XATTR_REPLACE 0x0004 +#define XATTR_XATTR_NOSECURITY 0x0008 + +#define XATTR_CREATE 0x1 +#define XATTR_REPLACE 0x2 + +#ifndef u_int32_t +#define u_int32_t uint32_t +#endif + +static ssize_t xattr_fgetxattr(int fd, const char *name, void *value, + ssize_t size, u_int32_t position, int options) +{ + int xfd; + ssize_t bytes; + struct stat statbuf; + + /* XXX should check that name does not have / characters in it */ + xfd = openat(fd, name, O_RDONLY | O_XATTR); + if (xfd == -1) { + return -1; + } + if (lseek(xfd, position, SEEK_SET) == -1) { + close(xfd); + return -1; + } + if (value == NULL) { + if (fstat(xfd, &statbuf) == -1) { + close(xfd); + return -1; + } + close(xfd); + return statbuf.st_size; + } + /* XXX should keep reading until the buffer is exhausted or EOF */ + bytes = read(xfd, value, size); + close(xfd); + return bytes; +} + +static ssize_t xattr_getxattr(const char *path, const char *name, + void *value, ssize_t size, u_int32_t position, + int options) +{ + int fd; + ssize_t bytes; + + if (position != 0 || + !(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { + return -1; + } + + fd = open(path, + O_RDONLY | + ((options & XATTR_XATTR_NOFOLLOW) ? O_NOFOLLOW : 0)); + if (fd == -1) { + return -1; + } + bytes = xattr_fgetxattr(fd, name, value, size, position, options); + close(fd); + return bytes; +} + +static ssize_t xattr_fsetxattr(int fd, const char *name, void *value, + ssize_t size, u_int32_t position, int options) +{ + int xfd; + ssize_t bytes = 0; + + /* XXX should check that name does not have / characters in it */ + xfd = openat(fd, name, O_XATTR | O_TRUNC | + ((options & XATTR_XATTR_CREATE) ? O_EXCL : 0) | + ((options & XATTR_XATTR_NOFOLLOW) ? O_NOFOLLOW : 0) | + ((options & XATTR_XATTR_REPLACE) ? O_RDWR : O_WRONLY|O_CREAT), + 0644); + if (xfd == -1) { + return -1; + } + while (size > 0) { + bytes = write(xfd, value, size); + if (bytes == -1) { + close(xfd); + return -1; + } + size -= bytes; + value += bytes; + } + close(xfd); + return 0; +} + +static ssize_t xattr_setxattr(const char *path, const char *name, + void *value, ssize_t size, u_int32_t position, + int options) +{ + int fd; + ssize_t bytes; + + if (position != 0) { + return -1; + } + + fd = open(path, + O_RDONLY | (options & XATTR_XATTR_NOFOLLOW) ? O_NOFOLLOW : 0); + if (fd == -1) { + return -1; + } + bytes = xattr_fsetxattr(fd, name, value, size, position, options); + close(fd); + return bytes; +} + +static ssize_t xattr_fremovexattr(int fd, const char *name, int options) +{ + int xfd, status; + /* XXX should check that name does not have / characters in it */ + if (!(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { + return -1; + } + if (options & XATTR_XATTR_NOFOLLOW) { + return -1; + } + xfd = openat(fd, ".", O_XATTR, 0644); + if (xfd == -1) { + return -1; + } + status = unlinkat(xfd, name, 0); + close(xfd); + return status; +} + +static ssize_t xattr_removexattr(const char *path, const char *name, + int options) +{ + int fd; + ssize_t status; + + fd = open(path, + O_RDONLY | ((options & XATTR_XATTR_NOFOLLOW) ? O_NOFOLLOW : 0)); + if (fd == -1) { + return -1; + } + status = xattr_fremovexattr(fd, name, options); + close(fd); + return status; +} + +static ssize_t xattr_xflistxattr(int xfd, char *namebuf, size_t size, int options) +{ + int esize; + DIR *dirp; + struct dirent *entry; + ssize_t nsize = 0; + + dirp = fdopendir(xfd); + if (dirp == NULL) { + return (-1); + } + while (entry = readdir(dirp)) { + if (strcmp(entry->d_name, ".") == 0 || + strcmp(entry->d_name, "..") == 0) + continue; + esize = strlen(entry->d_name); + if (nsize + esize + 1 <= size) { + snprintf((char *)(namebuf + nsize), esize + 1, + entry->d_name); + } + nsize += esize + 1; /* +1 for \0 */ + } + closedir(dirp); + return nsize; +} +static ssize_t xattr_flistxattr(int fd, char *namebuf, size_t size, int options) +{ + int xfd; + + xfd = openat(fd, ".", O_RDONLY | O_XATTR); + return xattr_xflistxattr(xfd, namebuf, size, options); +} + +static ssize_t xattr_listxattr(const char *path, char *namebuf, + size_t size, int options) +{ + int xfd; + + xfd = attropen(path, ".", O_RDONLY); + return xattr_xflistxattr(xfd, namebuf, size, options); +} + +#elif !defined(XATTR_NOFOLLOW) +/* Linux compatibility API */ +#define XATTR_XATTR_NOFOLLOW 0x0001 +#define XATTR_XATTR_CREATE 0x0002 +#define XATTR_XATTR_REPLACE 0x0004 +#define XATTR_XATTR_NOSECURITY 0x0008 +static ssize_t xattr_getxattr(const char *path, const char *name, void *value, ssize_t size, u_int32_t position, int options) { + if (position != 0 || !(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { + return -1; + } + if (options & XATTR_XATTR_NOFOLLOW) { + return lgetxattr(path, name, value, size); + } else { + return getxattr(path, name, value, size); + } +} + +static ssize_t xattr_setxattr(const char *path, const char *name, void *value, ssize_t size, u_int32_t position, int options) { + int nofollow; + if (position != 0) { + return -1; + } + nofollow = options & XATTR_XATTR_NOFOLLOW; + options &= ~XATTR_XATTR_NOFOLLOW; + if (options == XATTR_XATTR_CREATE) { + options = XATTR_CREATE; + } else if (options == XATTR_XATTR_REPLACE) { + options = XATTR_REPLACE; + } else if (options != 0) { + return -1; + } + if (nofollow) { + return lsetxattr(path, name, value, size, options); + } else { + return setxattr(path, name, value, size, options); + } +} + +static ssize_t xattr_removexattr(const char *path, const char *name, int options) { + if (!(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { + return -1; + } + if (options & XATTR_XATTR_NOFOLLOW) { + return lremovexattr(path, name); + } else { + return removexattr(path, name); + } +} + + +static ssize_t xattr_listxattr(const char *path, char *namebuf, size_t size, int options) { + if (!(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { + return -1; + } + if (options & XATTR_XATTR_NOFOLLOW) { + return llistxattr(path, namebuf, size); + } else { + return listxattr(path, namebuf, size); + } +} + +static ssize_t xattr_fgetxattr(int fd, const char *name, void *value, ssize_t size, u_int32_t position, int options) { + if (position != 0 || !(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { + return -1; + } + if (options & XATTR_XATTR_NOFOLLOW) { + return -1; + } else { + return fgetxattr(fd, name, value, size); + } +} + +static ssize_t xattr_fsetxattr(int fd, const char *name, void *value, ssize_t size, u_int32_t position, int options) { + int nofollow; + if (position != 0) { + return -1; + } + nofollow = options & XATTR_XATTR_NOFOLLOW; + options &= ~XATTR_XATTR_NOFOLLOW; + if (options == XATTR_XATTR_CREATE) { + options = XATTR_CREATE; + } else if (options == XATTR_XATTR_REPLACE) { + options = XATTR_REPLACE; + } else if (options != 0) { + return -1; + } + if (nofollow) { + return -1; + } else { + return fsetxattr(fd, name, value, size, options); + } +} + +static ssize_t xattr_fremovexattr(int fd, const char *name, int options) { + if (!(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { + return -1; + } + if (options & XATTR_XATTR_NOFOLLOW) { + return -1; + } else { + return fremovexattr(fd, name); + } +} + + +static ssize_t xattr_flistxattr(int fd, char *namebuf, size_t size, int options) { + if (!(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { + return -1; + } + if (options & XATTR_XATTR_NOFOLLOW) { + return -1; + } else { + return flistxattr(fd, namebuf, size); + } +} + +#else /* Mac OS X assumed */ +#define xattr_getxattr getxattr +#define xattr_fgetxattr fgetxattr +#define xattr_removexattr removexattr +#define xattr_fremovexattr fremovexattr +#define xattr_setxattr setxattr +#define xattr_fsetxattr fsetxattr +#define xattr_listxattr listxattr +#define xattr_flistxattr flistxattr + +/* define these for use in python (see below) */ +#define XATTR_XATTR_NOFOLLOW XATTR_NOFOLLOW +#define XATTR_XATTR_CREATE XATTR_CREATE +#define XATTR_XATTR_REPLACE XATTR_REPLACE +#define XATTR_XATTR_NOSECURITY XATTR_NOSECURITY +#endif + +#ifndef XATTR_MAXNAMELEN +#define XATTR_MAXNAMELEN 127 +#endif diff --git a/xattr/lib_build.h b/xattr/lib_build.h new file mode 100644 index 0000000..919722a --- /dev/null +++ b/xattr/lib_build.h @@ -0,0 +1,17 @@ +#define XATTR_XATTR_NOFOLLOW ... +#define XATTR_XATTR_CREATE ... +#define XATTR_XATTR_REPLACE ... +#define XATTR_XATTR_NOSECURITY ... +#define XATTR_MAXNAMELEN ... + +ssize_t xattr_getxattr(const char *, const char *, void *, ssize_t, uint32_t, int); +ssize_t xattr_fgetxattr(int, const char *, void *, ssize_t, uint32_t, int); + +ssize_t xattr_setxattr(const char *, const char *, void *, ssize_t, uint32_t, int); +ssize_t xattr_fsetxattr(int, const char *, void *, ssize_t, uint32_t, int); + +ssize_t xattr_removexattr(const char *, const char *, int); +ssize_t xattr_fremovexattr(int, const char *, int); + +ssize_t xattr_listxattr(const char *, char *, size_t, int); +ssize_t xattr_flistxattr(int, char *, size_t, int); diff --git a/xattr/lib_build.py b/xattr/lib_build.py index a687cea..bb0caae 100644 --- a/xattr/lib_build.py +++ b/xattr/lib_build.py @@ -1,600 +1,17 @@ -import os import sys +import os +from cffi import FFI -import cffi - -ffi = cffi.FFI() -ffi.cdef(""" -#define XATTR_XATTR_NOFOLLOW ... -#define XATTR_XATTR_CREATE ... -#define XATTR_XATTR_REPLACE ... -#define XATTR_XATTR_NOSECURITY ... -#define XATTR_MAXNAMELEN ... - -ssize_t xattr_getxattr(const char *, const char *, void *, ssize_t, uint32_t, int); -ssize_t xattr_fgetxattr(int, const char *, void *, ssize_t, uint32_t, int); - -ssize_t xattr_setxattr(const char *, const char *, void *, ssize_t, uint32_t, int); -ssize_t xattr_fsetxattr(int, const char *, void *, ssize_t, uint32_t, int); - -ssize_t xattr_removexattr(const char *, const char *, int); -ssize_t xattr_fremovexattr(int, const char *, int); - -ssize_t xattr_listxattr(const char *, char *, size_t, int); -ssize_t xattr_flistxattr(int, char *, size_t, int); - -""") - -C_SRC = """ -#include "Python.h" -#ifdef __FreeBSD__ -#include <sys/extattr.h> -#elif defined(__SUN__) || defined(__sun__) || defined(__sun) -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <dirent.h> -#include <alloca.h> -#else -#include <sys/xattr.h> -#endif - -#ifdef __FreeBSD__ - -/* FreeBSD compatibility API */ -#define XATTR_XATTR_NOFOLLOW 0x0001 -#define XATTR_XATTR_CREATE 0x0002 -#define XATTR_XATTR_REPLACE 0x0004 -#define XATTR_XATTR_NOSECURITY 0x0008 - -#define XATTR_CREATE 0x1 -#define XATTR_REPLACE 0x2 - -/* Converts a freebsd format attribute list into a NULL terminated list. - * The first byte is the length of the following attribute. - */ -static void convert_bsd_list(char *namebuf, size_t size) -{ - size_t offset = 0; - while(offset < size) { - int length = (int) (unsigned char)namebuf[offset]; - memmove(namebuf+offset, namebuf+offset+1, length); - namebuf[offset+length] = '\\0'; - offset += length+1; - } -} - -static ssize_t xattr_getxattr(const char *path, const char *name, - void *value, ssize_t size, u_int32_t position, - int options) -{ - if (position != 0 || - !(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { - return -1; - } - - if (options & XATTR_XATTR_NOFOLLOW) { - return extattr_get_link(path, EXTATTR_NAMESPACE_USER, - name, value, size); - } - else { - return extattr_get_file(path, EXTATTR_NAMESPACE_USER, - name, value, size); - } -} - -static ssize_t xattr_setxattr(const char *path, const char *name, - void *value, ssize_t size, u_int32_t position, - int options) -{ - int rv = 0; - int nofollow; - - if (position != 0) { - return -1; - } - - nofollow = options & XATTR_XATTR_NOFOLLOW; - options &= ~XATTR_XATTR_NOFOLLOW; - - if (options == XATTR_XATTR_CREATE || - options == XATTR_XATTR_REPLACE) { - - /* meh. FreeBSD doesn't really have this in its - * API... Oh well. - */ - } - else if (options != 0) { - return -1; - } - - if (nofollow) { - rv = extattr_set_link(path, EXTATTR_NAMESPACE_USER, - name, value, size); - } - else { - rv = extattr_set_file(path, EXTATTR_NAMESPACE_USER, - name, value, size); - } - - /* freebsd returns the written length on success, not zero. */ - if (rv >= 0) { - return 0; - } - else { - return rv; - } -} - -static ssize_t xattr_removexattr(const char *path, const char *name, - int options) -{ - if (!(options == 0 || - options == XATTR_XATTR_NOFOLLOW)) { - return -1; - } - - if (options & XATTR_XATTR_NOFOLLOW) { - return extattr_delete_link(path, EXTATTR_NAMESPACE_USER, name); - } - else { - return extattr_delete_file(path, EXTATTR_NAMESPACE_USER, name); - } -} - - -static ssize_t xattr_listxattr(const char *path, char *namebuf, - size_t size, int options) -{ - ssize_t rv = 0; - if (!(options == 0 || - options == XATTR_XATTR_NOFOLLOW)) { - return -1; - } - - if (options & XATTR_XATTR_NOFOLLOW) { - rv = extattr_list_link(path, EXTATTR_NAMESPACE_USER, namebuf, size); - } - else { - rv = extattr_list_file(path, EXTATTR_NAMESPACE_USER, namebuf, size); - } - - if (rv > 0 && namebuf) { - convert_bsd_list(namebuf, rv); - } - - return rv; -} - -static ssize_t xattr_fgetxattr(int fd, const char *name, void *value, - ssize_t size, u_int32_t position, int options) -{ - if (position != 0 || - !(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { - return -1; - } - - if (options & XATTR_XATTR_NOFOLLOW) { - return -1; - } - else { - return extattr_get_fd(fd, EXTATTR_NAMESPACE_USER, name, value, size); - } -} - -static ssize_t xattr_fsetxattr(int fd, const char *name, void *value, - ssize_t size, u_int32_t position, int options) -{ - int rv = 0; - int nofollow; - - if (position != 0) { - return -1; - } - - nofollow = options & XATTR_XATTR_NOFOLLOW; - options &= ~XATTR_XATTR_NOFOLLOW; - - if (options == XATTR_XATTR_CREATE || - options == XATTR_XATTR_REPLACE) { - /* freebsd noop */ - } - else if (options != 0) { - return -1; - } - - if (nofollow) { - return -1; - } - else { - rv = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, - name, value, size); - } - - /* freebsd returns the written length on success, not zero. */ - if (rv >= 0) { - return 0; - } - else { - return rv; - } -} - -static ssize_t xattr_fremovexattr(int fd, const char *name, int options) -{ - - if (!(options == 0 || - options == XATTR_XATTR_NOFOLLOW)) { - return -1; - } - - if (options & XATTR_XATTR_NOFOLLOW) { - return -1; - } - else { - return extattr_delete_fd(fd, EXTATTR_NAMESPACE_USER, name); - } -} - - -static ssize_t xattr_flistxattr(int fd, char *namebuf, size_t size, int options) -{ - ssize_t rv = 0; - - if (!(options == 0 || - options == XATTR_XATTR_NOFOLLOW)) { - return -1; - } - - if (options & XATTR_XATTR_NOFOLLOW) { - return -1; - } - else { - rv = extattr_list_fd(fd, EXTATTR_NAMESPACE_USER, namebuf, size); - } - - if (rv > 0 && namebuf) { - convert_bsd_list(namebuf, rv); - } - - return rv; -} - -#elif defined(__SUN__) || defined(__sun__) || defined(__sun) - -/* Solaris 9 and later compatibility API */ -#define XATTR_XATTR_NOFOLLOW 0x0001 -#define XATTR_XATTR_CREATE 0x0002 -#define XATTR_XATTR_REPLACE 0x0004 -#define XATTR_XATTR_NOSECURITY 0x0008 - -#define XATTR_CREATE 0x1 -#define XATTR_REPLACE 0x2 - -#ifndef u_int32_t -#define u_int32_t uint32_t -#endif - -static ssize_t xattr_fgetxattr(int fd, const char *name, void *value, - ssize_t size, u_int32_t position, int options) -{ - int xfd; - ssize_t bytes; - struct stat statbuf; - - /* XXX should check that name does not have / characters in it */ - xfd = openat(fd, name, O_RDONLY | O_XATTR); - if (xfd == -1) { - return -1; - } - if (lseek(xfd, position, SEEK_SET) == -1) { - close(xfd); - return -1; - } - if (value == NULL) { - if (fstat(xfd, &statbuf) == -1) { - close(xfd); - return -1; - } - close(xfd); - return statbuf.st_size; - } - /* XXX should keep reading until the buffer is exhausted or EOF */ - bytes = read(xfd, value, size); - close(xfd); - return bytes; -} - -static ssize_t xattr_getxattr(const char *path, const char *name, - void *value, ssize_t size, u_int32_t position, - int options) -{ - int fd; - ssize_t bytes; - - if (position != 0 || - !(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { - return -1; - } - - fd = open(path, - O_RDONLY | - ((options & XATTR_XATTR_NOFOLLOW) ? O_NOFOLLOW : 0)); - if (fd == -1) { - return -1; - } - bytes = xattr_fgetxattr(fd, name, value, size, position, options); - close(fd); - return bytes; -} - -static ssize_t xattr_fsetxattr(int fd, const char *name, void *value, - ssize_t size, u_int32_t position, int options) -{ - int xfd; - ssize_t bytes = 0; - - /* XXX should check that name does not have / characters in it */ - xfd = openat(fd, name, O_XATTR | O_TRUNC | - ((options & XATTR_XATTR_CREATE) ? O_EXCL : 0) | - ((options & XATTR_XATTR_NOFOLLOW) ? O_NOFOLLOW : 0) | - ((options & XATTR_XATTR_REPLACE) ? O_RDWR : O_WRONLY|O_CREAT), - 0644); - if (xfd == -1) { - return -1; - } - while (size > 0) { - bytes = write(xfd, value, size); - if (bytes == -1) { - close(xfd); - return -1; - } - size -= bytes; - value += bytes; - } - close(xfd); - return 0; -} - -static ssize_t xattr_setxattr(const char *path, const char *name, - void *value, ssize_t size, u_int32_t position, - int options) -{ - int fd; - ssize_t bytes; - - if (position != 0) { - return -1; - } - - fd = open(path, - O_RDONLY | (options & XATTR_XATTR_NOFOLLOW) ? O_NOFOLLOW : 0); - if (fd == -1) { - return -1; - } - bytes = xattr_fsetxattr(fd, name, value, size, position, options); - close(fd); - return bytes; -} - -static ssize_t xattr_fremovexattr(int fd, const char *name, int options) -{ - int xfd, status; - /* XXX should check that name does not have / characters in it */ - if (!(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { - return -1; - } - if (options & XATTR_XATTR_NOFOLLOW) { - return -1; - } - xfd = openat(fd, ".", O_XATTR, 0644); - if (xfd == -1) { - return -1; - } - status = unlinkat(xfd, name, 0); - close(xfd); - return status; -} - -static ssize_t xattr_removexattr(const char *path, const char *name, - int options) -{ - int fd; - ssize_t status; - - fd = open(path, - O_RDONLY | ((options & XATTR_XATTR_NOFOLLOW) ? O_NOFOLLOW : 0)); - if (fd == -1) { - return -1; - } - status = xattr_fremovexattr(fd, name, options); - close(fd); - return status; -} - -static ssize_t xattr_xflistxattr(int xfd, char *namebuf, size_t size, int options) -{ - int esize; - DIR *dirp; - struct dirent *entry; - ssize_t nsize = 0; - - dirp = fdopendir(xfd); - if (dirp == NULL) { - return (-1); - } - while (entry = readdir(dirp)) { - if (strcmp(entry->d_name, ".") == 0 || - strcmp(entry->d_name, "..") == 0) - continue; - esize = strlen(entry->d_name); - if (nsize + esize + 1 <= size) { - snprintf((char *)(namebuf + nsize), esize + 1, - entry->d_name); - } - nsize += esize + 1; /* +1 for \\0 */ - } - closedir(dirp); - return nsize; -} -static ssize_t xattr_flistxattr(int fd, char *namebuf, size_t size, int options) -{ - int xfd; - - xfd = openat(fd, ".", O_RDONLY | O_XATTR); - return xattr_xflistxattr(xfd, namebuf, size, options); -} - -static ssize_t xattr_listxattr(const char *path, char *namebuf, - size_t size, int options) -{ - int xfd; - - xfd = attropen(path, ".", O_RDONLY); - return xattr_xflistxattr(xfd, namebuf, size, options); -} - -#elif !defined(XATTR_NOFOLLOW) -/* Linux compatibility API */ -#define XATTR_XATTR_NOFOLLOW 0x0001 -#define XATTR_XATTR_CREATE 0x0002 -#define XATTR_XATTR_REPLACE 0x0004 -#define XATTR_XATTR_NOSECURITY 0x0008 -static ssize_t xattr_getxattr(const char *path, const char *name, void *value, ssize_t size, u_int32_t position, int options) { - if (position != 0 || !(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { - return -1; - } - if (options & XATTR_XATTR_NOFOLLOW) { - return lgetxattr(path, name, value, size); - } else { - return getxattr(path, name, value, size); - } -} - -static ssize_t xattr_setxattr(const char *path, const char *name, void *value, ssize_t size, u_int32_t position, int options) { - int nofollow; - if (position != 0) { - return -1; - } - nofollow = options & XATTR_XATTR_NOFOLLOW; - options &= ~XATTR_XATTR_NOFOLLOW; - if (options == XATTR_XATTR_CREATE) { - options = XATTR_CREATE; - } else if (options == XATTR_XATTR_REPLACE) { - options = XATTR_REPLACE; - } else if (options != 0) { - return -1; - } - if (nofollow) { - return lsetxattr(path, name, value, size, options); - } else { - return setxattr(path, name, value, size, options); - } -} - -static ssize_t xattr_removexattr(const char *path, const char *name, int options) { - if (!(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { - return -1; - } - if (options & XATTR_XATTR_NOFOLLOW) { - return lremovexattr(path, name); - } else { - return removexattr(path, name); - } -} - - -static ssize_t xattr_listxattr(const char *path, char *namebuf, size_t size, int options) { - if (!(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { - return -1; - } - if (options & XATTR_XATTR_NOFOLLOW) { - return llistxattr(path, namebuf, size); - } else { - return listxattr(path, namebuf, size); - } -} - -static ssize_t xattr_fgetxattr(int fd, const char *name, void *value, ssize_t size, u_int32_t position, int options) { - if (position != 0 || !(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { - return -1; - } - if (options & XATTR_XATTR_NOFOLLOW) { - return -1; - } else { - return fgetxattr(fd, name, value, size); - } -} - -static ssize_t xattr_fsetxattr(int fd, const char *name, void *value, ssize_t size, u_int32_t position, int options) { - int nofollow; - if (position != 0) { - return -1; - } - nofollow = options & XATTR_XATTR_NOFOLLOW; - options &= ~XATTR_XATTR_NOFOLLOW; - if (options == XATTR_XATTR_CREATE) { - options = XATTR_CREATE; - } else if (options == XATTR_XATTR_REPLACE) { - options = XATTR_REPLACE; - } else if (options != 0) { - return -1; - } - if (nofollow) { - return -1; - } else { - return fsetxattr(fd, name, value, size, options); - } -} - -static ssize_t xattr_fremovexattr(int fd, const char *name, int options) { - if (!(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { - return -1; - } - if (options & XATTR_XATTR_NOFOLLOW) { - return -1; - } else { - return fremovexattr(fd, name); - } -} - - -static ssize_t xattr_flistxattr(int fd, char *namebuf, size_t size, int options) { - if (!(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { - return -1; - } - if (options & XATTR_XATTR_NOFOLLOW) { - return -1; - } else { - return flistxattr(fd, namebuf, size); - } -} - -#else /* Mac OS X assumed */ -#define xattr_getxattr getxattr -#define xattr_fgetxattr fgetxattr -#define xattr_removexattr removexattr -#define xattr_fremovexattr fremovexattr -#define xattr_setxattr setxattr -#define xattr_fsetxattr fsetxattr -#define xattr_listxattr listxattr -#define xattr_flistxattr flistxattr - -/* define these for use in python (see below) */ -#define XATTR_XATTR_NOFOLLOW XATTR_NOFOLLOW -#define XATTR_XATTR_CREATE XATTR_CREATE -#define XATTR_XATTR_REPLACE XATTR_REPLACE -#define XATTR_XATTR_NOSECURITY XATTR_NOSECURITY -#endif +PATH = os.path.dirname(__file__) -#ifndef XATTR_MAXNAMELEN -#define XATTR_MAXNAMELEN 127 -#endif -""" +with open(os.path.join(PATH, 'lib_build.h')) as hf: + c_header = hf.read() +with open(os.path.join(PATH, 'lib_build.c')) as cf: + c_source = cf.read() -ffi.set_source('_lib', C_SRC) +ffi = FFI() +ffi.cdef(c_header) +ffi.set_source('_lib', c_source) if __name__ == '__main__': ffi.compile() - |