diff options
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/copy.c | 1 | ||||
-rw-r--r-- | src/basic/smack-util.c | 7 | ||||
-rw-r--r-- | src/basic/util.c | 167 | ||||
-rw-r--r-- | src/basic/util.h | 10 | ||||
-rw-r--r-- | src/basic/xattr-util.c | 193 | ||||
-rw-r--r-- | src/basic/xattr-util.h | 38 |
6 files changed, 236 insertions, 180 deletions
diff --git a/src/basic/copy.c b/src/basic/copy.c index 2d2d7ade34..60a4bee0fe 100644 --- a/src/basic/copy.c +++ b/src/basic/copy.c @@ -31,6 +31,7 @@ #include "string-util.h" #include "strv.h" #include "util.h" +#include "xattr-util.h" #define COPY_BUFFER_SIZE (16*1024) diff --git a/src/basic/smack-util.c b/src/basic/smack-util.c index 5f570ff02a..5ada621ca3 100644 --- a/src/basic/smack-util.c +++ b/src/basic/smack-util.c @@ -23,11 +23,12 @@ #include <sys/xattr.h> -#include "util.h" -#include "process-util.h" -#include "path-util.h" #include "fileio.h" +#include "path-util.h" +#include "process-util.h" #include "smack-util.h" +#include "util.h" +#include "xattr-util.h" #ifdef HAVE_SMACK bool mac_smack_use(void) { diff --git a/src/basic/util.c b/src/basic/util.c index e214c6f3dc..dfebff7ec1 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -53,7 +53,6 @@ #include <sys/utsname.h> #include <sys/vfs.h> #include <sys/wait.h> -#include <sys/xattr.h> #include <syslog.h> #include <unistd.h> @@ -1963,102 +1962,6 @@ int is_device_node(const char *path) { return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode)); } -ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) { - char fn[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1]; - _cleanup_close_ int fd = -1; - ssize_t l; - - /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */ - - fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0)); - if (fd < 0) - return -errno; - - xsprintf(fn, "/proc/self/fd/%i", fd); - - l = getxattr(fn, attribute, value, size); - if (l < 0) - return -errno; - - return l; -} - -static int parse_crtime(le64_t le, usec_t *usec) { - uint64_t u; - - assert(usec); - - u = le64toh(le); - if (u == 0 || u == (uint64_t) -1) - return -EIO; - - *usec = (usec_t) u; - return 0; -} - -int fd_getcrtime(int fd, usec_t *usec) { - le64_t le; - ssize_t n; - - assert(fd >= 0); - assert(usec); - - /* Until Linux gets a real concept of birthtime/creation time, - * let's fake one with xattrs */ - - n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le)); - if (n < 0) - return -errno; - if (n != sizeof(le)) - return -EIO; - - return parse_crtime(le, usec); -} - -int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) { - le64_t le; - ssize_t n; - - n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags); - if (n < 0) - return -errno; - if (n != sizeof(le)) - return -EIO; - - return parse_crtime(le, usec); -} - -int path_getcrtime(const char *p, usec_t *usec) { - le64_t le; - ssize_t n; - - assert(p); - assert(usec); - - n = getxattr(p, "user.crtime_usec", &le, sizeof(le)); - if (n < 0) - return -errno; - if (n != sizeof(le)) - return -EIO; - - return parse_crtime(le, usec); -} - -int fd_setcrtime(int fd, usec_t usec) { - le64_t le; - - assert(fd >= 0); - - if (usec <= 0) - usec = now(CLOCK_REALTIME); - - le = htole64((uint64_t) usec); - if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0) - return -errno; - - return 0; -} - int chattr_fd(int fd, unsigned value, unsigned mask) { unsigned old_attr, new_attr; struct stat st; @@ -2233,76 +2136,6 @@ int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char return 0; } -int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) { - char *v; - size_t l; - ssize_t n; - - assert(path); - assert(name); - assert(value); - - for (l = 100; ; l = (size_t) n + 1) { - v = new0(char, l); - if (!v) - return -ENOMEM; - - if (allow_symlink) - n = lgetxattr(path, name, v, l); - else - n = getxattr(path, name, v, l); - - if (n >= 0 && (size_t) n < l) { - *value = v; - return n; - } - - free(v); - - if (n < 0 && errno != ERANGE) - return -errno; - - if (allow_symlink) - n = lgetxattr(path, name, NULL, 0); - else - n = getxattr(path, name, NULL, 0); - if (n < 0) - return -errno; - } -} - -int fgetxattr_malloc(int fd, const char *name, char **value) { - char *v; - size_t l; - ssize_t n; - - assert(fd >= 0); - assert(name); - assert(value); - - for (l = 100; ; l = (size_t) n + 1) { - v = new0(char, l); - if (!v) - return -ENOMEM; - - n = fgetxattr(fd, name, v, l); - - if (n >= 0 && (size_t) n < l) { - *value = v; - return n; - } - - free(v); - - if (n < 0 && errno != ERANGE) - return -errno; - - n = fgetxattr(fd, name, NULL, 0); - if (n < 0) - return -errno; - } -} - int version(void) { puts(PACKAGE_STRING "\n" SYSTEMD_FEATURES); diff --git a/src/basic/util.h b/src/basic/util.h index 190d4f5edb..8f9f3f8fe6 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -500,13 +500,6 @@ union inotify_event_buffer { #define laccess(path, mode) faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW) -ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags); - -int fd_setcrtime(int fd, usec_t usec); -int fd_getcrtime(int fd, usec_t *usec); -int path_getcrtime(const char *p, usec_t *usec); -int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags); - int chattr_fd(int fd, unsigned value, unsigned mask); int chattr_path(const char *p, unsigned value, unsigned mask); @@ -517,9 +510,6 @@ int syslog_parse_priority(const char **p, int *priority, bool with_facility); int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath); -int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink); -int fgetxattr_malloc(int fd, const char *name, char **value); - int version(void); bool fdname_is_valid(const char *s); diff --git a/src/basic/xattr-util.c b/src/basic/xattr-util.c new file mode 100644 index 0000000000..35fd1c1616 --- /dev/null +++ b/src/basic/xattr-util.c @@ -0,0 +1,193 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <sys/xattr.h> + +#include "fd-util.h" +#include "sparse-endian.h" +#include "util.h" +#include "xattr-util.h" + +int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) { + char *v; + size_t l; + ssize_t n; + + assert(path); + assert(name); + assert(value); + + for (l = 100; ; l = (size_t) n + 1) { + v = new0(char, l); + if (!v) + return -ENOMEM; + + if (allow_symlink) + n = lgetxattr(path, name, v, l); + else + n = getxattr(path, name, v, l); + + if (n >= 0 && (size_t) n < l) { + *value = v; + return n; + } + + free(v); + + if (n < 0 && errno != ERANGE) + return -errno; + + if (allow_symlink) + n = lgetxattr(path, name, NULL, 0); + else + n = getxattr(path, name, NULL, 0); + if (n < 0) + return -errno; + } +} + +int fgetxattr_malloc(int fd, const char *name, char **value) { + char *v; + size_t l; + ssize_t n; + + assert(fd >= 0); + assert(name); + assert(value); + + for (l = 100; ; l = (size_t) n + 1) { + v = new0(char, l); + if (!v) + return -ENOMEM; + + n = fgetxattr(fd, name, v, l); + + if (n >= 0 && (size_t) n < l) { + *value = v; + return n; + } + + free(v); + + if (n < 0 && errno != ERANGE) + return -errno; + + n = fgetxattr(fd, name, NULL, 0); + if (n < 0) + return -errno; + } +} + +ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) { + char fn[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1]; + _cleanup_close_ int fd = -1; + ssize_t l; + + /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */ + + fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0)); + if (fd < 0) + return -errno; + + xsprintf(fn, "/proc/self/fd/%i", fd); + + l = getxattr(fn, attribute, value, size); + if (l < 0) + return -errno; + + return l; +} + +static int parse_crtime(le64_t le, usec_t *usec) { + uint64_t u; + + assert(usec); + + u = le64toh(le); + if (u == 0 || u == (uint64_t) -1) + return -EIO; + + *usec = (usec_t) u; + return 0; +} + +int fd_getcrtime(int fd, usec_t *usec) { + le64_t le; + ssize_t n; + + assert(fd >= 0); + assert(usec); + + /* Until Linux gets a real concept of birthtime/creation time, + * let's fake one with xattrs */ + + n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le)); + if (n < 0) + return -errno; + if (n != sizeof(le)) + return -EIO; + + return parse_crtime(le, usec); +} + +int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) { + le64_t le; + ssize_t n; + + n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags); + if (n < 0) + return -errno; + if (n != sizeof(le)) + return -EIO; + + return parse_crtime(le, usec); +} + +int path_getcrtime(const char *p, usec_t *usec) { + le64_t le; + ssize_t n; + + assert(p); + assert(usec); + + n = getxattr(p, "user.crtime_usec", &le, sizeof(le)); + if (n < 0) + return -errno; + if (n != sizeof(le)) + return -EIO; + + return parse_crtime(le, usec); +} + +int fd_setcrtime(int fd, usec_t usec) { + le64_t le; + + assert(fd >= 0); + + if (usec <= 0) + usec = now(CLOCK_REALTIME); + + le = htole64((uint64_t) usec); + if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0) + return -errno; + + return 0; +} diff --git a/src/basic/xattr-util.h b/src/basic/xattr-util.h new file mode 100644 index 0000000000..cf4cb12a25 --- /dev/null +++ b/src/basic/xattr-util.h @@ -0,0 +1,38 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <stdbool.h> +#include <sys/types.h> + +#include "time-util.h" + +int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink); +int fgetxattr_malloc(int fd, const char *name, char **value); + +ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags); + +int fd_setcrtime(int fd, usec_t usec); + +int fd_getcrtime(int fd, usec_t *usec); +int path_getcrtime(const char *p, usec_t *usec); +int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags); |