diff options
Diffstat (limited to 'src/libsystemd-basic/include')
103 files changed, 9759 insertions, 0 deletions
| diff --git a/src/libsystemd-basic/include/systemd-basic/MurmurHash2.h b/src/libsystemd-basic/include/systemd-basic/MurmurHash2.h new file mode 100644 index 0000000000..93362dd485 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/MurmurHash2.h @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// MurmurHash2 was written by Austin Appleby, and is placed in the public +// domain. The author hereby disclaims copyright to this source code. + +#ifndef _MURMURHASH2_H_ +#define _MURMURHASH2_H_ + +//----------------------------------------------------------------------------- +// Platform-specific functions and macros + +// Microsoft Visual Studio + +#if defined(_MSC_VER) + +typedef unsigned char uint8_t; +typedef unsigned long uint32_t; +typedef unsigned __int64 uint64_t; + +// Other compilers + +#else	// defined(_MSC_VER) + +#include <stdint.h> + +#endif // !defined(_MSC_VER) + +//----------------------------------------------------------------------------- + +uint32_t MurmurHash2        ( const void * key, int len, uint32_t seed ); + +//----------------------------------------------------------------------------- + +#endif // _MURMURHASH2_H_ diff --git a/src/libsystemd-basic/include/systemd-basic/af-list.h b/src/libsystemd-basic/include/systemd-basic/af-list.h new file mode 100644 index 0000000000..6a4cc03839 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/af-list.h @@ -0,0 +1,41 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2014 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 "string-util.h" + +const char *af_to_name(int id); +int af_from_name(const char *name); + +static inline const char* af_to_name_short(int id) { +        const char *f; + +        if (id == AF_UNSPEC) +                return "*"; + +        f = af_to_name(id); +        if (!f) +                return "unknown"; + +        assert(startswith(f, "AF_")); +        return f + 3; +} + +int af_max(void); diff --git a/src/libsystemd-basic/include/systemd-basic/alloc-util.h b/src/libsystemd-basic/include/systemd-basic/alloc-util.h new file mode 100644 index 0000000000..a44dd473c1 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/alloc-util.h @@ -0,0 +1,119 @@ +#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 <alloca.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +#include "macro.h" + +#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n))) + +#define new0(t, n) ((t*) calloc((n), sizeof(t))) + +#define newa(t, n) ((t*) alloca(sizeof(t)*(n))) + +#define newa0(t, n) ((t*) alloca0(sizeof(t)*(n))) + +#define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n))) + +#define malloc0(n) (calloc(1, (n))) + +static inline void *mfree(void *memory) { +        free(memory); +        return NULL; +} + +#define free_and_replace(a, b)                  \ +        ({                                      \ +                free(a);                        \ +                (a) = (b);                      \ +                (b) = NULL;                     \ +                0;                              \ +        }) + +void* memdup(const void *p, size_t l) _alloc_(2); + +static inline void freep(void *p) { +        free(*(void**) p); +} + +#define _cleanup_free_ _cleanup_(freep) + +static inline bool size_multiply_overflow(size_t size, size_t need) { +        return _unlikely_(need != 0 && size > (SIZE_MAX / need)); +} + +_malloc_  _alloc_(1, 2) static inline void *malloc_multiply(size_t size, size_t need) { +        if (size_multiply_overflow(size, need)) +                return NULL; + +        return malloc(size * need); +} + +_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t size, size_t need) { +        if (size_multiply_overflow(size, need)) +                return NULL; + +        return realloc(p, size * need); +} + +_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, size_t need) { +        if (size_multiply_overflow(size, need)) +                return NULL; + +        return memdup(p, size * need); +} + +void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size); +void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size); + +#define GREEDY_REALLOC(array, allocated, need)                          \ +        greedy_realloc((void**) &(array), &(allocated), (need), sizeof((array)[0])) + +#define GREEDY_REALLOC0(array, allocated, need)                         \ +        greedy_realloc0((void**) &(array), &(allocated), (need), sizeof((array)[0])) + +#define alloca0(n)                                      \ +        ({                                              \ +                char *_new_;                            \ +                size_t _len_ = n;                       \ +                _new_ = alloca(_len_);                  \ +                (void *) memset(_new_, 0, _len_);       \ +        }) + +/* It's not clear what alignment glibc/gcc alloca() guarantee, hence provide a guaranteed safe version */ +#define alloca_align(size, align)                                       \ +        ({                                                              \ +                void *_ptr_;                                            \ +                size_t _mask_ = (align) - 1;                            \ +                _ptr_ = alloca((size) + _mask_);                        \ +                (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_);         \ +        }) + +#define alloca0_align(size, align)                                      \ +        ({                                                              \ +                void *_new_;                                            \ +                size_t _size_ = (size);                                 \ +                _new_ = alloca_align(_size_, (align));                  \ +                (void*)memset(_new_, 0, _size_);                        \ +        }) diff --git a/src/libsystemd-basic/include/systemd-basic/architecture.h b/src/libsystemd-basic/include/systemd-basic/architecture.h new file mode 100644 index 0000000000..5a77c31932 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/architecture.h @@ -0,0 +1,211 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2014 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 <endian.h> + +#include "macro.h" +#include "util.h" + +/* A cleaned up architecture definition. We don't want to get lost in + * processor features, models, generations or even ABIs. Hence we + * focus on general family, and distinguish word width and + * endianness. */ + +enum { +        ARCHITECTURE_X86 = 0, +        ARCHITECTURE_X86_64, +        ARCHITECTURE_PPC, +        ARCHITECTURE_PPC_LE, +        ARCHITECTURE_PPC64, +        ARCHITECTURE_PPC64_LE, +        ARCHITECTURE_IA64, +        ARCHITECTURE_PARISC, +        ARCHITECTURE_PARISC64, +        ARCHITECTURE_S390, +        ARCHITECTURE_S390X, +        ARCHITECTURE_SPARC, +        ARCHITECTURE_SPARC64, +        ARCHITECTURE_MIPS, +        ARCHITECTURE_MIPS_LE, +        ARCHITECTURE_MIPS64, +        ARCHITECTURE_MIPS64_LE, +        ARCHITECTURE_ALPHA, +        ARCHITECTURE_ARM, +        ARCHITECTURE_ARM_BE, +        ARCHITECTURE_ARM64, +        ARCHITECTURE_ARM64_BE, +        ARCHITECTURE_SH, +        ARCHITECTURE_SH64, +        ARCHITECTURE_M68K, +        ARCHITECTURE_TILEGX, +        ARCHITECTURE_CRIS, +        ARCHITECTURE_NIOS2, +        ARCHITECTURE_RISCV32, +        ARCHITECTURE_RISCV64, +        _ARCHITECTURE_MAX, +        _ARCHITECTURE_INVALID = -1 +}; + +int uname_architecture(void); + +/* + * LIB_ARCH_TUPLE should resolve to the local library path + * architecture tuple systemd is built for, according to the Debian + * tuple list: + * + * https://wiki.debian.org/Multiarch/Tuples + * + * This is used in library search paths that should understand + * Debian's paths on all distributions. + */ + +#if defined(__x86_64__) +#  define native_architecture() ARCHITECTURE_X86_64 +#  define LIB_ARCH_TUPLE "x86_64-linux-gnu" +#  define SECONDARY_ARCHITECTURE ARCHITECTURE_X86 +#elif defined(__i386__) +#  define native_architecture() ARCHITECTURE_X86 +#  define LIB_ARCH_TUPLE "i386-linux-gnu" +#elif defined(__powerpc64__) +#  if __BYTE_ORDER == __BIG_ENDIAN +#    define native_architecture() ARCHITECTURE_PPC64 +#    define LIB_ARCH_TUPLE "ppc64-linux-gnu" +#    define SECONDARY_ARCHITECTURE ARCHITECTURE_PPC +#  else +#    define native_architecture() ARCHITECTURE_PPC64_LE +#    define LIB_ARCH_TUPLE  "powerpc64le-linux-gnu" +#    define SECONDARY_ARCHITECTURE ARCHITECTURE_PPC_LE +#  endif +#elif defined(__powerpc__) +#  if __BYTE_ORDER == __BIG_ENDIAN +#    define native_architecture() ARCHITECTURE_PPC +#    define LIB_ARCH_TUPLE "powerpc-linux-gnu" +#  else +#    define native_architecture() ARCHITECTURE_PPC_LE +#    error "Missing LIB_ARCH_TUPLE for PPCLE" +#  endif +#elif defined(__ia64__) +#  define native_architecture() ARCHITECTURE_IA64 +#  define LIB_ARCH_TUPLE "ia64-linux-gnu" +#elif defined(__hppa64__) +#  define native_architecture() ARCHITECTURE_PARISC64 +#  error "Missing LIB_ARCH_TUPLE for HPPA64" +#elif defined(__hppa__) +#  define native_architecture() ARCHITECTURE_PARISC +#  define LIB_ARCH_TUPLE "hppa‑linux‑gnu" +#elif defined(__s390x__) +#  define native_architecture() ARCHITECTURE_S390X +#  define LIB_ARCH_TUPLE "s390x-linux-gnu" +#  define SECONDARY_ARCHITECTURE ARCHITECTURE_S390 +#elif defined(__s390__) +#  define native_architecture() ARCHITECTURE_S390 +#  define LIB_ARCH_TUPLE "s390-linux-gnu" +#elif defined(__sparc__) && defined (__arch64__) +#  define native_architecture() ARCHITECTURE_SPARC64 +#  define LIB_ARCH_TUPLE "sparc64-linux-gnu" +#elif defined(__sparc__) +#  define native_architecture() ARCHITECTURE_SPARC +#  define LIB_ARCH_TUPLE "sparc-linux-gnu" +#elif defined(__mips64__) +#  if __BYTE_ORDER == __BIG_ENDIAN +#    define native_architecture() ARCHITECTURE_MIPS64 +#    error "Missing LIB_ARCH_TUPLE for MIPS64" +#  else +#    define native_architecture() ARCHITECTURE_MIPS64_LE +#    error "Missing LIB_ARCH_TUPLE for MIPS64_LE" +#  endif +#elif defined(__mips__) +#  if __BYTE_ORDER == __BIG_ENDIAN +#    define native_architecture() ARCHITECTURE_MIPS +#    define LIB_ARCH_TUPLE "mips-linux-gnu" +#  else +#    define native_architecture() ARCHITECTURE_MIPS_LE +#    define LIB_ARCH_TUPLE "mipsel-linux-gnu" +#  endif +#elif defined(__alpha__) +#  define native_architecture() ARCHITECTURE_ALPHA +#  define LIB_ARCH_TUPLE "alpha-linux-gnu" +#elif defined(__aarch64__) +#  if __BYTE_ORDER == __BIG_ENDIAN +#    define native_architecture() ARCHITECTURE_ARM64_BE +#    define LIB_ARCH_TUPLE "aarch64_be-linux-gnu" +#  else +#    define native_architecture() ARCHITECTURE_ARM64 +#    define LIB_ARCH_TUPLE "aarch64-linux-gnu" +#  endif +#elif defined(__arm__) +#  if __BYTE_ORDER == __BIG_ENDIAN +#    define native_architecture() ARCHITECTURE_ARM_BE +#    if defined(__ARM_EABI__) +#      if defined(__ARM_PCS_VFP) +#        define LIB_ARCH_TUPLE "armeb-linux-gnueabihf" +#      else +#        define LIB_ARCH_TUPLE "armeb-linux-gnueabi" +#      endif +#    else +#      define LIB_ARCH_TUPLE "armeb-linux-gnu" +#    endif +#  else +#    define native_architecture() ARCHITECTURE_ARM +#    if defined(__ARM_EABI__) +#      if defined(__ARM_PCS_VFP) +#        define LIB_ARCH_TUPLE "arm-linux-gnueabihf" +#      else +#        define LIB_ARCH_TUPLE "arm-linux-gnueabi" +#      endif +#    else +#      define LIB_ARCH_TUPLE "arm-linux-gnu" +#    endif +#  endif +#elif defined(__sh64__) +#  define native_architecture() ARCHITECTURE_SH64 +#  error "Missing LIB_ARCH_TUPLE for SH64" +#elif defined(__sh__) +#  define native_architecture() ARCHITECTURE_SH +#  define LIB_ARCH_TUPLE "sh4-linux-gnu" +#elif defined(__m68k__) +#  define native_architecture() ARCHITECTURE_M68K +#  define LIB_ARCH_TUPLE "m68k-linux-gnu" +#elif defined(__tilegx__) +#  define native_architecture() ARCHITECTURE_TILEGX +#  error "Missing LIB_ARCH_TUPLE for TILEGX" +#elif defined(__cris__) +#  define native_architecture() ARCHITECTURE_CRIS +#  error "Missing LIB_ARCH_TUPLE for CRIS" +#elif defined(__nios2__) +#  define native_architecture() ARCHITECTURE_NIOS2 +#  define LIB_ARCH_TUPLE "nios2-linux-gnu" +#elif defined(__riscv__) +#  if __SIZEOF_POINTER__ == 4 +#    define native_architecture() ARCHITECTURE_RISCV32 +#    define LIB_ARCH_TUPLE "riscv32-linux-gnu" +#  elif __SIZEOF_POINTER__ == 8 +#    define native_architecture() ARCHITECTURE_RISCV64 +#    define LIB_ARCH_TUPLE "riscv64-linux-gnu" +#  else +#    error "Unrecognized riscv architecture variant" +#  endif +#else +#  error "Please register your architecture here!" +#endif + +const char *architecture_to_string(int a) _const_; +int architecture_from_string(const char *s) _pure_; diff --git a/src/libsystemd-basic/include/systemd-basic/arphrd-list.h b/src/libsystemd-basic/include/systemd-basic/arphrd-list.h new file mode 100644 index 0000000000..c0f8758dbe --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/arphrd-list.h @@ -0,0 +1,25 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2014 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/>. +***/ + +const char *arphrd_to_name(int id); +int arphrd_from_name(const char *name); + +int arphrd_max(void); diff --git a/src/libsystemd-basic/include/systemd-basic/async.h b/src/libsystemd-basic/include/systemd-basic/async.h new file mode 100644 index 0000000000..9bd13ff6e0 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/async.h @@ -0,0 +1,25 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2013 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/>. +***/ + +int asynchronous_job(void* (*func)(void *p), void *arg); + +int asynchronous_sync(void); +int asynchronous_close(int fd); diff --git a/src/libsystemd-basic/include/systemd-basic/audit-util.h b/src/libsystemd-basic/include/systemd-basic/audit-util.h new file mode 100644 index 0000000000..e048503991 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/audit-util.h @@ -0,0 +1,31 @@ +#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 <stdint.h> +#include <sys/types.h> + +#define AUDIT_SESSION_INVALID ((uint32_t) -1) + +int audit_session_from_pid(pid_t pid, uint32_t *id); +int audit_loginuid_from_pid(pid_t pid, uid_t *uid); + +bool use_audit(void); diff --git a/src/libsystemd-basic/include/systemd-basic/barrier.h b/src/libsystemd-basic/include/systemd-basic/barrier.h new file mode 100644 index 0000000000..6347fddc4d --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/barrier.h @@ -0,0 +1,91 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2014 David Herrmann <dh.herrmann@gmail.com> + +  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 <stdint.h> +#include <sys/types.h> + +#include "macro.h" + +/* See source file for an API description. */ + +typedef struct Barrier Barrier; + +enum { +        BARRIER_SINGLE                  = 1LL, +        BARRIER_ABORTION                = INT64_MAX, + +        /* bias values to store state; keep @WE < @THEY < @I */ +        BARRIER_BIAS                    = INT64_MIN, +        BARRIER_WE_ABORTED              = BARRIER_BIAS + 1LL, +        BARRIER_THEY_ABORTED            = BARRIER_BIAS + 2LL, +        BARRIER_I_ABORTED               = BARRIER_BIAS + 3LL, +}; + +enum { +        BARRIER_PARENT, +        BARRIER_CHILD, +}; + +struct Barrier { +        int me; +        int them; +        int pipe[2]; +        int64_t barriers; +}; + +#define BARRIER_NULL {-1, -1, {-1, -1}, 0} + +int barrier_create(Barrier *obj); +void barrier_destroy(Barrier *b); + +DEFINE_TRIVIAL_CLEANUP_FUNC(Barrier*, barrier_destroy); + +void barrier_set_role(Barrier *b, unsigned int role); + +bool barrier_place(Barrier *b); +bool barrier_abort(Barrier *b); + +bool barrier_wait_next(Barrier *b); +bool barrier_wait_abortion(Barrier *b); +bool barrier_sync_next(Barrier *b); +bool barrier_sync(Barrier *b); + +static inline bool barrier_i_aborted(Barrier *b) { +        return b->barriers == BARRIER_I_ABORTED || b->barriers == BARRIER_WE_ABORTED; +} + +static inline bool barrier_they_aborted(Barrier *b) { +        return b->barriers == BARRIER_THEY_ABORTED || b->barriers == BARRIER_WE_ABORTED; +} + +static inline bool barrier_we_aborted(Barrier *b) { +        return b->barriers == BARRIER_WE_ABORTED; +} + +static inline bool barrier_is_aborted(Barrier *b) { +        return b->barriers == BARRIER_I_ABORTED || b->barriers == BARRIER_THEY_ABORTED || b->barriers == BARRIER_WE_ABORTED; +} + +static inline bool barrier_place_and_sync(Barrier *b) { +        (void) barrier_place(b); +        return barrier_sync(b); +} diff --git a/src/libsystemd-basic/include/systemd-basic/bitmap.h b/src/libsystemd-basic/include/systemd-basic/bitmap.h new file mode 100644 index 0000000000..63fdbe8bea --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/bitmap.h @@ -0,0 +1,49 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2015 Tom Gundersen + +  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 "hashmap.h" +#include "macro.h" + +typedef struct Bitmap Bitmap; + +Bitmap *bitmap_new(void); +Bitmap *bitmap_copy(Bitmap *b); +int bitmap_ensure_allocated(Bitmap **b); +void bitmap_free(Bitmap *b); + +int bitmap_set(Bitmap *b, unsigned n); +void bitmap_unset(Bitmap *b, unsigned n); +bool bitmap_isset(Bitmap *b, unsigned n); +bool bitmap_isclear(Bitmap *b); +void bitmap_clear(Bitmap *b); + +bool bitmap_iterate(Bitmap *b, Iterator *i, unsigned *n); + +bool bitmap_equal(Bitmap *a, Bitmap *b); + +#define BITMAP_FOREACH(n, b, i) \ +        for ((i).idx = 0; bitmap_iterate((b), &(i), (unsigned*)&(n)); ) + +DEFINE_TRIVIAL_CLEANUP_FUNC(Bitmap*, bitmap_free); + +#define _cleanup_bitmap_free_ _cleanup_(bitmap_freep) diff --git a/src/libsystemd-basic/include/systemd-basic/btrfs-ctree.h b/src/libsystemd-basic/include/systemd-basic/btrfs-ctree.h new file mode 100644 index 0000000000..66bdf9736e --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/btrfs-ctree.h @@ -0,0 +1,96 @@ +#pragma once + +#include "macro.h" +#include "sparse-endian.h" + +/* Stolen from btrfs' ctree.h */ + +struct btrfs_timespec { +        le64_t sec; +        le32_t nsec; +} _packed_; + +struct btrfs_disk_key { +        le64_t objectid; +        uint8_t type; +        le64_t offset; +} _packed_; + +struct btrfs_inode_item { +        le64_t generation; +        le64_t transid; +        le64_t size; +        le64_t nbytes; +        le64_t block_group; +        le32_t nlink; +        le32_t uid; +        le32_t gid; +        le32_t mode; +        le64_t rdev; +        le64_t flags; +        le64_t sequence; +        le64_t reserved[4]; +        struct btrfs_timespec atime; +        struct btrfs_timespec ctime; +        struct btrfs_timespec mtime; +        struct btrfs_timespec otime; +} _packed_; + +struct btrfs_root_item { +        struct btrfs_inode_item inode; +        le64_t generation; +        le64_t root_dirid; +        le64_t bytenr; +        le64_t byte_limit; +        le64_t bytes_used; +        le64_t last_snapshot; +        le64_t flags; +        le32_t refs; +        struct btrfs_disk_key drop_progress; +        uint8_t drop_level; +        uint8_t level; +        le64_t generation_v2; +        uint8_t uuid[BTRFS_UUID_SIZE]; +        uint8_t parent_uuid[BTRFS_UUID_SIZE]; +        uint8_t received_uuid[BTRFS_UUID_SIZE]; +        le64_t ctransid; +        le64_t otransid; +        le64_t stransid; +        le64_t rtransid; +        struct btrfs_timespec ctime; +        struct btrfs_timespec otime; +        struct btrfs_timespec stime; +        struct btrfs_timespec rtime; +        le64_t reserved[8]; +} _packed_; + +#define BTRFS_ROOT_SUBVOL_RDONLY (1ULL << 0) + +struct btrfs_qgroup_info_item { +        le64_t generation; +        le64_t rfer; +        le64_t rfer_cmpr; +        le64_t excl; +        le64_t excl_cmpr; +} _packed_; + +#define BTRFS_QGROUP_LIMIT_MAX_RFER     (1ULL << 0) +#define BTRFS_QGROUP_LIMIT_MAX_EXCL     (1ULL << 1) +#define BTRFS_QGROUP_LIMIT_RSV_RFER     (1ULL << 2) +#define BTRFS_QGROUP_LIMIT_RSV_EXCL     (1ULL << 3) +#define BTRFS_QGROUP_LIMIT_RFER_CMPR    (1ULL << 4) +#define BTRFS_QGROUP_LIMIT_EXCL_CMPR    (1ULL << 5) + +struct btrfs_qgroup_limit_item { +        le64_t flags; +        le64_t max_rfer; +        le64_t max_excl; +        le64_t rsv_rfer; +        le64_t rsv_excl; +} _packed_; + +struct btrfs_root_ref { +        le64_t dirid; +        le64_t sequence; +        le16_t name_len; +} _packed_; diff --git a/src/libsystemd-basic/include/systemd-basic/btrfs-util.h b/src/libsystemd-basic/include/systemd-basic/btrfs-util.h new file mode 100644 index 0000000000..db431f5b74 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/btrfs-util.h @@ -0,0 +1,131 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2014 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 <stdint.h> +#include <sys/types.h> + +#include <systemd/sd-id128.h> + +#include "time-util.h" + +typedef struct BtrfsSubvolInfo { +        uint64_t subvol_id; +        usec_t otime; + +        sd_id128_t uuid; +        sd_id128_t parent_uuid; + +        bool read_only; +} BtrfsSubvolInfo; + +typedef struct BtrfsQuotaInfo { +        uint64_t referenced; +        uint64_t exclusive; +        uint64_t referenced_max; +        uint64_t exclusive_max; +} BtrfsQuotaInfo; + +typedef enum BtrfsSnapshotFlags { +        BTRFS_SNAPSHOT_FALLBACK_COPY = 1, +        BTRFS_SNAPSHOT_READ_ONLY = 2, +        BTRFS_SNAPSHOT_RECURSIVE = 4, +        BTRFS_SNAPSHOT_QUOTA = 8, +} BtrfsSnapshotFlags; + +typedef enum BtrfsRemoveFlags { +        BTRFS_REMOVE_RECURSIVE = 1, +        BTRFS_REMOVE_QUOTA = 2, +} BtrfsRemoveFlags; + +int btrfs_is_filesystem(int fd); + +int btrfs_is_subvol_fd(int fd); +int btrfs_is_subvol(const char *path); + +int btrfs_reflink(int infd, int outfd); +int btrfs_clone_range(int infd, uint64_t in_offset, int ofd, uint64_t out_offset, uint64_t sz); + +int btrfs_get_block_device_fd(int fd, dev_t *dev); +int btrfs_get_block_device(const char *path, dev_t *dev); + +int btrfs_defrag_fd(int fd); +int btrfs_defrag(const char *p); + +int btrfs_quota_enable_fd(int fd, bool b); +int btrfs_quota_enable(const char *path, bool b); + +int btrfs_quota_scan_start(int fd); +int btrfs_quota_scan_wait(int fd); +int btrfs_quota_scan_ongoing(int fd); + +int btrfs_resize_loopback_fd(int fd, uint64_t size, bool grow_only); +int btrfs_resize_loopback(const char *path, uint64_t size, bool grow_only); + +int btrfs_subvol_make(const char *path); +int btrfs_subvol_make_label(const char *path); + +int btrfs_subvol_snapshot_fd(int old_fd, const char *new_path, BtrfsSnapshotFlags flags); +int btrfs_subvol_snapshot(const char *old_path, const char *new_path, BtrfsSnapshotFlags flags); + +int btrfs_subvol_remove(const char *path, BtrfsRemoveFlags flags); +int btrfs_subvol_remove_fd(int fd, const char *subvolume, BtrfsRemoveFlags flags); + +int btrfs_subvol_set_read_only_fd(int fd, bool b); +int btrfs_subvol_set_read_only(const char *path, bool b); +int btrfs_subvol_get_read_only_fd(int fd); + +int btrfs_subvol_get_id(int fd, const char *subvolume, uint64_t *ret); +int btrfs_subvol_get_id_fd(int fd, uint64_t *ret); +int btrfs_subvol_get_parent(int fd, uint64_t subvol_id, uint64_t *ret); + +int btrfs_subvol_get_info_fd(int fd, uint64_t subvol_id, BtrfsSubvolInfo *info); + +int btrfs_subvol_find_subtree_qgroup(int fd, uint64_t subvol_id, uint64_t *ret); + +int btrfs_subvol_get_subtree_quota(const char *path, uint64_t subvol_id, BtrfsQuotaInfo *quota); +int btrfs_subvol_get_subtree_quota_fd(int fd, uint64_t subvol_id, BtrfsQuotaInfo *quota); + +int btrfs_subvol_set_subtree_quota_limit(const char *path, uint64_t subvol_id, uint64_t referenced_max); +int btrfs_subvol_set_subtree_quota_limit_fd(int fd, uint64_t subvol_id, uint64_t referenced_max); + +int btrfs_subvol_auto_qgroup_fd(int fd, uint64_t subvol_id, bool new_qgroup); +int btrfs_subvol_auto_qgroup(const char *path, uint64_t subvol_id, bool create_intermediary_qgroup); + +int btrfs_qgroupid_make(uint64_t level, uint64_t id, uint64_t *ret); +int btrfs_qgroupid_split(uint64_t qgroupid, uint64_t *level, uint64_t *id); + +int btrfs_qgroup_create(int fd, uint64_t qgroupid); +int btrfs_qgroup_destroy(int fd, uint64_t qgroupid); +int btrfs_qgroup_destroy_recursive(int fd, uint64_t qgroupid); + +int btrfs_qgroup_set_limit_fd(int fd, uint64_t qgroupid, uint64_t referenced_max); +int btrfs_qgroup_set_limit(const char *path, uint64_t qgroupid, uint64_t referenced_max); + +int btrfs_qgroup_copy_limits(int fd, uint64_t old_qgroupid, uint64_t new_qgroupid); + +int btrfs_qgroup_assign(int fd, uint64_t child, uint64_t parent); +int btrfs_qgroup_unassign(int fd, uint64_t child, uint64_t parent); + +int btrfs_qgroup_find_parents(int fd, uint64_t qgroupid, uint64_t **ret); + +int btrfs_qgroup_get_quota_fd(int fd, uint64_t qgroupid, BtrfsQuotaInfo *quota); +int btrfs_qgroup_get_quota(const char *path, uint64_t qgroupid, BtrfsQuotaInfo *quota); diff --git a/src/libsystemd-basic/include/systemd-basic/build.h b/src/libsystemd-basic/include/systemd-basic/build.h new file mode 100644 index 0000000000..633c2aaccb --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/build.h @@ -0,0 +1,155 @@ +#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/>. +***/ + +#ifdef HAVE_PAM +#define _PAM_FEATURE_ "+PAM" +#else +#define _PAM_FEATURE_ "-PAM" +#endif + +#ifdef HAVE_AUDIT +#define _AUDIT_FEATURE_ "+AUDIT" +#else +#define _AUDIT_FEATURE_ "-AUDIT" +#endif + +#ifdef HAVE_SELINUX +#define _SELINUX_FEATURE_ "+SELINUX" +#else +#define _SELINUX_FEATURE_ "-SELINUX" +#endif + +#ifdef HAVE_APPARMOR +#define _APPARMOR_FEATURE_ "+APPARMOR" +#else +#define _APPARMOR_FEATURE_ "-APPARMOR" +#endif + +#ifdef HAVE_IMA +#define _IMA_FEATURE_ "+IMA" +#else +#define _IMA_FEATURE_ "-IMA" +#endif + +#ifdef HAVE_SMACK +#define _SMACK_FEATURE_ "+SMACK" +#else +#define _SMACK_FEATURE_ "-SMACK" +#endif + +#ifdef HAVE_SYSV_COMPAT +#define _SYSVINIT_FEATURE_ "+SYSVINIT" +#else +#define _SYSVINIT_FEATURE_ "-SYSVINIT" +#endif + +#ifdef HAVE_UTMP +#define _UTMP_FEATURE_ "+UTMP" +#else +#define _UTMP_FEATURE_ "-UTMP" +#endif + +#ifdef HAVE_LIBCRYPTSETUP +#define _LIBCRYPTSETUP_FEATURE_ "+LIBCRYPTSETUP" +#else +#define _LIBCRYPTSETUP_FEATURE_ "-LIBCRYPTSETUP" +#endif + +#ifdef HAVE_GCRYPT +#define _GCRYPT_FEATURE_ "+GCRYPT" +#else +#define _GCRYPT_FEATURE_ "-GCRYPT" +#endif + +#ifdef HAVE_GNUTLS +#define _GNUTLS_FEATURE_ "+GNUTLS" +#else +#define _GNUTLS_FEATURE_ "-GNUTLS" +#endif + +#ifdef HAVE_ACL +#define _ACL_FEATURE_ "+ACL" +#else +#define _ACL_FEATURE_ "-ACL" +#endif + +#ifdef HAVE_XZ +#define _XZ_FEATURE_ "+XZ" +#else +#define _XZ_FEATURE_ "-XZ" +#endif + +#ifdef HAVE_LZ4 +#define _LZ4_FEATURE_ "+LZ4" +#else +#define _LZ4_FEATURE_ "-LZ4" +#endif + +#ifdef HAVE_SECCOMP +#define _SECCOMP_FEATURE_ "+SECCOMP" +#else +#define _SECCOMP_FEATURE_ "-SECCOMP" +#endif + +#ifdef HAVE_BLKID +#define _BLKID_FEATURE_ "+BLKID" +#else +#define _BLKID_FEATURE_ "-BLKID" +#endif + +#ifdef HAVE_ELFUTILS +#define _ELFUTILS_FEATURE_ "+ELFUTILS" +#else +#define _ELFUTILS_FEATURE_ "-ELFUTILS" +#endif + +#ifdef HAVE_KMOD +#define _KMOD_FEATURE_ "+KMOD" +#else +#define _KMOD_FEATURE_ "-KMOD" +#endif + +#ifdef HAVE_LIBIDN +#define _IDN_FEATURE_ "+IDN" +#else +#define _IDN_FEATURE_ "-IDN" +#endif + +#define SYSTEMD_FEATURES                                                \ +        _PAM_FEATURE_ " "                                               \ +        _AUDIT_FEATURE_ " "                                             \ +        _SELINUX_FEATURE_ " "                                           \ +        _IMA_FEATURE_ " "                                               \ +        _APPARMOR_FEATURE_ " "                                          \ +        _SMACK_FEATURE_ " "                                             \ +        _SYSVINIT_FEATURE_ " "                                          \ +        _UTMP_FEATURE_ " "                                              \ +        _LIBCRYPTSETUP_FEATURE_ " "                                     \ +        _GCRYPT_FEATURE_ " "                                            \ +        _GNUTLS_FEATURE_ " "                                            \ +        _ACL_FEATURE_ " "                                               \ +        _XZ_FEATURE_ " "                                                \ +        _LZ4_FEATURE_ " "                                               \ +        _SECCOMP_FEATURE_ " "                                           \ +        _BLKID_FEATURE_ " "                                             \ +        _ELFUTILS_FEATURE_ " "                                          \ +        _KMOD_FEATURE_ " "                                              \ +        _IDN_FEATURE_ diff --git a/src/libsystemd-basic/include/systemd-basic/bus-label.h b/src/libsystemd-basic/include/systemd-basic/bus-label.h new file mode 100644 index 0000000000..62fb2c450c --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/bus-label.h @@ -0,0 +1,31 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2013 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 <stddef.h> +#include <stdlib.h> +#include <string.h> + +char *bus_label_escape(const char *s); +char *bus_label_unescape_n(const char *f, size_t l); + +static inline char *bus_label_unescape(const char *f) { +        return bus_label_unescape_n(f, f ? strlen(f) : 0); +} diff --git a/src/libsystemd-basic/include/systemd-basic/calendarspec.h b/src/libsystemd-basic/include/systemd-basic/calendarspec.h new file mode 100644 index 0000000000..c6087228fd --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/calendarspec.h @@ -0,0 +1,59 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2012 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/>. +***/ + +/* A structure for specifying (possibly repetitive) points in calendar + * time, a la cron */ + +#include <stdbool.h> + +#include "time-util.h" +#include "util.h" + +typedef struct CalendarComponent { +        int value; +        int repeat; + +        struct CalendarComponent *next; +} CalendarComponent; + +typedef struct CalendarSpec { +        int weekdays_bits; +        bool utc; +        int dst; + +        CalendarComponent *year; +        CalendarComponent *month; +        CalendarComponent *day; + +        CalendarComponent *hour; +        CalendarComponent *minute; +        CalendarComponent *microsecond; +} CalendarSpec; + +void calendar_spec_free(CalendarSpec *c); + +int calendar_spec_normalize(CalendarSpec *spec); +bool calendar_spec_valid(CalendarSpec *spec); + +int calendar_spec_to_string(const CalendarSpec *spec, char **p); +int calendar_spec_from_string(const char *p, CalendarSpec **spec); + +int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next); diff --git a/src/libsystemd-basic/include/systemd-basic/cap-list.h b/src/libsystemd-basic/include/systemd-basic/cap-list.h new file mode 100644 index 0000000000..c1f6b94ad3 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/cap-list.h @@ -0,0 +1,24 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2014 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/>. +***/ + +const char *capability_to_name(int id); +int capability_from_name(const char *name); +int capability_list_length(void); diff --git a/src/libsystemd-basic/include/systemd-basic/capability-util.h b/src/libsystemd-basic/include/systemd-basic/capability-util.h new file mode 100644 index 0000000000..35a896e229 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/capability-util.h @@ -0,0 +1,57 @@ +#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 <stdint.h> +#include <sys/capability.h> +#include <sys/types.h> + +#include "macro.h" +#include "util.h" + +#define CAP_ALL (uint64_t) -1 + +unsigned long cap_last_cap(void); +int have_effective_cap(int value); +int capability_bounding_set_drop(uint64_t keep, bool right_now); +int capability_bounding_set_drop_usermode(uint64_t keep); + +int capability_ambient_set_apply(uint64_t set, bool also_inherit); +int capability_update_inherited_set(cap_t caps, uint64_t ambient_set); + +int drop_privileges(uid_t uid, gid_t gid, uint64_t keep_capabilities); + +int drop_capability(cap_value_t cv); + +DEFINE_TRIVIAL_CLEANUP_FUNC(cap_t, cap_free); +#define _cleanup_cap_free_ _cleanup_(cap_freep) + +static inline void cap_free_charpp(char **p) { +        if (*p) +                cap_free(*p); +} +#define _cleanup_cap_free_charp_ _cleanup_(cap_free_charpp) + +static inline bool cap_test_all(uint64_t caps) { +        uint64_t m; +        m = (UINT64_C(1) << (cap_last_cap() + 1)) - 1; +        return (caps & m) == m; +} diff --git a/src/libsystemd-basic/include/systemd-basic/cgroup-util.h b/src/libsystemd-basic/include/systemd-basic/cgroup-util.h new file mode 100644 index 0000000000..0aa27c4cd7 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/cgroup-util.h @@ -0,0 +1,260 @@ +#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 <dirent.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <sys/statfs.h> +#include <sys/types.h> + +#include "def.h" +#include "hashmap.h" +#include "macro.h" +#include "set.h" + +/* An enum of well known cgroup controllers */ +typedef enum CGroupController { +        CGROUP_CONTROLLER_CPU, +        CGROUP_CONTROLLER_CPUACCT, +        CGROUP_CONTROLLER_IO, +        CGROUP_CONTROLLER_BLKIO, +        CGROUP_CONTROLLER_MEMORY, +        CGROUP_CONTROLLER_DEVICES, +        CGROUP_CONTROLLER_PIDS, +        _CGROUP_CONTROLLER_MAX, +        _CGROUP_CONTROLLER_INVALID = -1, +} CGroupController; + +#define CGROUP_CONTROLLER_TO_MASK(c) (1 << (c)) + +/* A bit mask of well known cgroup controllers */ +typedef enum CGroupMask { +        CGROUP_MASK_CPU = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPU), +        CGROUP_MASK_CPUACCT = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_CPUACCT), +        CGROUP_MASK_IO = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_IO), +        CGROUP_MASK_BLKIO = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BLKIO), +        CGROUP_MASK_MEMORY = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_MEMORY), +        CGROUP_MASK_DEVICES = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_DEVICES), +        CGROUP_MASK_PIDS = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_PIDS), +        _CGROUP_MASK_ALL = CGROUP_CONTROLLER_TO_MASK(_CGROUP_CONTROLLER_MAX) - 1 +} CGroupMask; + +/* Special values for all weight knobs on unified hierarchy */ +#define CGROUP_WEIGHT_INVALID ((uint64_t) -1) +#define CGROUP_WEIGHT_MIN UINT64_C(1) +#define CGROUP_WEIGHT_MAX UINT64_C(10000) +#define CGROUP_WEIGHT_DEFAULT UINT64_C(100) + +#define CGROUP_LIMIT_MIN UINT64_C(0) +#define CGROUP_LIMIT_MAX ((uint64_t) -1) + +static inline bool CGROUP_WEIGHT_IS_OK(uint64_t x) { +        return +            x == CGROUP_WEIGHT_INVALID || +            (x >= CGROUP_WEIGHT_MIN && x <= CGROUP_WEIGHT_MAX); +} + +/* IO limits on unified hierarchy */ +typedef enum CGroupIOLimitType { +        CGROUP_IO_RBPS_MAX, +        CGROUP_IO_WBPS_MAX, +        CGROUP_IO_RIOPS_MAX, +        CGROUP_IO_WIOPS_MAX, + +        _CGROUP_IO_LIMIT_TYPE_MAX, +        _CGROUP_IO_LIMIT_TYPE_INVALID = -1 +} CGroupIOLimitType; + +extern const uint64_t cgroup_io_limit_defaults[_CGROUP_IO_LIMIT_TYPE_MAX]; + +const char* cgroup_io_limit_type_to_string(CGroupIOLimitType t) _const_; +CGroupIOLimitType cgroup_io_limit_type_from_string(const char *s) _pure_; + +/* Special values for the cpu.shares attribute */ +#define CGROUP_CPU_SHARES_INVALID ((uint64_t) -1) +#define CGROUP_CPU_SHARES_MIN UINT64_C(2) +#define CGROUP_CPU_SHARES_MAX UINT64_C(262144) +#define CGROUP_CPU_SHARES_DEFAULT UINT64_C(1024) + +static inline bool CGROUP_CPU_SHARES_IS_OK(uint64_t x) { +        return +            x == CGROUP_CPU_SHARES_INVALID || +            (x >= CGROUP_CPU_SHARES_MIN && x <= CGROUP_CPU_SHARES_MAX); +} + +/* Special values for the blkio.weight attribute */ +#define CGROUP_BLKIO_WEIGHT_INVALID ((uint64_t) -1) +#define CGROUP_BLKIO_WEIGHT_MIN UINT64_C(10) +#define CGROUP_BLKIO_WEIGHT_MAX UINT64_C(1000) +#define CGROUP_BLKIO_WEIGHT_DEFAULT UINT64_C(500) + +static inline bool CGROUP_BLKIO_WEIGHT_IS_OK(uint64_t x) { +        return +            x == CGROUP_BLKIO_WEIGHT_INVALID || +            (x >= CGROUP_BLKIO_WEIGHT_MIN && x <= CGROUP_BLKIO_WEIGHT_MAX); +} + +/* Default resource limits */ +#define DEFAULT_TASKS_MAX_PERCENTAGE            15U /* 15% of PIDs, 4915 on default settings */ +#define DEFAULT_USER_TASKS_MAX_PERCENTAGE       33U /* 33% of PIDs, 10813 on default settings */ + +typedef enum CGroupUnified { +        CGROUP_UNIFIED_UNKNOWN = -1, +        CGROUP_UNIFIED_NONE = 0,        /* Both systemd and controllers on legacy */ +        CGROUP_UNIFIED_SYSTEMD = 1,     /* Only systemd on unified */ +        CGROUP_UNIFIED_ALL = 2,         /* Both systemd and controllers on unified */ +} CGroupUnified; + +/* + * General rules: + * + * We accept named hierarchies in the syntax "foo" and "name=foo". + * + * We expect that named hierarchies do not conflict in name with a + * kernel hierarchy, modulo the "name=" prefix. + * + * We always generate "normalized" controller names, i.e. without the + * "name=" prefix. + * + * We require absolute cgroup paths. When returning, we will always + * generate paths with multiple adjacent / removed. + */ + +int cg_enumerate_processes(const char *controller, const char *path, FILE **_f); +int cg_read_pid(FILE *f, pid_t *_pid); +int cg_read_event(const char *controller, const char *path, const char *event, +                  char **val); + +int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d); +int cg_read_subgroup(DIR *d, char **fn); + +typedef enum CGroupFlags { +        CGROUP_SIGCONT     = 1, +        CGROUP_IGNORE_SELF = 2, +        CGROUP_REMOVE      = 4, +} CGroupFlags; + +typedef void (*cg_kill_log_func_t)(pid_t pid, int sig, void *userdata); + +int cg_kill(const char *controller, const char *path, int sig, CGroupFlags flags, Set *s, cg_kill_log_func_t kill_log, void *userdata); +int cg_kill_recursive(const char *controller, const char *path, int sig, CGroupFlags flags, Set *s, cg_kill_log_func_t kill_log, void *userdata); + +int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char *pto, CGroupFlags flags); +int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto, const char *pto, CGroupFlags flags); +int cg_migrate_recursive_fallback(const char *cfrom, const char *pfrom, const char *cto, const char *pto, CGroupFlags flags); + +int cg_split_spec(const char *spec, char **controller, char **path); +int cg_mangle_path(const char *path, char **result); + +int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs); +int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs); + +int cg_pid_get_path(const char *controller, pid_t pid, char **path); + +int cg_trim(const char *controller, const char *path, bool delete_root); + +int cg_rmdir(const char *controller, const char *path); + +int cg_create(const char *controller, const char *path); +int cg_attach(const char *controller, const char *path, pid_t pid); +int cg_attach_fallback(const char *controller, const char *path, pid_t pid); +int cg_create_and_attach(const char *controller, const char *path, pid_t pid); + +int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value); +int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret); +int cg_get_keyed_attribute(const char *controller, const char *path, const char *attribute, const char **keys, char **values); + +int cg_set_group_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid); +int cg_set_task_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid); + +int cg_set_xattr(const char *controller, const char *path, const char *name, const void *value, size_t size, int flags); +int cg_get_xattr(const char *controller, const char *path, const char *name, void *value, size_t size); + +int cg_install_release_agent(const char *controller, const char *agent); +int cg_uninstall_release_agent(const char *controller); + +int cg_is_empty(const char *controller, const char *path); +int cg_is_empty_recursive(const char *controller, const char *path); + +int cg_get_root_path(char **path); + +int cg_path_get_session(const char *path, char **session); +int cg_path_get_owner_uid(const char *path, uid_t *uid); +int cg_path_get_unit(const char *path, char **unit); +int cg_path_get_user_unit(const char *path, char **unit); +int cg_path_get_machine_name(const char *path, char **machine); +int cg_path_get_slice(const char *path, char **slice); +int cg_path_get_user_slice(const char *path, char **slice); + +int cg_shift_path(const char *cgroup, const char *cached_root, const char **shifted); +int cg_pid_get_path_shifted(pid_t pid, const char *cached_root, char **cgroup); + +int cg_pid_get_session(pid_t pid, char **session); +int cg_pid_get_owner_uid(pid_t pid, uid_t *uid); +int cg_pid_get_unit(pid_t pid, char **unit); +int cg_pid_get_user_unit(pid_t pid, char **unit); +int cg_pid_get_machine_name(pid_t pid, char **machine); +int cg_pid_get_slice(pid_t pid, char **slice); +int cg_pid_get_user_slice(pid_t pid, char **slice); + +int cg_path_decode_unit(const char *cgroup, char **unit); + +char *cg_escape(const char *p); +char *cg_unescape(const char *p) _pure_; + +bool cg_controller_is_valid(const char *p); + +int cg_slice_to_path(const char *unit, char **ret); + +typedef const char* (*cg_migrate_callback_t)(CGroupMask mask, void *userdata); + +int cg_create_everywhere(CGroupMask supported, CGroupMask mask, const char *path); +int cg_attach_everywhere(CGroupMask supported, const char *path, pid_t pid, cg_migrate_callback_t callback, void *userdata); +int cg_attach_many_everywhere(CGroupMask supported, const char *path, Set* pids, cg_migrate_callback_t callback, void *userdata); +int cg_migrate_everywhere(CGroupMask supported, const char *from, const char *to, cg_migrate_callback_t callback, void *userdata); +int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root); +int cg_enable_everywhere(CGroupMask supported, CGroupMask mask, const char *p); + +int cg_mask_supported(CGroupMask *ret); + +int cg_kernel_controllers(Set *controllers); + +bool cg_ns_supported(void); + +int cg_all_unified(void); +int cg_unified(const char *controller); +void cg_unified_flush(void); + +bool cg_is_unified_wanted(void); +bool cg_is_legacy_wanted(void); +bool cg_is_unified_systemd_controller_wanted(void); +bool cg_is_legacy_systemd_controller_wanted(void); + +const char* cgroup_controller_to_string(CGroupController c) _const_; +CGroupController cgroup_controller_from_string(const char *s) _pure_; + +int cg_weight_parse(const char *s, uint64_t *ret); +int cg_cpu_shares_parse(const char *s, uint64_t *ret); +int cg_blkio_weight_parse(const char *s, uint64_t *ret); + +bool is_cgroup_fs(const struct statfs *s); +bool fd_is_cgroup_fs(int fd); diff --git a/src/libsystemd-basic/include/systemd-basic/chattr-util.h b/src/libsystemd-basic/include/systemd-basic/chattr-util.h new file mode 100644 index 0000000000..960cf6d5b3 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/chattr-util.h @@ -0,0 +1,26 @@ +#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/>. +***/ + +int chattr_fd(int fd, unsigned value, unsigned mask); +int chattr_path(const char *p, unsigned value, unsigned mask); + +int read_attr_fd(int fd, unsigned *ret); +int read_attr_path(const char *p, unsigned *ret); diff --git a/src/libsystemd-basic/include/systemd-basic/clock-util.h b/src/libsystemd-basic/include/systemd-basic/clock-util.h new file mode 100644 index 0000000000..8830cd2f38 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/clock-util.h @@ -0,0 +1,29 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2010-2012 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 <time.h> + +int clock_is_localtime(const char* adjtime_path); +int clock_set_timezone(int *min); +int clock_reset_timewarp(void); +int clock_get_hwclock(struct tm *tm); +int clock_set_hwclock(const struct tm *tm); +int clock_apply_epoch(void); diff --git a/src/libsystemd-basic/include/systemd-basic/conf-files.h b/src/libsystemd-basic/include/systemd-basic/conf-files.h new file mode 100644 index 0000000000..e00e0e81fb --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/conf-files.h @@ -0,0 +1,25 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2010-2012 Lennart Poettering +  Copyright 2010-2012 Kay Sievers + +  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/>. +***/ + +int conf_files_list(char ***ret, const char *suffix, const char *root, const char *dir, ...); +int conf_files_list_strv(char ***ret, const char *suffix, const char *root, const char* const* dirs); +int conf_files_list_nulstr(char ***ret, const char *suffix, const char *root, const char *dirs); diff --git a/src/libsystemd-basic/include/systemd-basic/copy.h b/src/libsystemd-basic/include/systemd-basic/copy.h new file mode 100644 index 0000000000..b5d08ebafe --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/copy.h @@ -0,0 +1,36 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2014 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 <inttypes.h> +#include <stdbool.h> +#include <stdint.h> +#include <sys/types.h> + +int copy_file_fd(const char *from, int to, bool try_reflink); +int copy_file(const char *from, const char *to, int flags, mode_t mode, unsigned chattr_flags); +int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace, unsigned chattr_flags); +int copy_tree(const char *from, const char *to, bool merge); +int copy_tree_at(int fdf, const char *from, int fdt, const char *to, bool merge); +int copy_directory_fd(int dirfd, const char *to, bool merge); +int copy_directory(const char *from, const char *to, bool merge); +int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink); +int copy_times(int fdf, int fdt); +int copy_xattr(int fdf, int fdt); diff --git a/src/libsystemd-basic/include/systemd-basic/cpu-set-util.h b/src/libsystemd-basic/include/systemd-basic/cpu-set-util.h new file mode 100644 index 0000000000..6f49d9afb0 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/cpu-set-util.h @@ -0,0 +1,32 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2010-2015 Lennart Poettering +  Copyright 2015 Filipe Brandenburger + +  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 <sched.h> + +#include "macro.h" + +DEFINE_TRIVIAL_CLEANUP_FUNC(cpu_set_t*, CPU_FREE); +#define _cleanup_cpu_free_ _cleanup_(CPU_FREEp) + +cpu_set_t* cpu_set_malloc(unsigned *ncpus); + +int parse_cpu_set_and_warn(const char *rvalue, cpu_set_t **cpu_set, const char *unit, const char *filename, unsigned line, const char *lvalue); diff --git a/src/libsystemd-basic/include/systemd-basic/def.h b/src/libsystemd-basic/include/systemd-basic/def.h new file mode 100644 index 0000000000..2266eff650 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/def.h @@ -0,0 +1,90 @@ +#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 "util.h" + +#define DEFAULT_TIMEOUT_USEC (90*USEC_PER_SEC) +#define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC) +#define DEFAULT_CONFIRM_USEC (30*USEC_PER_SEC) + +#define DEFAULT_START_LIMIT_INTERVAL (10*USEC_PER_SEC) +#define DEFAULT_START_LIMIT_BURST 5 + +/* The default time after which exit-on-idle services exit. This + * should be kept lower than the watchdog timeout, because otherwise + * the watchdog pings will keep the loop busy. */ +#define DEFAULT_EXIT_USEC (30*USEC_PER_SEC) + +/* The default value for the net.unix.max_dgram_qlen sysctl */ +#define DEFAULT_UNIX_MAX_DGRAM_QLEN 512UL + +#define SYSTEMD_CGROUP_CONTROLLER "name=systemd" + +#define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT +#define SIGNALS_IGNORE SIGPIPE + +#ifdef HAVE_SPLIT_USR +#define KBD_KEYMAP_DIRS                         \ +        "/usr/share/keymaps/\0"                 \ +        "/usr/share/kbd/keymaps/\0"             \ +        "/usr/lib/kbd/keymaps/\0"               \ +        "/lib/kbd/keymaps/\0" +#else +#define KBD_KEYMAP_DIRS                         \ +        "/usr/share/keymaps/\0"                 \ +        "/usr/share/kbd/keymaps/\0"             \ +        "/usr/lib/kbd/keymaps/\0" +#endif + +#define UNIX_SYSTEM_BUS_ADDRESS "unix:path=/var/run/dbus/system_bus_socket" +#define KERNEL_SYSTEM_BUS_ADDRESS "kernel:path=/sys/fs/kdbus/0-system/bus" +#define DEFAULT_SYSTEM_BUS_ADDRESS KERNEL_SYSTEM_BUS_ADDRESS ";" UNIX_SYSTEM_BUS_ADDRESS +#define UNIX_USER_BUS_ADDRESS_FMT "unix:path=%s/bus" +#define KERNEL_USER_BUS_ADDRESS_FMT "kernel:path=/sys/fs/kdbus/"UID_FMT"-user/bus" + +#define PLYMOUTH_SOCKET {                                       \ +                .un.sun_family = AF_UNIX,                       \ +                .un.sun_path = "\0/org/freedesktop/plymouthd",  \ +        } + +#ifndef TTY_GID +#define TTY_GID 5 +#endif + +#define NOTIFY_FD_MAX 768 +#define NOTIFY_BUFFER_MAX PIPE_BUF + +#ifdef HAVE_SPLIT_USR +#define _CONF_PATHS_SPLIT_USR(n) "/lib/" n "\0" +#else +#define _CONF_PATHS_SPLIT_USR(n) +#endif + +/* Return a nulstr for a standard cascade of configuration paths, + * suitable to pass to conf_files_list_nulstr() or config_parse_many_nulstr() + * to implement drop-in directories for extending configuration + * files. */ +#define CONF_PATHS_NULSTR(n) \ +        "/etc/" n "\0" \ +        "/run/" n "\0" \ +        "/usr/local/lib/" n "\0" \ +        "/usr/lib/" n "\0" \ +        _CONF_PATHS_SPLIT_USR(n) diff --git a/src/libsystemd-basic/include/systemd-basic/device-nodes.h b/src/libsystemd-basic/include/systemd-basic/device-nodes.h new file mode 100644 index 0000000000..94f385abcb --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/device-nodes.h @@ -0,0 +1,26 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2012 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 <stddef.h> +#include <sys/types.h> + +int encode_devnode_name(const char *str, char *str_enc, size_t len); +int whitelisted_char_for_devnode(char c, const char *additional); diff --git a/src/libsystemd-basic/include/systemd-basic/dirent-util.h b/src/libsystemd-basic/include/systemd-basic/dirent-util.h new file mode 100644 index 0000000000..b91d04908f --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/dirent-util.h @@ -0,0 +1,52 @@ +#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 <dirent.h> +#include <errno.h> +#include <stdbool.h> + +#include "macro.h" +#include "path-util.h" + +int dirent_ensure_type(DIR *d, struct dirent *de); + +bool dirent_is_file(const struct dirent *de) _pure_; +bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_; + +#define FOREACH_DIRENT(de, d, on_error)                                 \ +        for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d))   \ +                if (!de) {                                              \ +                        if (errno > 0) {                                \ +                                on_error;                               \ +                        }                                               \ +                        break;                                          \ +                } else if (hidden_or_backup_file((de)->d_name))         \ +                        continue;                                       \ +                else + +#define FOREACH_DIRENT_ALL(de, d, on_error)                             \ +        for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d))   \ +                if (!de) {                                              \ +                        if (errno > 0) {                                \ +                                on_error;                               \ +                        }                                               \ +                        break;                                          \ +                } else diff --git a/src/libsystemd-basic/include/systemd-basic/env-util.h b/src/libsystemd-basic/include/systemd-basic/env-util.h new file mode 100644 index 0000000000..b1fef704c2 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/env-util.h @@ -0,0 +1,51 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2013 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 <stddef.h> + +#include "macro.h" + +bool env_name_is_valid(const char *e); +bool env_value_is_valid(const char *e); +bool env_assignment_is_valid(const char *e); + +char *replace_env(const char *format, char **env); +char **replace_env_argv(char **argv, char **env); + +bool strv_env_is_valid(char **e); +#define strv_env_clean(l) strv_env_clean_with_callback(l, NULL, NULL) +char **strv_env_clean_with_callback(char **l, void (*invalid_callback)(const char *p, void *userdata), void *userdata); + +bool strv_env_name_is_valid(char **l); +bool strv_env_name_or_assignment_is_valid(char **l); + +char **strv_env_merge(unsigned n_lists, ...); +char **strv_env_delete(char **x, unsigned n_lists, ...); /* New copy */ + +char **strv_env_set(char **x, const char *p); /* New copy ... */ +char **strv_env_unset(char **l, const char *p); /* In place ... */ +char **strv_env_unset_many(char **l, ...) _sentinel_; + +char *strv_env_get_n(char **l, const char *name, size_t k) _pure_; +char *strv_env_get(char **x, const char *n) _pure_; + +int getenv_bool(const char *p); diff --git a/src/libsystemd-basic/include/systemd-basic/errno-list.h b/src/libsystemd-basic/include/systemd-basic/errno-list.h new file mode 100644 index 0000000000..4eec0cc786 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/errno-list.h @@ -0,0 +1,25 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2013 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/>. +***/ + +const char *errno_to_name(int id); +int errno_from_name(const char *name); + +int errno_max(void); diff --git a/src/libsystemd-basic/include/systemd-basic/escape.h b/src/libsystemd-basic/include/systemd-basic/escape.h new file mode 100644 index 0000000000..6e58f61e19 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/escape.h @@ -0,0 +1,54 @@ +#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 <inttypes.h> +#include <stddef.h> +#include <stdint.h> +#include <sys/types.h> +#include <uchar.h> + +#include "missing.h" +#include "string-util.h" + +/* What characters are special in the shell? */ +/* must be escaped outside and inside double-quotes */ +#define SHELL_NEED_ESCAPE "\"\\`$" +/* can be escaped or double-quoted */ +#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;" + +typedef enum UnescapeFlags { +        UNESCAPE_RELAX = 1, +} UnescapeFlags; + +char *cescape(const char *s); +char *cescape_length(const char *s, size_t n); +size_t cescape_char(char c, char *buf); + +int cunescape(const char *s, UnescapeFlags flags, char **ret); +int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret); +int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret); +int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit); + +char *xescape(const char *s, const char *bad); +char *octescape(const char *s, size_t len); + +char *shell_escape(const char *s, const char *bad); +char *shell_maybe_quote(const char *s); diff --git a/src/libsystemd-basic/include/systemd-basic/ether-addr-util.h b/src/libsystemd-basic/include/systemd-basic/ether-addr-util.h new file mode 100644 index 0000000000..74e125a95f --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/ether-addr-util.h @@ -0,0 +1,39 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2014 Tom Gundersen + +  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 <net/ethernet.h> +#include <stdbool.h> + +#define ETHER_ADDR_FORMAT_STR "%02X%02X%02X%02X%02X%02X" +#define ETHER_ADDR_FORMAT_VAL(x) (x).ether_addr_octet[0], (x).ether_addr_octet[1], (x).ether_addr_octet[2], (x).ether_addr_octet[3], (x).ether_addr_octet[4], (x).ether_addr_octet[5] + +#define ETHER_ADDR_TO_STRING_MAX (3*6) +char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]); + +bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b); + +#define ETHER_ADDR_NULL ((const struct ether_addr){}) + +static inline bool ether_addr_is_null(const struct ether_addr *addr) { +        return ether_addr_equal(addr, ÐER_ADDR_NULL); +} + +int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset); diff --git a/src/libsystemd-basic/include/systemd-basic/exit-status.h b/src/libsystemd-basic/include/systemd-basic/exit-status.h new file mode 100644 index 0000000000..0cfdfd7891 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/exit-status.h @@ -0,0 +1,110 @@ +#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 "hashmap.h" +#include "macro.h" +#include "set.h" + +/* This defines pretty names for the LSB 'start' verb exit codes. Note that they shouldn't be confused with the LSB + * 'status' verb exit codes which are defined very differently. For details see: + * + * https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html + */ + +enum { +        /* EXIT_SUCCESS defined by libc */ +        /* EXIT_FAILURE defined by libc */ +        EXIT_INVALIDARGUMENT = 2, +        EXIT_NOTIMPLEMENTED = 3, +        EXIT_NOPERMISSION = 4, +        EXIT_NOTINSTALLED = 5, +        EXIT_NOTCONFIGURED = 6, +        EXIT_NOTRUNNING = 7, + +        /* The LSB suggests that error codes >= 200 are "reserved". We +         * use them here under the assumption that they hence are +         * unused by init scripts. */ + +        EXIT_CHDIR = 200, +        EXIT_NICE, +        EXIT_FDS, +        EXIT_EXEC, +        EXIT_MEMORY, +        EXIT_LIMITS, +        EXIT_OOM_ADJUST, +        EXIT_SIGNAL_MASK, +        EXIT_STDIN, +        EXIT_STDOUT, +        EXIT_CHROOT,   /* 210 */ +        EXIT_IOPRIO, +        EXIT_TIMERSLACK, +        EXIT_SECUREBITS, +        EXIT_SETSCHEDULER, +        EXIT_CPUAFFINITY, +        EXIT_GROUP, +        EXIT_USER, +        EXIT_CAPABILITIES, +        EXIT_CGROUP, +        EXIT_SETSID,   /* 220 */ +        EXIT_CONFIRM, +        EXIT_STDERR, +        _EXIT_RESERVED, /* used to be tcpwrap, don't reuse! */ +        EXIT_PAM, +        EXIT_NETWORK, +        EXIT_NAMESPACE, +        EXIT_NO_NEW_PRIVILEGES, +        EXIT_SECCOMP, +        EXIT_SELINUX_CONTEXT, +        EXIT_PERSONALITY,  /* 230 */ +        EXIT_APPARMOR_PROFILE, +        EXIT_ADDRESS_FAMILIES, +        EXIT_RUNTIME_DIRECTORY, +        EXIT_MAKE_STARTER, +        EXIT_CHOWN, +        EXIT_SMACK_PROCESS_LABEL, +}; + +typedef enum ExitStatusLevel { +        EXIT_STATUS_MINIMAL,   /* only cover libc EXIT_STATUS/EXIT_FAILURE */ +        EXIT_STATUS_SYSTEMD,   /* cover libc and systemd's own exit codes */ +        EXIT_STATUS_LSB,       /* cover libc, systemd's own and LSB exit codes */ +        EXIT_STATUS_FULL = EXIT_STATUS_LSB +} ExitStatusLevel; + +typedef struct ExitStatusSet { +        Set *status; +        Set *signal; +} ExitStatusSet; + +const char* exit_status_to_string(int status, ExitStatusLevel level) _const_; + +typedef enum ExitClean { +        EXIT_CLEAN_DAEMON, +        EXIT_CLEAN_COMMAND, +} ExitClean; + +bool is_clean_exit(int code, int status, ExitClean clean, ExitStatusSet *success_status); + +void exit_status_set_free(ExitStatusSet *x); +bool exit_status_set_is_empty(ExitStatusSet *x); +bool exit_status_set_test(ExitStatusSet *x, int code, int status); diff --git a/src/libsystemd-basic/include/systemd-basic/extract-word.h b/src/libsystemd-basic/include/systemd-basic/extract-word.h new file mode 100644 index 0000000000..21db5ef33f --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/extract-word.h @@ -0,0 +1,35 @@ +#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 "macro.h" + +typedef enum ExtractFlags { +        EXTRACT_RELAX                    = 1, +        EXTRACT_CUNESCAPE                = 2, +        EXTRACT_CUNESCAPE_RELAX          = 4, +        EXTRACT_QUOTES                   = 8, +        EXTRACT_DONT_COALESCE_SEPARATORS = 16, +        EXTRACT_RETAIN_ESCAPE            = 32, +} ExtractFlags; + +int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags); +int extract_first_word_and_warn(const char **p, char **ret, const char *separators, ExtractFlags flags, const char *unit, const char *filename, unsigned line, const char *rvalue); +int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) _sentinel_; diff --git a/src/libsystemd-basic/include/systemd-basic/fd-util.h b/src/libsystemd-basic/include/systemd-basic/fd-util.h new file mode 100644 index 0000000000..34b98d4aec --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/fd-util.h @@ -0,0 +1,80 @@ +#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 <dirent.h> +#include <stdbool.h> +#include <stdio.h> +#include <sys/socket.h> + +#include "macro.h" + +/* Make sure we can distinguish fd 0 and NULL */ +#define FD_TO_PTR(fd) INT_TO_PTR((fd)+1) +#define PTR_TO_FD(p) (PTR_TO_INT(p)-1) + +int close_nointr(int fd); +int safe_close(int fd); +void safe_close_pair(int p[]); + +void close_many(const int fds[], unsigned n_fd); + +int fclose_nointr(FILE *f); +FILE* safe_fclose(FILE *f); +DIR* safe_closedir(DIR *f); + +static inline void closep(int *fd) { +        safe_close(*fd); +} + +static inline void close_pairp(int (*p)[2]) { +        safe_close_pair(*p); +} + +static inline void fclosep(FILE **f) { +        safe_fclose(*f); +} + +DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, pclose); +DEFINE_TRIVIAL_CLEANUP_FUNC(DIR*, closedir); + +#define _cleanup_close_ _cleanup_(closep) +#define _cleanup_fclose_ _cleanup_(fclosep) +#define _cleanup_pclose_ _cleanup_(pclosep) +#define _cleanup_closedir_ _cleanup_(closedirp) +#define _cleanup_close_pair_ _cleanup_(close_pairp) + +int fd_nonblock(int fd, bool nonblock); +int fd_cloexec(int fd, bool cloexec); +void stdio_unset_cloexec(void); + +int close_all_fds(const int except[], unsigned n_except); + +int same_fd(int a, int b); + +void cmsg_close_all(struct msghdr *mh); + +bool fdname_is_valid(const char *s); + +int fd_get_path(int fd, char **ret); + +/* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */ +#define ERRNO_IS_DISCONNECT(r) \ +        IN_SET(r, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, ENETUNREACH) diff --git a/src/libsystemd-basic/include/systemd-basic/fileio-label.h b/src/libsystemd-basic/include/systemd-basic/fileio-label.h new file mode 100644 index 0000000000..fe7543013d --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/fileio-label.h @@ -0,0 +1,30 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2010 Lennart Poettering +  Copyright 2010 Harald Hoyer + +  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 <stdio.h> + +#include "fileio.h" + +int write_string_file_atomic_label(const char *fn, const char *line); +int write_env_file_label(const char *fname, char **l); +int fopen_temporary_label(const char *target, +                          const char *path, FILE **f, char **temp_path); diff --git a/src/libsystemd-basic/include/systemd-basic/fileio.h b/src/libsystemd-basic/include/systemd-basic/fileio.h new file mode 100644 index 0000000000..b58c83e64a --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/fileio.h @@ -0,0 +1,90 @@ +#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 <dirent.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdio.h> +#include <sys/types.h> + +#include "macro.h" +#include "time-util.h" + +typedef enum { +        WRITE_STRING_FILE_CREATE = 1, +        WRITE_STRING_FILE_ATOMIC = 2, +        WRITE_STRING_FILE_AVOID_NEWLINE = 4, +        WRITE_STRING_FILE_VERIFY_ON_FAILURE = 8, +} WriteStringFileFlags; + +int write_string_stream(FILE *f, const char *line, bool enforce_newline); +int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags); + +int read_one_line_file(const char *fn, char **line); +int read_full_file(const char *fn, char **contents, size_t *size); +int read_full_stream(FILE *f, char **contents, size_t *size); + +int verify_file(const char *fn, const char *blob, bool accept_extra_nl); + +int parse_env_file(const char *fname, const char *separator, ...) _sentinel_; +int load_env_file(FILE *f, const char *fname, const char *separator, char ***l); +int load_env_file_pairs(FILE *f, const char *fname, const char *separator, char ***l); + +int write_env_file(const char *fname, char **l); + +int executable_is_script(const char *path, char **interpreter); + +int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field); + +DIR *xopendirat(int dirfd, const char *name, int flags); + +int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f); +int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f); + +#define FOREACH_LINE(line, f, on_error)                         \ +        for (;;)                                                \ +                if (!fgets(line, sizeof(line), f)) {            \ +                        if (ferror(f)) {                        \ +                                on_error;                       \ +                        }                                       \ +                        break;                                  \ +                } else + +int fflush_and_check(FILE *f); + +int fopen_temporary(const char *path, FILE **_f, char **_temp_path); +int mkostemp_safe(char *pattern); + +int tempfn_xxxxxx(const char *p, const char *extra, char **ret); +int tempfn_random(const char *p, const char *extra, char **ret); +int tempfn_random_child(const char *p, const char *extra, char **ret); + +int write_timestamp_file_atomic(const char *fn, usec_t n); +int read_timestamp_file(const char *fn, usec_t *ret); + +int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space); + +int open_tmpfile_unlinkable(const char *directory, int flags); +int open_tmpfile_linkable(const char *target, int flags, char **ret_path); + +int link_tmpfile(int fd, const char *path, const char *target); + +int read_nul_string(FILE *f, char **ret); diff --git a/src/libsystemd-basic/include/systemd-basic/formats-util.h b/src/libsystemd-basic/include/systemd-basic/formats-util.h new file mode 100644 index 0000000000..39a185f59b --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/formats-util.h @@ -0,0 +1,79 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2015 Ronny Chevalier + +  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 <inttypes.h> + +#if SIZEOF_PID_T == 4 +#  define PID_PRI PRIi32 +#elif SIZEOF_PID_T == 2 +#  define PID_PRI PRIi16 +#else +#  error Unknown pid_t size +#endif +#define PID_FMT "%" PID_PRI + +#if SIZEOF_UID_T == 4 +#  define UID_FMT "%" PRIu32 +#elif SIZEOF_UID_T == 2 +#  define UID_FMT "%" PRIu16 +#else +#  error Unknown uid_t size +#endif + +#if SIZEOF_GID_T == 4 +#  define GID_FMT "%" PRIu32 +#elif SIZEOF_GID_T == 2 +#  define GID_FMT "%" PRIu16 +#else +#  error Unknown gid_t size +#endif + +#if SIZEOF_TIME_T == 8 +#  define PRI_TIME PRIi64 +#elif SIZEOF_TIME_T == 4 +#  define PRI_TIME "li" +#else +#  error Unknown time_t size +#endif + +#if SIZEOF_RLIM_T == 8 +#  define RLIM_FMT "%" PRIu64 +#elif SIZEOF_RLIM_T == 4 +#  define RLIM_FMT "%" PRIu32 +#else +#  error Unknown rlim_t size +#endif + +#if SIZEOF_DEV_T == 8 +#  define DEV_FMT "%" PRIu64 +#elif SIZEOF_DEV_T == 4 +#  define DEV_FMT "%" PRIu32 +#else +#  error Unknown dev_t size +#endif + +#if SIZEOF_INO_T == 8 +#  define INO_FMT "%" PRIu64 +#elif SIZEOF_INO_T == 4 +#  define INO_FMT "%" PRIu32 +#else +#  error Unknown ino_t size +#endif diff --git a/src/libsystemd-basic/include/systemd-basic/fs-util.h b/src/libsystemd-basic/include/systemd-basic/fs-util.h new file mode 100644 index 0000000000..31df47cf1e --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/fs-util.h @@ -0,0 +1,81 @@ +#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 <fcntl.h> +#include <limits.h> +#include <stdbool.h> +#include <stdint.h> +#include <sys/inotify.h> +#include <sys/types.h> +#include <unistd.h> + +#include "time-util.h" + +int unlink_noerrno(const char *path); + +int rmdir_parents(const char *path, const char *stop); + +int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath); + +int readlinkat_malloc(int fd, const char *p, char **ret); +int readlink_malloc(const char *p, char **r); +int readlink_value(const char *p, char **ret); +int readlink_and_make_absolute(const char *p, char **r); +int readlink_and_canonicalize(const char *p, char **r); +int readlink_and_make_absolute_root(const char *root, const char *path, char **ret); + +int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid); + +int fchmod_umask(int fd, mode_t mode); + +int fd_warn_permissions(const char *path, int fd); + +#define laccess(path, mode) faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW) + +int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode); +int touch(const char *path); + +int symlink_idempotent(const char *from, const char *to); + +int symlink_atomic(const char *from, const char *to); +int mknod_atomic(const char *path, mode_t mode, dev_t dev); +int mkfifo_atomic(const char *path, mode_t mode); + +int get_files_in_directory(const char *path, char ***list); + +int tmp_dir(const char **ret); +int var_tmp_dir(const char **ret); + +#define INOTIFY_EVENT_MAX (sizeof(struct inotify_event) + NAME_MAX + 1) + +#define FOREACH_INOTIFY_EVENT(e, buffer, sz) \ +        for ((e) = &buffer.ev;                                \ +             (uint8_t*) (e) < (uint8_t*) (buffer.raw) + (sz); \ +             (e) = (struct inotify_event*) ((uint8_t*) (e) + sizeof(struct inotify_event) + (e)->len)) + +union inotify_event_buffer { +        struct inotify_event ev; +        uint8_t raw[INOTIFY_EVENT_MAX]; +}; + +int inotify_add_watch_fd(int fd, int what, uint32_t mask); + +int chase_symlinks(const char *path, const char *_root, char **ret); diff --git a/src/libsystemd-basic/include/systemd-basic/glob-util.h b/src/libsystemd-basic/include/systemd-basic/glob-util.h new file mode 100644 index 0000000000..5d8fb47a26 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/glob-util.h @@ -0,0 +1,36 @@ +#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 <string.h> + +#include "macro.h" +#include "string-util.h" + +int glob_exists(const char *path); +int glob_extend(char ***strv, const char *path); + +#define _cleanup_globfree_ _cleanup_(globfree) + +_pure_ static inline bool string_is_glob(const char *p) { +        /* Check if a string contains any glob patterns. */ +        return !!strpbrk(p, GLOB_CHARS); +} diff --git a/src/libsystemd-basic/include/systemd-basic/gunicode.h b/src/libsystemd-basic/include/systemd-basic/gunicode.h new file mode 100644 index 0000000000..5975bc8fc9 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/gunicode.h @@ -0,0 +1,30 @@ +#pragma once + +/* gunicode.h - Unicode manipulation functions + * + *  Copyright (C) 1999, 2000 Tom Tromey + *  Copyright 2000, 2005 Red Hat, Inc. + */ + +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> + +char *utf8_prev_char (const char *p); + +extern const char utf8_skip_data[256]; + +/** + * g_utf8_next_char: + * @p: Pointer to the start of a valid UTF-8 character + * + * Skips to the next character in a UTF-8 string. The string must be + * valid; this macro is as fast as possible, and has no error-checking. + * You would use this macro to iterate over a string character by + * character. The macro returns the start of the next UTF-8 character. + * Before using this macro, use g_utf8_validate() to validate strings + * that may contain invalid UTF-8. + */ +#define utf8_next_char(p) (char *)((p) + utf8_skip_data[*(const unsigned char *)(p)]) + +bool unichar_iswide (uint32_t c); diff --git a/src/libsystemd-basic/include/systemd-basic/hash-funcs.h b/src/libsystemd-basic/include/systemd-basic/hash-funcs.h new file mode 100644 index 0000000000..299189d143 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/hash-funcs.h @@ -0,0 +1,65 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2010 Lennart Poettering +  Copyright 2014 Michal Schmidt + +  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 "macro.h" +#include "siphash24.h" + +typedef void (*hash_func_t)(const void *p, struct siphash *state); +typedef int (*compare_func_t)(const void *a, const void *b); + +struct hash_ops { +        hash_func_t hash; +        compare_func_t compare; +}; + +void string_hash_func(const void *p, struct siphash *state); +int string_compare_func(const void *a, const void *b) _pure_; +extern const struct hash_ops string_hash_ops; + +/* This will compare the passed pointers directly, and will not + * dereference them. This is hence not useful for strings or + * suchlike. */ +void trivial_hash_func(const void *p, struct siphash *state); +int trivial_compare_func(const void *a, const void *b) _const_; +extern const struct hash_ops trivial_hash_ops; + +/* 32bit values we can always just embed in the pointer itself, but + * in order to support 32bit archs we need store 64bit values + * indirectly, since they don't fit in a pointer. */ +void uint64_hash_func(const void *p, struct siphash *state); +int uint64_compare_func(const void *a, const void *b) _pure_; +extern const struct hash_ops uint64_hash_ops; + +/* On some archs dev_t is 32bit, and on others 64bit. And sometimes + * it's 64bit on 32bit archs, and sometimes 32bit on 64bit archs. Yuck! */ +#if SIZEOF_DEV_T != 8 +void devt_hash_func(const void *p, struct siphash *state) _pure_; +int devt_compare_func(const void *a, const void *b) _pure_; +extern const struct hash_ops devt_hash_ops = { +        .hash = devt_hash_func, +        .compare = devt_compare_func +}; +#else +#define devt_hash_func uint64_hash_func +#define devt_compare_func uint64_compare_func +#define devt_hash_ops uint64_hash_ops +#endif diff --git a/src/libsystemd-basic/include/systemd-basic/hashmap.h b/src/libsystemd-basic/include/systemd-basic/hashmap.h new file mode 100644 index 0000000000..6d1ae48b21 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/hashmap.h @@ -0,0 +1,372 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2010 Lennart Poettering +  Copyright 2014 Michal Schmidt + +  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 <limits.h> +#include <stdbool.h> +#include <stddef.h> + +#include "hash-funcs.h" +#include "macro.h" +#include "util.h" + +/* + * A hash table implementation. As a minor optimization a NULL hashmap object + * will be treated as empty hashmap for all read operations. That way it is not + * necessary to instantiate an object for each Hashmap use. + * + * If ENABLE_DEBUG_HASHMAP is defined (by configuring with --enable-debug=hashmap), + * the implemention will: + * - store extra data for debugging and statistics (see tools/gdb-sd_dump_hashmaps.py) + * - perform extra checks for invalid use of iterators + */ + +#define HASH_KEY_SIZE 16 + +/* The base type for all hashmap and set types. Many functions in the + * implementation take (HashmapBase*) parameters and are run-time polymorphic, + * though the API is not meant to be polymorphic (do not call functions + * internal_*() directly). */ +typedef struct HashmapBase HashmapBase; + +/* Specific hashmap/set types */ +typedef struct Hashmap Hashmap;               /* Maps keys to values */ +typedef struct OrderedHashmap OrderedHashmap; /* Like Hashmap, but also remembers entry insertion order */ +typedef struct Set Set;                       /* Stores just keys */ + +/* Ideally the Iterator would be an opaque struct, but it is instantiated + * by hashmap users, so the definition has to be here. Do not use its fields + * directly. */ +typedef struct { +        unsigned idx;         /* index of an entry to be iterated next */ +        const void *next_key; /* expected value of that entry's key pointer */ +#ifdef ENABLE_DEBUG_HASHMAP +        unsigned put_count;   /* hashmap's put_count recorded at start of iteration */ +        unsigned rem_count;   /* hashmap's rem_count in previous iteration */ +        unsigned prev_idx;    /* idx in previous iteration */ +#endif +} Iterator; + +#define _IDX_ITERATOR_FIRST (UINT_MAX - 1) +#define ITERATOR_FIRST ((Iterator) { .idx = _IDX_ITERATOR_FIRST, .next_key = NULL }) + +/* Macros for type checking */ +#define PTR_COMPATIBLE_WITH_HASHMAP_BASE(h) \ +        (__builtin_types_compatible_p(typeof(h), HashmapBase*) || \ +         __builtin_types_compatible_p(typeof(h), Hashmap*) || \ +         __builtin_types_compatible_p(typeof(h), OrderedHashmap*) || \ +         __builtin_types_compatible_p(typeof(h), Set*)) + +#define PTR_COMPATIBLE_WITH_PLAIN_HASHMAP(h) \ +        (__builtin_types_compatible_p(typeof(h), Hashmap*) || \ +         __builtin_types_compatible_p(typeof(h), OrderedHashmap*)) \ + +#define HASHMAP_BASE(h) \ +        __builtin_choose_expr(PTR_COMPATIBLE_WITH_HASHMAP_BASE(h), \ +                (HashmapBase*)(h), \ +                (void)0) + +#define PLAIN_HASHMAP(h) \ +        __builtin_choose_expr(PTR_COMPATIBLE_WITH_PLAIN_HASHMAP(h), \ +                (Hashmap*)(h), \ +                (void)0) + +#ifdef ENABLE_DEBUG_HASHMAP +# define HASHMAP_DEBUG_PARAMS , const char *func, const char *file, int line +# define HASHMAP_DEBUG_SRC_ARGS   , __func__, __FILE__, __LINE__ +# define HASHMAP_DEBUG_PASS_ARGS   , func, file, line +#else +# define HASHMAP_DEBUG_PARAMS +# define HASHMAP_DEBUG_SRC_ARGS +# define HASHMAP_DEBUG_PASS_ARGS +#endif + +Hashmap *internal_hashmap_new(const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS); +OrderedHashmap *internal_ordered_hashmap_new(const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS); +#define hashmap_new(ops) internal_hashmap_new(ops  HASHMAP_DEBUG_SRC_ARGS) +#define ordered_hashmap_new(ops) internal_ordered_hashmap_new(ops  HASHMAP_DEBUG_SRC_ARGS) + +HashmapBase *internal_hashmap_free(HashmapBase *h); +static inline Hashmap *hashmap_free(Hashmap *h) { +        return (void*)internal_hashmap_free(HASHMAP_BASE(h)); +} +static inline OrderedHashmap *ordered_hashmap_free(OrderedHashmap *h) { +        return (void*)internal_hashmap_free(HASHMAP_BASE(h)); +} + +HashmapBase *internal_hashmap_free_free(HashmapBase *h); +static inline Hashmap *hashmap_free_free(Hashmap *h) { +        return (void*)internal_hashmap_free_free(HASHMAP_BASE(h)); +} +static inline OrderedHashmap *ordered_hashmap_free_free(OrderedHashmap *h) { +        return (void*)internal_hashmap_free_free(HASHMAP_BASE(h)); +} + +Hashmap *hashmap_free_free_free(Hashmap *h); +static inline OrderedHashmap *ordered_hashmap_free_free_free(OrderedHashmap *h) { +        return (void*)hashmap_free_free_free(PLAIN_HASHMAP(h)); +} + +HashmapBase *internal_hashmap_copy(HashmapBase *h); +static inline Hashmap *hashmap_copy(Hashmap *h) { +        return (Hashmap*) internal_hashmap_copy(HASHMAP_BASE(h)); +} +static inline OrderedHashmap *ordered_hashmap_copy(OrderedHashmap *h) { +        return (OrderedHashmap*) internal_hashmap_copy(HASHMAP_BASE(h)); +} + +int internal_hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS); +int internal_ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS); +#define hashmap_ensure_allocated(h, ops) internal_hashmap_ensure_allocated(h, ops  HASHMAP_DEBUG_SRC_ARGS) +#define ordered_hashmap_ensure_allocated(h, ops) internal_ordered_hashmap_ensure_allocated(h, ops  HASHMAP_DEBUG_SRC_ARGS) + +int hashmap_put(Hashmap *h, const void *key, void *value); +static inline int ordered_hashmap_put(OrderedHashmap *h, const void *key, void *value) { +        return hashmap_put(PLAIN_HASHMAP(h), key, value); +} + +int hashmap_update(Hashmap *h, const void *key, void *value); +static inline int ordered_hashmap_update(OrderedHashmap *h, const void *key, void *value) { +        return hashmap_update(PLAIN_HASHMAP(h), key, value); +} + +int hashmap_replace(Hashmap *h, const void *key, void *value); +static inline int ordered_hashmap_replace(OrderedHashmap *h, const void *key, void *value) { +        return hashmap_replace(PLAIN_HASHMAP(h), key, value); +} + +void *internal_hashmap_get(HashmapBase *h, const void *key); +static inline void *hashmap_get(Hashmap *h, const void *key) { +        return internal_hashmap_get(HASHMAP_BASE(h), key); +} +static inline void *ordered_hashmap_get(OrderedHashmap *h, const void *key) { +        return internal_hashmap_get(HASHMAP_BASE(h), key); +} + +void *hashmap_get2(Hashmap *h, const void *key, void **rkey); +static inline void *ordered_hashmap_get2(OrderedHashmap *h, const void *key, void **rkey) { +        return hashmap_get2(PLAIN_HASHMAP(h), key, rkey); +} + +bool internal_hashmap_contains(HashmapBase *h, const void *key); +static inline bool hashmap_contains(Hashmap *h, const void *key) { +        return internal_hashmap_contains(HASHMAP_BASE(h), key); +} +static inline bool ordered_hashmap_contains(OrderedHashmap *h, const void *key) { +        return internal_hashmap_contains(HASHMAP_BASE(h), key); +} + +void *internal_hashmap_remove(HashmapBase *h, const void *key); +static inline void *hashmap_remove(Hashmap *h, const void *key) { +        return internal_hashmap_remove(HASHMAP_BASE(h), key); +} +static inline void *ordered_hashmap_remove(OrderedHashmap *h, const void *key) { +        return internal_hashmap_remove(HASHMAP_BASE(h), key); +} + +void *hashmap_remove2(Hashmap *h, const void *key, void **rkey); +static inline void *ordered_hashmap_remove2(OrderedHashmap *h, const void *key, void **rkey) { +        return hashmap_remove2(PLAIN_HASHMAP(h), key, rkey); +} + +void *hashmap_remove_value(Hashmap *h, const void *key, void *value); +static inline void *ordered_hashmap_remove_value(OrderedHashmap *h, const void *key, void *value) { +        return hashmap_remove_value(PLAIN_HASHMAP(h), key, value); +} + +int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value); +static inline int ordered_hashmap_remove_and_put(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) { +        return hashmap_remove_and_put(PLAIN_HASHMAP(h), old_key, new_key, value); +} + +int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value); +static inline int ordered_hashmap_remove_and_replace(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) { +        return hashmap_remove_and_replace(PLAIN_HASHMAP(h), old_key, new_key, value); +} + +/* Since merging data from a OrderedHashmap into a Hashmap or vice-versa + * should just work, allow this by having looser type-checking here. */ +int internal_hashmap_merge(Hashmap *h, Hashmap *other); +#define hashmap_merge(h, other) internal_hashmap_merge(PLAIN_HASHMAP(h), PLAIN_HASHMAP(other)) +#define ordered_hashmap_merge(h, other) hashmap_merge(h, other) + +int internal_hashmap_reserve(HashmapBase *h, unsigned entries_add); +static inline int hashmap_reserve(Hashmap *h, unsigned entries_add) { +        return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add); +} +static inline int ordered_hashmap_reserve(OrderedHashmap *h, unsigned entries_add) { +        return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add); +} + +int internal_hashmap_move(HashmapBase *h, HashmapBase *other); +/* Unlike hashmap_merge, hashmap_move does not allow mixing the types. */ +static inline int hashmap_move(Hashmap *h, Hashmap *other) { +        return internal_hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other)); +} +static inline int ordered_hashmap_move(OrderedHashmap *h, OrderedHashmap *other) { +        return internal_hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other)); +} + +int internal_hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key); +static inline int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key) { +        return internal_hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key); +} +static inline int ordered_hashmap_move_one(OrderedHashmap *h, OrderedHashmap *other, const void *key) { +        return internal_hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key); +} + +unsigned internal_hashmap_size(HashmapBase *h) _pure_; +static inline unsigned hashmap_size(Hashmap *h) { +        return internal_hashmap_size(HASHMAP_BASE(h)); +} +static inline unsigned ordered_hashmap_size(OrderedHashmap *h) { +        return internal_hashmap_size(HASHMAP_BASE(h)); +} + +static inline bool hashmap_isempty(Hashmap *h) { +        return hashmap_size(h) == 0; +} +static inline bool ordered_hashmap_isempty(OrderedHashmap *h) { +        return ordered_hashmap_size(h) == 0; +} + +unsigned internal_hashmap_buckets(HashmapBase *h) _pure_; +static inline unsigned hashmap_buckets(Hashmap *h) { +        return internal_hashmap_buckets(HASHMAP_BASE(h)); +} +static inline unsigned ordered_hashmap_buckets(OrderedHashmap *h) { +        return internal_hashmap_buckets(HASHMAP_BASE(h)); +} + +bool internal_hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key); +static inline bool hashmap_iterate(Hashmap *h, Iterator *i, void **value, const void **key) { +        return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key); +} +static inline bool ordered_hashmap_iterate(OrderedHashmap *h, Iterator *i, void **value, const void **key) { +        return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key); +} + +void internal_hashmap_clear(HashmapBase *h); +static inline void hashmap_clear(Hashmap *h) { +        internal_hashmap_clear(HASHMAP_BASE(h)); +} +static inline void ordered_hashmap_clear(OrderedHashmap *h) { +        internal_hashmap_clear(HASHMAP_BASE(h)); +} + +void internal_hashmap_clear_free(HashmapBase *h); +static inline void hashmap_clear_free(Hashmap *h) { +        internal_hashmap_clear_free(HASHMAP_BASE(h)); +} +static inline void ordered_hashmap_clear_free(OrderedHashmap *h) { +        internal_hashmap_clear_free(HASHMAP_BASE(h)); +} + +void hashmap_clear_free_free(Hashmap *h); +static inline void ordered_hashmap_clear_free_free(OrderedHashmap *h) { +        hashmap_clear_free_free(PLAIN_HASHMAP(h)); +} + +/* + * Note about all *_first*() functions + * + * For plain Hashmaps and Sets the order of entries is undefined. + * The functions find whatever entry is first in the implementation + * internal order. + * + * Only for OrderedHashmaps the order is well defined and finding + * the first entry is O(1). + */ + +void *internal_hashmap_steal_first(HashmapBase *h); +static inline void *hashmap_steal_first(Hashmap *h) { +        return internal_hashmap_steal_first(HASHMAP_BASE(h)); +} +static inline void *ordered_hashmap_steal_first(OrderedHashmap *h) { +        return internal_hashmap_steal_first(HASHMAP_BASE(h)); +} + +void *internal_hashmap_steal_first_key(HashmapBase *h); +static inline void *hashmap_steal_first_key(Hashmap *h) { +        return internal_hashmap_steal_first_key(HASHMAP_BASE(h)); +} +static inline void *ordered_hashmap_steal_first_key(OrderedHashmap *h) { +        return internal_hashmap_steal_first_key(HASHMAP_BASE(h)); +} + +void *internal_hashmap_first_key(HashmapBase *h) _pure_; +static inline void *hashmap_first_key(Hashmap *h) { +        return internal_hashmap_first_key(HASHMAP_BASE(h)); +} +static inline void *ordered_hashmap_first_key(OrderedHashmap *h) { +        return internal_hashmap_first_key(HASHMAP_BASE(h)); +} + +void *internal_hashmap_first(HashmapBase *h) _pure_; +static inline void *hashmap_first(Hashmap *h) { +        return internal_hashmap_first(HASHMAP_BASE(h)); +} +static inline void *ordered_hashmap_first(OrderedHashmap *h) { +        return internal_hashmap_first(HASHMAP_BASE(h)); +} + +/* no hashmap_next */ +void *ordered_hashmap_next(OrderedHashmap *h, const void *key); + +char **internal_hashmap_get_strv(HashmapBase *h); +static inline char **hashmap_get_strv(Hashmap *h) { +        return internal_hashmap_get_strv(HASHMAP_BASE(h)); +} +static inline char **ordered_hashmap_get_strv(OrderedHashmap *h) { +        return internal_hashmap_get_strv(HASHMAP_BASE(h)); +} + +/* + * Hashmaps are iterated in unpredictable order. + * OrderedHashmaps are an exception to this. They are iterated in the order + * the entries were inserted. + * It is safe to remove the current entry. + */ +#define HASHMAP_FOREACH(e, h, i) \ +        for ((i) = ITERATOR_FIRST; hashmap_iterate((h), &(i), (void**)&(e), NULL); ) + +#define ORDERED_HASHMAP_FOREACH(e, h, i) \ +        for ((i) = ITERATOR_FIRST; ordered_hashmap_iterate((h), &(i), (void**)&(e), NULL); ) + +#define HASHMAP_FOREACH_KEY(e, k, h, i) \ +        for ((i) = ITERATOR_FIRST; hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); ) + +#define ORDERED_HASHMAP_FOREACH_KEY(e, k, h, i) \ +        for ((i) = ITERATOR_FIRST; ordered_hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); ) + +DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free_free); + +#define _cleanup_hashmap_free_ _cleanup_(hashmap_freep) +#define _cleanup_hashmap_free_free_ _cleanup_(hashmap_free_freep) +#define _cleanup_hashmap_free_free_free_ _cleanup_(hashmap_free_free_freep) +#define _cleanup_ordered_hashmap_free_ _cleanup_(ordered_hashmap_freep) +#define _cleanup_ordered_hashmap_free_free_ _cleanup_(ordered_hashmap_free_freep) +#define _cleanup_ordered_hashmap_free_free_free_ _cleanup_(ordered_hashmap_free_free_freep) diff --git a/src/libsystemd-basic/include/systemd-basic/hexdecoct.h b/src/libsystemd-basic/include/systemd-basic/hexdecoct.h new file mode 100644 index 0000000000..1ba2f69ebd --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/hexdecoct.h @@ -0,0 +1,56 @@ +#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 <stddef.h> +#include <stdio.h> +#include <sys/types.h> + +#include "macro.h" + +char octchar(int x) _const_; +int unoctchar(char c) _const_; + +char decchar(int x) _const_; +int undecchar(char c) _const_; + +char hexchar(int x) _const_; +int unhexchar(char c) _const_; + +char *hexmem(const void *p, size_t l); +int unhexmem(const char *p, size_t l, void **mem, size_t *len); + +char base32hexchar(int x) _const_; +int unbase32hexchar(char c) _const_; + +char base64char(int x) _const_; +int unbase64char(char c) _const_; + +char *base32hexmem(const void *p, size_t l, bool padding); +int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *len); + +ssize_t base64mem(const void *p, size_t l, char **out); +int base64_append(char **prefix, int plen, +                  const void *p, size_t l, +                  int margin, int width); +int unbase64mem(const char *p, size_t l, void **mem, size_t *len); + +void hexdump(FILE *f, const void *p, size_t s); diff --git a/src/libsystemd-basic/include/systemd-basic/hostname-util.h b/src/libsystemd-basic/include/systemd-basic/hostname-util.h new file mode 100644 index 0000000000..7af4e6c7ec --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/hostname-util.h @@ -0,0 +1,41 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2010-2015 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 "macro.h" + +bool hostname_is_set(void); + +char* gethostname_malloc(void); +int gethostname_strict(char **ret); + +bool hostname_is_valid(const char *s, bool allow_trailing_dot) _pure_; +char* hostname_cleanup(char *s); + +#define machine_name_is_valid(s) hostname_is_valid(s, false) + +bool is_localhost(const char *hostname); +bool is_gateway_hostname(const char *hostname); + +int sethostname_idempotent(const char *s); + +int read_hostname_config(const char *path, char **hostname); diff --git a/src/libsystemd-basic/include/systemd-basic/in-addr-util.h b/src/libsystemd-basic/include/systemd-basic/in-addr-util.h new file mode 100644 index 0000000000..d60064aef8 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/in-addr-util.h @@ -0,0 +1,64 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2014 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 <netinet/in.h> +#include <stddef.h> +#include <sys/socket.h> + +#include "macro.h" +#include "util.h" + +union in_addr_union { +        struct in_addr in; +        struct in6_addr in6; +}; + +struct in_addr_data { +        int family; +        union in_addr_union address; +}; + +bool in4_addr_is_null(const struct in_addr *a); +bool in6_addr_is_null(const struct in6_addr *a); + +int in_addr_is_null(int family, const union in_addr_union *u); +int in_addr_is_link_local(int family, const union in_addr_union *u); +int in_addr_is_localhost(int family, const union in_addr_union *u); +int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b); +int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen); +int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen); +int in_addr_to_string(int family, const union in_addr_union *u, char **ret); +int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifindex, char **ret); +int in_addr_from_string(int family, const char *s, union in_addr_union *ret); +int in_addr_from_string_auto(const char *s, int *family, union in_addr_union *ret); +int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_union *ret, int *ifindex); +unsigned char in_addr_netmask_to_prefixlen(const struct in_addr *addr); +struct in_addr* in_addr_prefixlen_to_netmask(struct in_addr *addr, unsigned char prefixlen); +int in_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen); +int in_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mask); +int in_addr_mask(int family, union in_addr_union *addr, unsigned char prefixlen); + +static inline size_t FAMILY_ADDRESS_SIZE(int family) { +        assert(family == AF_INET || family == AF_INET6); +        return family == AF_INET6 ? 16 : 4; +} + +#define IN_ADDR_NULL ((union in_addr_union) {}) diff --git a/src/libsystemd-basic/include/systemd-basic/io-util.h b/src/libsystemd-basic/include/systemd-basic/io-util.h new file mode 100644 index 0000000000..4684ed3bfc --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/io-util.h @@ -0,0 +1,95 @@ +#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 <stddef.h> +#include <stdint.h> +#include <sys/types.h> +#include <sys/uio.h> + +#include "macro.h" +#include "time-util.h" + +int flush_fd(int fd); + +ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll); +int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll); +int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll); + +int pipe_eof(int fd); + +int fd_wait_for_event(int fd, int event, usec_t timeout); + +ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length); + +#define IOVEC_SET_STRING(i, s)                  \ +        do {                                    \ +                struct iovec *_i = &(i);        \ +                char *_s = (char *)(s);         \ +                _i->iov_base = _s;              \ +                _i->iov_len = strlen(_s);       \ +        } while (false) + +static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) { +        unsigned j; +        size_t r = 0; + +        for (j = 0; j < n; j++) +                r += i[j].iov_len; + +        return r; +} + +static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) { +        unsigned j; + +        for (j = 0; j < n; j++) { +                size_t sub; + +                if (_unlikely_(k <= 0)) +                        break; + +                sub = MIN(i[j].iov_len, k); +                i[j].iov_len -= sub; +                i[j].iov_base = (uint8_t*) i[j].iov_base + sub; +                k -= sub; +        } + +        return k; +} + +static inline bool FILE_SIZE_VALID(uint64_t l) { +        /* ftruncate() and friends take an unsigned file size, but actually cannot deal with file sizes larger than +         * 2^63 since the kernel internally handles it as signed value. This call allows checking for this early. */ + +        return (l >> 63) == 0; +} + +static inline bool FILE_SIZE_VALID_OR_INFINITY(uint64_t l) { + +        /* Same as above, but allows one extra value: -1 as indication for infinity. */ + +        if (l == (uint64_t) -1) +                return true; + +        return FILE_SIZE_VALID(l); + +} diff --git a/src/libsystemd-basic/include/systemd-basic/ioprio.h b/src/libsystemd-basic/include/systemd-basic/ioprio.h new file mode 100644 index 0000000000..d8bb6eb497 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/ioprio.h @@ -0,0 +1,55 @@ +#ifndef IOPRIO_H +#define IOPRIO_H + +/* This is minimal version of Linux' linux/ioprio.h header file, which + * is licensed GPL2 */ + +#include <sys/syscall.h> +#include <unistd.h> + +/* + * Gives us 8 prio classes with 13-bits of data for each class + */ +#define IOPRIO_BITS             (16) +#define IOPRIO_CLASS_SHIFT      (13) +#define IOPRIO_PRIO_MASK        ((1UL << IOPRIO_CLASS_SHIFT) - 1) + +#define IOPRIO_PRIO_CLASS(mask) ((mask) >> IOPRIO_CLASS_SHIFT) +#define IOPRIO_PRIO_DATA(mask)  ((mask) & IOPRIO_PRIO_MASK) +#define IOPRIO_PRIO_VALUE(class, data)  (((class) << IOPRIO_CLASS_SHIFT) | data) + +#define ioprio_valid(mask)      (IOPRIO_PRIO_CLASS((mask)) != IOPRIO_CLASS_NONE) + +/* + * These are the io priority groups as implemented by CFQ. RT is the realtime + * class, it always gets premium service. BE is the best-effort scheduling + * class, the default for any process. IDLE is the idle scheduling class, it + * is only served when no one else is using the disk. + */ +enum { +        IOPRIO_CLASS_NONE, +        IOPRIO_CLASS_RT, +        IOPRIO_CLASS_BE, +        IOPRIO_CLASS_IDLE, +}; + +/* + * 8 best effort priority levels are supported + */ +#define IOPRIO_BE_NR    (8) + +enum { +        IOPRIO_WHO_PROCESS = 1, +        IOPRIO_WHO_PGRP, +        IOPRIO_WHO_USER, +}; + +static inline int ioprio_set(int which, int who, int ioprio) { +        return syscall(__NR_ioprio_set, which, who, ioprio); +} + +static inline int ioprio_get(int which, int who) { +        return syscall(__NR_ioprio_get, which, who); +} + +#endif diff --git a/src/libsystemd-basic/include/systemd-basic/label.h b/src/libsystemd-basic/include/systemd-basic/label.h new file mode 100644 index 0000000000..3e9251aa71 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/label.h @@ -0,0 +1,28 @@ +#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> + +int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs); + +int mkdir_label(const char *path, mode_t mode); +int symlink_label(const char *old_path, const char *new_path); diff --git a/src/libsystemd-basic/include/systemd-basic/list.h b/src/libsystemd-basic/include/systemd-basic/list.h new file mode 100644 index 0000000000..c3771a177f --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/list.h @@ -0,0 +1,184 @@ +#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/>. +***/ + +/* The head of the linked list. Use this in the structure that shall + * contain the head of the linked list */ +#define LIST_HEAD(t,name)                                               \ +        t *name + +/* The pointers in the linked list's items. Use this in the item structure */ +#define LIST_FIELDS(t,name)                                             \ +        t *name##_next, *name##_prev + +/* Initialize the list's head */ +#define LIST_HEAD_INIT(head)                                            \ +        do {                                                            \ +                (head) = NULL; }                                        \ +        while (false) + +/* Initialize a list item */ +#define LIST_INIT(name,item)                                            \ +        do {                                                            \ +                typeof(*(item)) *_item = (item);                        \ +                assert(_item);                                          \ +                _item->name##_prev = _item->name##_next = NULL;         \ +        } while (false) + +/* Prepend an item to the list */ +#define LIST_PREPEND(name,head,item)                                    \ +        do {                                                            \ +                typeof(*(head)) **_head = &(head), *_item = (item);     \ +                assert(_item);                                          \ +                if ((_item->name##_next = *_head))                      \ +                        _item->name##_next->name##_prev = _item;        \ +                _item->name##_prev = NULL;                              \ +                *_head = _item;                                         \ +        } while (false) + +/* Append an item to the list */ +#define LIST_APPEND(name,head,item)                                     \ +        do {                                                            \ +                typeof(*(head)) *_tail;                                 \ +                LIST_FIND_TAIL(name,head,_tail);                        \ +                LIST_INSERT_AFTER(name,head,_tail,item);                \ +        } while (false) + +/* Remove an item from the list */ +#define LIST_REMOVE(name,head,item)                                     \ +        do {                                                            \ +                typeof(*(head)) **_head = &(head), *_item = (item);     \ +                assert(_item);                                          \ +                if (_item->name##_next)                                 \ +                        _item->name##_next->name##_prev = _item->name##_prev; \ +                if (_item->name##_prev)                                 \ +                        _item->name##_prev->name##_next = _item->name##_next; \ +                else {                                                  \ +                        assert(*_head == _item);                        \ +                        *_head = _item->name##_next;                    \ +                }                                                       \ +                _item->name##_next = _item->name##_prev = NULL;         \ +        } while (false) + +/* Find the head of the list */ +#define LIST_FIND_HEAD(name,item,head)                                  \ +        do {                                                            \ +                typeof(*(item)) *_item = (item);                        \ +                if (!_item)                                             \ +                        (head) = NULL;                                  \ +                else {                                                  \ +                        while (_item->name##_prev)                      \ +                                _item = _item->name##_prev;             \ +                        (head) = _item;                                 \ +                }                                                       \ +        } while (false) + +/* Find the tail of the list */ +#define LIST_FIND_TAIL(name,item,tail)                                  \ +        do {                                                            \ +                typeof(*(item)) *_item = (item);                        \ +                if (!_item)                                             \ +                        (tail) = NULL;                                  \ +                else {                                                  \ +                        while (_item->name##_next)                      \ +                                _item = _item->name##_next;             \ +                        (tail) = _item;                                 \ +                }                                                       \ +        } while (false) + +/* Insert an item after another one (a = where, b = what) */ +#define LIST_INSERT_AFTER(name,head,a,b)                                \ +        do {                                                            \ +                typeof(*(head)) **_head = &(head), *_a = (a), *_b = (b); \ +                assert(_b);                                             \ +                if (!_a) {                                              \ +                        if ((_b->name##_next = *_head))                 \ +                                _b->name##_next->name##_prev = _b;      \ +                        _b->name##_prev = NULL;                         \ +                        *_head = _b;                                    \ +                } else {                                                \ +                        if ((_b->name##_next = _a->name##_next))        \ +                                _b->name##_next->name##_prev = _b;      \ +                        _b->name##_prev = _a;                           \ +                        _a->name##_next = _b;                           \ +                }                                                       \ +        } while (false) + +/* Insert an item before another one (a = where, b = what) */ +#define LIST_INSERT_BEFORE(name,head,a,b)                               \ +        do {                                                            \ +                typeof(*(head)) **_head = &(head), *_a = (a), *_b = (b); \ +                assert(_b);                                             \ +                if (!_a) {                                              \ +                        if (!*_head) {                                  \ +                                _b->name##_next = NULL;                 \ +                                _b->name##_prev = NULL;                 \ +                                *_head = _b;                            \ +                        } else {                                        \ +                                typeof(*(head)) *_tail = (head);        \ +                                while (_tail->name##_next)              \ +                                        _tail = _tail->name##_next;     \ +                                _b->name##_next = NULL;                 \ +                                _b->name##_prev = _tail;                \ +                                _tail->name##_next = _b;                \ +                        }                                               \ +                } else {                                                \ +                        if ((_b->name##_prev = _a->name##_prev))        \ +                                _b->name##_prev->name##_next = _b;      \ +                        else                                            \ +                                *_head = _b;                            \ +                        _b->name##_next = _a;                           \ +                        _a->name##_prev = _b;                           \ +                }                                                       \ +        } while (false) + +#define LIST_JUST_US(name,item)                                         \ +        (!(item)->name##_prev && !(item)->name##_next)                  \ + +#define LIST_FOREACH(name,i,head)                                       \ +        for ((i) = (head); (i); (i) = (i)->name##_next) + +#define LIST_FOREACH_SAFE(name,i,n,head)                                \ +        for ((i) = (head); (i) && (((n) = (i)->name##_next), 1); (i) = (n)) + +#define LIST_FOREACH_BEFORE(name,i,p)                                   \ +        for ((i) = (p)->name##_prev; (i); (i) = (i)->name##_prev) + +#define LIST_FOREACH_AFTER(name,i,p)                                    \ +        for ((i) = (p)->name##_next; (i); (i) = (i)->name##_next) + +/* Iterate through all the members of the list p is included in, but skip over p */ +#define LIST_FOREACH_OTHERS(name,i,p)                                   \ +        for (({                                                         \ +                (i) = (p);                                              \ +                while ((i) && (i)->name##_prev)                         \ +                        (i) = (i)->name##_prev;                         \ +                if ((i) == (p))                                         \ +                        (i) = (p)->name##_next;                         \ +             });                                                        \ +             (i);                                                       \ +             (i) = (i)->name##_next == (p) ? (p)->name##_next : (i)->name##_next) + +/* Loop starting from p->next until p->prev. +   p can be adjusted meanwhile. */ +#define LIST_LOOP_BUT_ONE(name,i,head,p)                                \ +        for ((i) = (p)->name##_next ? (p)->name##_next : (head);        \ +             (i) != (p);                                                \ +             (i) = (i)->name##_next ? (i)->name##_next : (head)) diff --git a/src/libsystemd-basic/include/systemd-basic/locale-util.h b/src/libsystemd-basic/include/systemd-basic/locale-util.h new file mode 100644 index 0000000000..0630a034ab --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/locale-util.h @@ -0,0 +1,73 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2014 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 <libintl.h> +#include <stdbool.h> + +#include "macro.h" + +typedef enum LocaleVariable { +        /* We don't list LC_ALL here on purpose. People should be +         * using LANG instead. */ + +        VARIABLE_LANG, +        VARIABLE_LANGUAGE, +        VARIABLE_LC_CTYPE, +        VARIABLE_LC_NUMERIC, +        VARIABLE_LC_TIME, +        VARIABLE_LC_COLLATE, +        VARIABLE_LC_MONETARY, +        VARIABLE_LC_MESSAGES, +        VARIABLE_LC_PAPER, +        VARIABLE_LC_NAME, +        VARIABLE_LC_ADDRESS, +        VARIABLE_LC_TELEPHONE, +        VARIABLE_LC_MEASUREMENT, +        VARIABLE_LC_IDENTIFICATION, +        _VARIABLE_LC_MAX, +        _VARIABLE_LC_INVALID = -1 +} LocaleVariable; + +int get_locales(char ***l); +bool locale_is_valid(const char *name); + +#define _(String) gettext(String) +#define N_(String) String +void init_gettext(void); + +bool is_locale_utf8(void); + +typedef enum { +        TREE_VERTICAL, +        TREE_BRANCH, +        TREE_RIGHT, +        TREE_SPACE, +        TRIANGULAR_BULLET, +        BLACK_CIRCLE, +        ARROW, +        MDASH, +        _SPECIAL_GLYPH_MAX +} SpecialGlyph; + +const char *special_glyph(SpecialGlyph code) _const_; + +const char* locale_variable_to_string(LocaleVariable i) _const_; +LocaleVariable locale_variable_from_string(const char *s) _pure_; diff --git a/src/libsystemd-basic/include/systemd-basic/lockfile-util.h b/src/libsystemd-basic/include/systemd-basic/lockfile-util.h new file mode 100644 index 0000000000..22491ee8e1 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/lockfile-util.h @@ -0,0 +1,39 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2011 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 <stddef.h> + +#include "macro.h" +#include "missing.h" + +typedef struct LockFile { +        char *path; +        int fd; +        int operation; +} LockFile; + +int make_lock_file(const char *p, int operation, LockFile *ret); +int make_lock_file_for(const char *p, int operation, LockFile *ret); +void release_lock_file(LockFile *f); + +#define _cleanup_release_lock_file_ _cleanup_(release_lock_file) + +#define LOCK_FILE_INIT { .fd = -1, .path = NULL } diff --git a/src/libsystemd-basic/include/systemd-basic/log.h b/src/libsystemd-basic/include/systemd-basic/log.h new file mode 100644 index 0000000000..f5f62e1c23 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/log.h @@ -0,0 +1,253 @@ +#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 <errno.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stdlib.h> +#include <sys/signalfd.h> +#include <sys/socket.h> +#include <syslog.h> + +#include <systemd/sd-id128.h> + +#include "macro.h" + +typedef enum LogTarget{ +        LOG_TARGET_CONSOLE, +        LOG_TARGET_CONSOLE_PREFIXED, +        LOG_TARGET_KMSG, +        LOG_TARGET_JOURNAL, +        LOG_TARGET_JOURNAL_OR_KMSG, +        LOG_TARGET_SYSLOG, +        LOG_TARGET_SYSLOG_OR_KMSG, +        LOG_TARGET_AUTO, /* console if stderr is tty, JOURNAL_OR_KMSG otherwise */ +        LOG_TARGET_SAFE, /* console if stderr is tty, KMSG otherwise */ +        LOG_TARGET_NULL, +        _LOG_TARGET_MAX, +        _LOG_TARGET_INVALID = -1 +}  LogTarget; + +void log_set_target(LogTarget target); +void log_set_max_level(int level); +void log_set_facility(int facility); + +int log_set_target_from_string(const char *e); +int log_set_max_level_from_string(const char *e); + +void log_show_color(bool b); +bool log_get_show_color(void) _pure_; +void log_show_location(bool b); +bool log_get_show_location(void) _pure_; + +int log_show_color_from_string(const char *e); +int log_show_location_from_string(const char *e); + +LogTarget log_get_target(void) _pure_; +int log_get_max_level(void) _pure_; + +int log_open(void); +void log_close(void); +void log_forget_fds(void); + +void log_close_syslog(void); +void log_close_journal(void); +void log_close_kmsg(void); +void log_close_console(void); + +void log_parse_environment(void); + +int log_internal( +                int level, +                int error, +                const char *file, +                int line, +                const char *func, +                const char *format, ...) _printf_(6,7); + +int log_internalv( +                int level, +                int error, +                const char *file, +                int line, +                const char *func, +                const char *format, +                va_list ap) _printf_(6,0); + +int log_object_internal( +                int level, +                int error, +                const char *file, +                int line, +                const char *func, +                const char *object_field, +                const char *object, +                const char *extra_field, +                const char *extra, +                const char *format, ...) _printf_(10,11); + +int log_object_internalv( +                int level, +                int error, +                const char *file, +                int line, +                const char *func, +                const char *object_field, +                const char *object, +                const char *extra_field, +                const char *extra, +                const char *format, +                va_list ap) _printf_(9,0); + +int log_struct_internal( +                int level, +                int error, +                const char *file, +                int line, +                const char *func, +                const char *format, ...) _printf_(6,0) _sentinel_; + +int log_oom_internal( +                const char *file, +                int line, +                const char *func); + +int log_format_iovec( +                struct iovec *iovec, +                unsigned iovec_len, +                unsigned *n, +                bool newline_separator, +                int error, +                const char *format, +                va_list ap); + +/* This modifies the buffer passed! */ +int log_dump_internal( +                int level, +                int error, +                const char *file, +                int line, +                const char *func, +                char *buffer); + +/* Logging for various assertions */ +noreturn void log_assert_failed( +                const char *text, +                const char *file, +                int line, +                const char *func); + +noreturn void log_assert_failed_unreachable( +                const char *text, +                const char *file, +                int line, +                const char *func); + +void log_assert_failed_return( +                const char *text, +                const char *file, +                int line, +                const char *func); + +/* Logging with level */ +#define log_full_errno(level, error, ...)                               \ +        ({                                                              \ +                int _level = (level), _e = (error);                     \ +                (log_get_max_level() >= LOG_PRI(_level))                \ +                        ? log_internal(_level, _e, __FILE__, __LINE__, __func__, __VA_ARGS__) \ +                        : -abs(_e);                                     \ +        }) + +#define log_full(level, ...) log_full_errno(level, 0, __VA_ARGS__) + +/* Normal logging */ +#define log_debug(...)     log_full(LOG_DEBUG,   __VA_ARGS__) +#define log_info(...)      log_full(LOG_INFO,    __VA_ARGS__) +#define log_notice(...)    log_full(LOG_NOTICE,  __VA_ARGS__) +#define log_warning(...)   log_full(LOG_WARNING, __VA_ARGS__) +#define log_error(...)     log_full(LOG_ERR,     __VA_ARGS__) +#define log_emergency(...) log_full(getpid() == 1 ? LOG_EMERG : LOG_ERR, __VA_ARGS__) + +/* Logging triggered by an errno-like error */ +#define log_debug_errno(error, ...)     log_full_errno(LOG_DEBUG,   error, __VA_ARGS__) +#define log_info_errno(error, ...)      log_full_errno(LOG_INFO,    error, __VA_ARGS__) +#define log_notice_errno(error, ...)    log_full_errno(LOG_NOTICE,  error, __VA_ARGS__) +#define log_warning_errno(error, ...)   log_full_errno(LOG_WARNING, error, __VA_ARGS__) +#define log_error_errno(error, ...)     log_full_errno(LOG_ERR,     error, __VA_ARGS__) +#define log_emergency_errno(error, ...) log_full_errno(getpid() == 1 ? LOG_EMERG : LOG_ERR, error, __VA_ARGS__) + +#ifdef LOG_TRACE +#  define log_trace(...) log_debug(__VA_ARGS__) +#else +#  define log_trace(...) do {} while (0) +#endif + +/* Structured logging */ +#define log_struct(level, ...) log_struct_internal(level, 0, __FILE__, __LINE__, __func__, __VA_ARGS__) +#define log_struct_errno(level, error, ...) log_struct_internal(level, error, __FILE__, __LINE__, __func__, __VA_ARGS__) + +/* This modifies the buffer passed! */ +#define log_dump(level, buffer) log_dump_internal(level, 0, __FILE__, __LINE__, __func__, buffer) + +#define log_oom() log_oom_internal(__FILE__, __LINE__, __func__) + +bool log_on_console(void) _pure_; + +const char *log_target_to_string(LogTarget target) _const_; +LogTarget log_target_from_string(const char *s) _pure_; + +/* Helpers to prepare various fields for structured logging */ +#define LOG_MESSAGE(fmt, ...) "MESSAGE=" fmt, ##__VA_ARGS__ +#define LOG_MESSAGE_ID(x) "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(x) + +void log_received_signal(int level, const struct signalfd_siginfo *si); + +void log_set_upgrade_syslog_to_journal(bool b); + +int log_syntax_internal( +                const char *unit, +                int level, +                const char *config_file, +                unsigned config_line, +                int error, +                const char *file, +                int line, +                const char *func, +                const char *format, ...) _printf_(9, 10); + +#define log_syntax(unit, level, config_file, config_line, error, ...)   \ +        ({                                                              \ +                int _level = (level), _e = (error);                     \ +                (log_get_max_level() >= LOG_PRI(_level))                \ +                        ? log_syntax_internal(unit, _level, config_file, config_line, _e, __FILE__, __LINE__, __func__, __VA_ARGS__) \ +                        : -abs(_e);                                     \ +        }) + +#define log_syntax_invalid_utf8(unit, level, config_file, config_line, rvalue) \ +        ({                                                              \ +                int _level = (level);                                   \ +                if (log_get_max_level() >= LOG_PRI(_level)) {           \ +                        _cleanup_free_ char *_p = NULL;                 \ +                        _p = utf8_escape_invalid(rvalue);               \ +                        log_syntax_internal(unit, _level, config_file, config_line, 0, __FILE__, __LINE__, __func__, \ +                                            "String is not UTF-8 clean, ignoring assignment: %s", strna(_p)); \ +                }                                                       \ +        }) diff --git a/src/libsystemd-basic/include/systemd-basic/login-util.h b/src/libsystemd-basic/include/systemd-basic/login-util.h new file mode 100644 index 0000000000..b01ee25c88 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/login-util.h @@ -0,0 +1,29 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2013 Zbigniew JÄ™drzejewski-Szmek + +  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 <unistd.h> + +bool session_id_valid(const char *id); + +static inline bool logind_running(void) { +        return access("/run/systemd/seats/", F_OK) >= 0; +} diff --git a/src/libsystemd-basic/include/systemd-basic/macro.h b/src/libsystemd-basic/include/systemd-basic/macro.h new file mode 100644 index 0000000000..6b2aeb933f --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/macro.h @@ -0,0 +1,415 @@ +#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 <assert.h> +#include <inttypes.h> +#include <stdbool.h> +#include <sys/param.h> +#include <sys/sysmacros.h> +#include <sys/types.h> + +#define _printf_(a,b) __attribute__ ((format (printf, a, b))) +#ifdef __clang__ +#  define _alloc_(...) +#else +#  define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__))) +#endif +#define _sentinel_ __attribute__ ((sentinel)) +#define _unused_ __attribute__ ((unused)) +#define _destructor_ __attribute__ ((destructor)) +#define _pure_ __attribute__ ((pure)) +#define _const_ __attribute__ ((const)) +#define _deprecated_ __attribute__ ((deprecated)) +#define _packed_ __attribute__ ((packed)) +#define _malloc_ __attribute__ ((malloc)) +#define _weak_ __attribute__ ((weak)) +#define _likely_(x) (__builtin_expect(!!(x),1)) +#define _unlikely_(x) (__builtin_expect(!!(x),0)) +#define _public_ __attribute__ ((visibility("default"))) +#define _hidden_ __attribute__ ((visibility("hidden"))) +#define _weakref_(x) __attribute__((weakref(#x))) +#define _alignas_(x) __attribute__((aligned(__alignof(x)))) +#define _cleanup_(x) __attribute__((cleanup(x))) + +/* Temporarily disable some warnings */ +#define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT                     \ +        _Pragma("GCC diagnostic push");                                 \ +        _Pragma("GCC diagnostic ignored \"-Wdeclaration-after-statement\"") + +#define DISABLE_WARNING_FORMAT_NONLITERAL                               \ +        _Pragma("GCC diagnostic push");                                 \ +        _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") + +#define DISABLE_WARNING_MISSING_PROTOTYPES                              \ +        _Pragma("GCC diagnostic push");                                 \ +        _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"") + +#define DISABLE_WARNING_NONNULL                                         \ +        _Pragma("GCC diagnostic push");                                 \ +        _Pragma("GCC diagnostic ignored \"-Wnonnull\"") + +#define DISABLE_WARNING_SHADOW                                          \ +        _Pragma("GCC diagnostic push");                                 \ +        _Pragma("GCC diagnostic ignored \"-Wshadow\"") + +#define DISABLE_WARNING_INCOMPATIBLE_POINTER_TYPES                      \ +        _Pragma("GCC diagnostic push");                                 \ +        _Pragma("GCC diagnostic ignored \"-Wincompatible-pointer-types\"") + +#define REENABLE_WARNING                                                \ +        _Pragma("GCC diagnostic pop") + +/* automake test harness */ +#define EXIT_TEST_SKIP 77 + +#define XSTRINGIFY(x) #x +#define STRINGIFY(x) XSTRINGIFY(x) + +#define XCONCATENATE(x, y) x ## y +#define CONCATENATE(x, y) XCONCATENATE(x, y) + +#define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq)) +#define UNIQ __COUNTER__ + +/* builtins */ +#if __SIZEOF_INT__ == 4 +#define BUILTIN_FFS_U32(x) __builtin_ffs(x); +#elif __SIZEOF_LONG__ == 4 +#define BUILTIN_FFS_U32(x) __builtin_ffsl(x); +#else +#error "neither int nor long are four bytes long?!?" +#endif + +/* Rounds up */ + +#define ALIGN4(l) (((l) + 3) & ~3) +#define ALIGN8(l) (((l) + 7) & ~7) + +#if __SIZEOF_POINTER__ == 8 +#define ALIGN(l) ALIGN8(l) +#elif __SIZEOF_POINTER__ == 4 +#define ALIGN(l) ALIGN4(l) +#else +#error "Wut? Pointers are neither 4 nor 8 bytes long?" +#endif + +#define ALIGN_PTR(p) ((void*) ALIGN((unsigned long) (p))) +#define ALIGN4_PTR(p) ((void*) ALIGN4((unsigned long) (p))) +#define ALIGN8_PTR(p) ((void*) ALIGN8((unsigned long) (p))) + +static inline size_t ALIGN_TO(size_t l, size_t ali) { +        return ((l + ali - 1) & ~(ali - 1)); +} + +#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) (p), (ali))) + +/* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */ +static inline unsigned long ALIGN_POWER2(unsigned long u) { +        /* clz(0) is undefined */ +        if (u == 1) +                return 1; + +        /* left-shift overflow is undefined */ +        if (__builtin_clzl(u - 1UL) < 1) +                return 0; + +        return 1UL << (sizeof(u) * 8 - __builtin_clzl(u - 1UL)); +} + +#define ELEMENTSOF(x)                                                    \ +        __extension__ (__builtin_choose_expr(                            \ +                !__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \ +                sizeof(x)/sizeof((x)[0]),                                \ +                (void)0)) +/* + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + */ +#define container_of(ptr, type, member) __container_of(UNIQ, (ptr), type, member) +#define __container_of(uniq, ptr, type, member)                         \ +        __extension__ ({                                                \ +                const typeof( ((type*)0)->member ) *UNIQ_T(A, uniq) = (ptr); \ +                (type*)( (char *)UNIQ_T(A, uniq) - offsetof(type,member) ); \ +        }) + +#undef MAX +#define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b)) +#define __MAX(aq, a, bq, b)                             \ +        __extension__ ({                                \ +                const typeof(a) UNIQ_T(A, aq) = (a);    \ +                const typeof(b) UNIQ_T(B, bq) = (b);    \ +                UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \ +        }) + +/* evaluates to (void) if _A or _B are not constant or of different types */ +#define CONST_MAX(_A, _B) \ +        __extension__ (__builtin_choose_expr(                           \ +                __builtin_constant_p(_A) &&                             \ +                __builtin_constant_p(_B) &&                             \ +                __builtin_types_compatible_p(typeof(_A), typeof(_B)),   \ +                ((_A) > (_B)) ? (_A) : (_B),                            \ +                (void)0)) + +/* takes two types and returns the size of the larger one */ +#define MAXSIZE(A, B) (sizeof(union _packed_ { typeof(A) a; typeof(B) b; })) + +#define MAX3(x,y,z)                                     \ +        __extension__ ({                                \ +                        const typeof(x) _c = MAX(x,y);  \ +                        MAX(_c, z);                     \ +                }) + +#undef MIN +#define MIN(a, b) __MIN(UNIQ, (a), UNIQ, (b)) +#define __MIN(aq, a, bq, b)                             \ +        __extension__ ({                                \ +                const typeof(a) UNIQ_T(A, aq) = (a);    \ +                const typeof(b) UNIQ_T(B, bq) = (b);    \ +                UNIQ_T(A,aq) < UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \ +        }) + +#define MIN3(x,y,z)                                     \ +        __extension__ ({                                \ +                        const typeof(x) _c = MIN(x,y);  \ +                        MIN(_c, z);                     \ +                }) + +#define LESS_BY(a, b) __LESS_BY(UNIQ, (a), UNIQ, (b)) +#define __LESS_BY(aq, a, bq, b)                         \ +        __extension__ ({                                \ +                const typeof(a) UNIQ_T(A, aq) = (a);    \ +                const typeof(b) UNIQ_T(B, bq) = (b);    \ +                UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) - UNIQ_T(B,bq) : 0; \ +        }) + +#undef CLAMP +#define CLAMP(x, low, high) __CLAMP(UNIQ, (x), UNIQ, (low), UNIQ, (high)) +#define __CLAMP(xq, x, lowq, low, highq, high)                          \ +        __extension__ ({                                                \ +                const typeof(x) UNIQ_T(X,xq) = (x);                     \ +                const typeof(low) UNIQ_T(LOW,lowq) = (low);             \ +                const typeof(high) UNIQ_T(HIGH,highq) = (high);         \ +                        UNIQ_T(X,xq) > UNIQ_T(HIGH,highq) ?             \ +                                UNIQ_T(HIGH,highq) :                    \ +                                UNIQ_T(X,xq) < UNIQ_T(LOW,lowq) ?       \ +                                        UNIQ_T(LOW,lowq) :              \ +                                        UNIQ_T(X,xq);                   \ +        }) + +/* [(x + y - 1) / y] suffers from an integer overflow, even though the + * computation should be possible in the given type. Therefore, we use + * [x / y + !!(x % y)]. Note that on "Real CPUs" a division returns both the + * quotient and the remainder, so both should be equally fast. */ +#define DIV_ROUND_UP(_x, _y)                                            \ +        __extension__ ({                                                \ +                const typeof(_x) __x = (_x);                            \ +                const typeof(_y) __y = (_y);                            \ +                (__x / __y + !!(__x % __y));                            \ +        }) + +#define assert_message_se(expr, message)                                \ +        do {                                                            \ +                if (_unlikely_(!(expr)))                                \ +                        log_assert_failed(message, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ +        } while (false) + +#define assert_se(expr) assert_message_se(expr, #expr) + +/* We override the glibc assert() here. */ +#undef assert +#ifdef NDEBUG +#define assert(expr) do {} while (false) +#else +#define assert(expr) assert_message_se(expr, #expr) +#endif + +#define assert_not_reached(t)                                           \ +        do {                                                            \ +                log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ +        } while (false) + +#if defined(static_assert) +/* static_assert() is sometimes defined in a way that trips up + * -Wdeclaration-after-statement, hence let's temporarily turn off + * this warning around it. */ +#define assert_cc(expr)                                                 \ +        DISABLE_WARNING_DECLARATION_AFTER_STATEMENT;                    \ +        static_assert(expr, #expr);                                     \ +        REENABLE_WARNING +#else +#define assert_cc(expr)                                                 \ +        DISABLE_WARNING_DECLARATION_AFTER_STATEMENT;                    \ +        struct CONCATENATE(_assert_struct_, __COUNTER__) {              \ +                char x[(expr) ? 0 : -1];                                \ +        };                                                              \ +        REENABLE_WARNING +#endif + +#define assert_log(expr, message) ((_likely_(expr))                     \ +        ? (true)                                                        \ +        : (log_assert_failed_return(message, __FILE__, __LINE__, __PRETTY_FUNCTION__), false)) + +#define assert_return(expr, r)                                          \ +        do {                                                            \ +                if (!assert_log(expr, #expr))                           \ +                        return (r);                                     \ +        } while (false) + +#define assert_return_errno(expr, r, err)                               \ +        do {                                                            \ +                if (!assert_log(expr, #expr)) {                         \ +                        errno = err;                                    \ +                        return (r);                                     \ +                }                                                       \ +        } while (false) + +#define PTR_TO_INT(p) ((int) ((intptr_t) (p))) +#define INT_TO_PTR(u) ((void *) ((intptr_t) (u))) +#define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p))) +#define UINT_TO_PTR(u) ((void *) ((uintptr_t) (u))) + +#define PTR_TO_LONG(p) ((long) ((intptr_t) (p))) +#define LONG_TO_PTR(u) ((void *) ((intptr_t) (u))) +#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p))) +#define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u))) + +#define PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p))) +#define INT32_TO_PTR(u) ((void *) ((intptr_t) (u))) +#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p))) +#define UINT32_TO_PTR(u) ((void *) ((uintptr_t) (u))) + +#define PTR_TO_INT64(p) ((int64_t) ((intptr_t) (p))) +#define INT64_TO_PTR(u) ((void *) ((intptr_t) (u))) +#define PTR_TO_UINT64(p) ((uint64_t) ((uintptr_t) (p))) +#define UINT64_TO_PTR(u) ((void *) ((uintptr_t) (u))) + +#define PTR_TO_SIZE(p) ((size_t) ((uintptr_t) (p))) +#define SIZE_TO_PTR(u) ((void *) ((uintptr_t) (u))) + +#define CHAR_TO_STR(x) ((char[2]) { x, 0 }) + +#define char_array_0(x) x[sizeof(x)-1] = 0; + +/* Returns the number of chars needed to format variables of the + * specified type as a decimal string. Adds in extra space for a + * negative '-' prefix (hence works correctly on signed + * types). Includes space for the trailing NUL. */ +#define DECIMAL_STR_MAX(type)                                           \ +        (2+(sizeof(type) <= 1 ? 3 :                                     \ +            sizeof(type) <= 2 ? 5 :                                     \ +            sizeof(type) <= 4 ? 10 :                                    \ +            sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)]))) + +#define DECIMAL_STR_WIDTH(x)                            \ +        ({                                              \ +                typeof(x) _x_ = (x);                    \ +                unsigned ans = 1;                       \ +                while (_x_ /= 10)                       \ +                        ans++;                          \ +                ans;                                    \ +        }) + +#define SET_FLAG(v, flag, b) \ +        (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag)) + +#define CASE_F(X) case X: +#define CASE_F_1(CASE, X) CASE_F(X) +#define CASE_F_2(CASE, X, ...)  CASE(X) CASE_F_1(CASE, __VA_ARGS__) +#define CASE_F_3(CASE, X, ...)  CASE(X) CASE_F_2(CASE, __VA_ARGS__) +#define CASE_F_4(CASE, X, ...)  CASE(X) CASE_F_3(CASE, __VA_ARGS__) +#define CASE_F_5(CASE, X, ...)  CASE(X) CASE_F_4(CASE, __VA_ARGS__) +#define CASE_F_6(CASE, X, ...)  CASE(X) CASE_F_5(CASE, __VA_ARGS__) +#define CASE_F_7(CASE, X, ...)  CASE(X) CASE_F_6(CASE, __VA_ARGS__) +#define CASE_F_8(CASE, X, ...)  CASE(X) CASE_F_7(CASE, __VA_ARGS__) +#define CASE_F_9(CASE, X, ...)  CASE(X) CASE_F_8(CASE, __VA_ARGS__) +#define CASE_F_10(CASE, X, ...) CASE(X) CASE_F_9(CASE, __VA_ARGS__) +#define CASE_F_11(CASE, X, ...) CASE(X) CASE_F_10(CASE, __VA_ARGS__) +#define CASE_F_12(CASE, X, ...) CASE(X) CASE_F_11(CASE, __VA_ARGS__) +#define CASE_F_13(CASE, X, ...) CASE(X) CASE_F_12(CASE, __VA_ARGS__) +#define CASE_F_14(CASE, X, ...) CASE(X) CASE_F_13(CASE, __VA_ARGS__) +#define CASE_F_15(CASE, X, ...) CASE(X) CASE_F_14(CASE, __VA_ARGS__) +#define CASE_F_16(CASE, X, ...) CASE(X) CASE_F_15(CASE, __VA_ARGS__) +#define CASE_F_17(CASE, X, ...) CASE(X) CASE_F_16(CASE, __VA_ARGS__) +#define CASE_F_18(CASE, X, ...) CASE(X) CASE_F_17(CASE, __VA_ARGS__) +#define CASE_F_19(CASE, X, ...) CASE(X) CASE_F_18(CASE, __VA_ARGS__) +#define CASE_F_20(CASE, X, ...) CASE(X) CASE_F_19(CASE, __VA_ARGS__) + +#define GET_CASE_F(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,NAME,...) NAME +#define FOR_EACH_MAKE_CASE(...) \ +        GET_CASE_F(__VA_ARGS__,CASE_F_20,CASE_F_19,CASE_F_18,CASE_F_17,CASE_F_16,CASE_F_15,CASE_F_14,CASE_F_13,CASE_F_12,CASE_F_11, \ +                               CASE_F_10,CASE_F_9,CASE_F_8,CASE_F_7,CASE_F_6,CASE_F_5,CASE_F_4,CASE_F_3,CASE_F_2,CASE_F_1) \ +                   (CASE_F,__VA_ARGS__) + +#define IN_SET(x, ...)                          \ +        ({                                      \ +                bool _found = false;            \ +                /* If the build breaks in the line below, you need to extend the case macros */ \ +                static _unused_ char _static_assert__macros_need_to_be_extended[20 - sizeof((int[]){__VA_ARGS__})/sizeof(int)]; \ +                switch(x) {                     \ +                FOR_EACH_MAKE_CASE(__VA_ARGS__) \ +                        _found = true;          \ +                        break;                  \ +                default:                        \ +                        break;                  \ +                }                               \ +                _found;                         \ +        }) + +#define SWAP_TWO(x, y) do {                        \ +                typeof(x) _t = (x);                \ +                (x) = (y);                         \ +                (y) = (_t);                        \ +        } while (false) + +/* Define C11 thread_local attribute even on older gcc compiler + * version */ +#ifndef thread_local +/* + * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__ + * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769 + */ +#if __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16)) +#define thread_local _Thread_local +#else +#define thread_local __thread +#endif +#endif + +/* Define C11 noreturn without <stdnoreturn.h> and even on older gcc + * compiler versions */ +#ifndef noreturn +#if __STDC_VERSION__ >= 201112L +#define noreturn _Noreturn +#else +#define noreturn __attribute__((noreturn)) +#endif +#endif + +#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func)                 \ +        static inline void func##p(type *p) {                   \ +                if (*p)                                         \ +                        func(*p);                               \ +        }                                                       \ +        struct __useless_struct_to_allow_trailing_semicolon__ + +#include "log.h" diff --git a/src/libsystemd-basic/include/systemd-basic/memfd-util.h b/src/libsystemd-basic/include/systemd-basic/memfd-util.h new file mode 100644 index 0000000000..46d4989e4c --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/memfd-util.h @@ -0,0 +1,36 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2013 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 <inttypes.h> +#include <stddef.h> +#include <stdint.h> +#include <sys/types.h> + +int memfd_new(const char *name); +int memfd_new_and_map(const char *name, size_t sz, void **p); + +int memfd_map(int fd, uint64_t offset, size_t size, void **p); + +int memfd_set_sealed(int fd); +int memfd_get_sealed(int fd); + +int memfd_get_size(int fd, uint64_t *sz); +int memfd_set_size(int fd, uint64_t sz); diff --git a/src/libsystemd-basic/include/systemd-basic/mempool.h b/src/libsystemd-basic/include/systemd-basic/mempool.h new file mode 100644 index 0000000000..0618b8dd22 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/mempool.h @@ -0,0 +1,47 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2011-2014 Lennart Poettering +  Copyright 2014 Michal Schmidt + +  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 <stddef.h> + +struct pool; + +struct mempool { +        struct pool *first_pool; +        void *freelist; +        size_t tile_size; +        unsigned at_least; +}; + +void* mempool_alloc_tile(struct mempool *mp); +void* mempool_alloc0_tile(struct mempool *mp); +void mempool_free_tile(struct mempool *mp, void *p); + +#define DEFINE_MEMPOOL(pool_name, tile_type, alloc_at_least) \ +static struct mempool pool_name = { \ +        .tile_size = sizeof(tile_type), \ +        .at_least = alloc_at_least, \ +} + + +#ifdef VALGRIND +void mempool_drop(struct mempool *mp); +#endif diff --git a/src/libsystemd-basic/include/systemd-basic/missing.h b/src/libsystemd-basic/include/systemd-basic/missing.h new file mode 100644 index 0000000000..85d086eb9b --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/missing.h @@ -0,0 +1,1082 @@ +#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/>. +***/ + +/* Missing glibc definitions to access certain kernel APIs */ + +#include <errno.h> +#include <fcntl.h> +#include <net/ethernet.h> +#include <stdlib.h> +#include <sys/resource.h> +#include <sys/syscall.h> +#include <uchar.h> +#include <unistd.h> + +#include <linux/audit.h> +#include <linux/capability.h> +#include <linux/if_link.h> +#include <linux/input.h> +#include <linux/loop.h> +#include <linux/neighbour.h> +#include <linux/oom.h> +#include <linux/rtnetlink.h> + +#ifdef HAVE_AUDIT +#include <libaudit.h> +#endif + +#ifdef ARCH_MIPS +#include <asm/sgidefs.h> +#endif + +#ifdef HAVE_LINUX_BTRFS_H +#include <linux/btrfs.h> +#endif + +#include "macro.h" + +#ifndef RLIMIT_RTTIME +#define RLIMIT_RTTIME 15 +#endif + +/* If RLIMIT_RTTIME is not defined, then we cannot use RLIMIT_NLIMITS as is */ +#define _RLIMIT_MAX (RLIMIT_RTTIME+1 > RLIMIT_NLIMITS ? RLIMIT_RTTIME+1 : RLIMIT_NLIMITS) + +#ifndef F_LINUX_SPECIFIC_BASE +#define F_LINUX_SPECIFIC_BASE 1024 +#endif + +#ifndef F_SETPIPE_SZ +#define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7) +#endif + +#ifndef F_GETPIPE_SZ +#define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8) +#endif + +#ifndef F_ADD_SEALS +#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9) +#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10) + +#define F_SEAL_SEAL     0x0001  /* prevent further seals from being set */ +#define F_SEAL_SHRINK   0x0002  /* prevent file from shrinking */ +#define F_SEAL_GROW     0x0004  /* prevent file from growing */ +#define F_SEAL_WRITE    0x0008  /* prevent writes */ +#endif + +#ifndef F_OFD_GETLK +#define F_OFD_GETLK     36 +#define F_OFD_SETLK     37 +#define F_OFD_SETLKW    38 +#endif + +#ifndef MFD_ALLOW_SEALING +#define MFD_ALLOW_SEALING 0x0002U +#endif + +#ifndef MFD_CLOEXEC +#define MFD_CLOEXEC 0x0001U +#endif + +#ifndef IP_FREEBIND +#define IP_FREEBIND 15 +#endif + +#ifndef OOM_SCORE_ADJ_MIN +#define OOM_SCORE_ADJ_MIN (-1000) +#endif + +#ifndef OOM_SCORE_ADJ_MAX +#define OOM_SCORE_ADJ_MAX 1000 +#endif + +#ifndef AUDIT_SERVICE_START +#define AUDIT_SERVICE_START 1130 /* Service (daemon) start */ +#endif + +#ifndef AUDIT_SERVICE_STOP +#define AUDIT_SERVICE_STOP 1131 /* Service (daemon) stop */ +#endif + +#ifndef TIOCVHANGUP +#define TIOCVHANGUP 0x5437 +#endif + +#ifndef IP_TRANSPARENT +#define IP_TRANSPARENT 19 +#endif + +#ifndef SOL_NETLINK +#define SOL_NETLINK 270 +#endif + +#ifndef NETLINK_LIST_MEMBERSHIPS +#define NETLINK_LIST_MEMBERSHIPS 9 +#endif + +#ifndef SOL_SCTP +#define SOL_SCTP 132 +#endif + +#ifndef GRND_NONBLOCK +#define GRND_NONBLOCK 0x0001 +#endif + +#ifndef GRND_RANDOM +#define GRND_RANDOM 0x0002 +#endif + +#ifndef BTRFS_IOCTL_MAGIC +#define BTRFS_IOCTL_MAGIC 0x94 +#endif + +#ifndef BTRFS_PATH_NAME_MAX +#define BTRFS_PATH_NAME_MAX 4087 +#endif + +#ifndef BTRFS_DEVICE_PATH_NAME_MAX +#define BTRFS_DEVICE_PATH_NAME_MAX 1024 +#endif + +#ifndef BTRFS_FSID_SIZE +#define BTRFS_FSID_SIZE 16 +#endif + +#ifndef BTRFS_UUID_SIZE +#define BTRFS_UUID_SIZE 16 +#endif + +#ifndef BTRFS_SUBVOL_RDONLY +#define BTRFS_SUBVOL_RDONLY (1ULL << 1) +#endif + +#ifndef BTRFS_SUBVOL_NAME_MAX +#define BTRFS_SUBVOL_NAME_MAX 4039 +#endif + +#ifndef BTRFS_INO_LOOKUP_PATH_MAX +#define BTRFS_INO_LOOKUP_PATH_MAX 4080 +#endif + +#ifndef BTRFS_SEARCH_ARGS_BUFSIZE +#define BTRFS_SEARCH_ARGS_BUFSIZE (4096 - sizeof(struct btrfs_ioctl_search_key)) +#endif + +#ifndef BTRFS_QGROUP_LEVEL_SHIFT +#define BTRFS_QGROUP_LEVEL_SHIFT 48 +#endif + +#ifndef HAVE_LINUX_BTRFS_H +struct btrfs_ioctl_vol_args { +        int64_t fd; +        char name[BTRFS_PATH_NAME_MAX + 1]; +}; + +struct btrfs_qgroup_limit { +        __u64 flags; +        __u64 max_rfer; +        __u64 max_excl; +        __u64 rsv_rfer; +        __u64 rsv_excl; +}; + +struct btrfs_qgroup_inherit { +        __u64 flags; +        __u64 num_qgroups; +        __u64 num_ref_copies; +        __u64 num_excl_copies; +        struct btrfs_qgroup_limit lim; +        __u64 qgroups[0]; +}; + +struct btrfs_ioctl_qgroup_limit_args { +        __u64 qgroupid; +        struct btrfs_qgroup_limit lim; +}; + +struct btrfs_ioctl_vol_args_v2 { +        __s64 fd; +        __u64 transid; +        __u64 flags; +        union { +                struct { +                        __u64 size; +                        struct btrfs_qgroup_inherit *qgroup_inherit; +                }; +                __u64 unused[4]; +        }; +        char name[BTRFS_SUBVOL_NAME_MAX + 1]; +}; + +struct btrfs_ioctl_dev_info_args { +        uint64_t devid;                         /* in/out */ +        uint8_t uuid[BTRFS_UUID_SIZE];          /* in/out */ +        uint64_t bytes_used;                    /* out */ +        uint64_t total_bytes;                   /* out */ +        uint64_t unused[379];                   /* pad to 4k */ +        char path[BTRFS_DEVICE_PATH_NAME_MAX];  /* out */ +}; + +struct btrfs_ioctl_fs_info_args { +        uint64_t max_id;                        /* out */ +        uint64_t num_devices;                   /* out */ +        uint8_t fsid[BTRFS_FSID_SIZE];          /* out */ +        uint64_t reserved[124];                 /* pad to 1k */ +}; + +struct btrfs_ioctl_ino_lookup_args { +        __u64 treeid; +        __u64 objectid; +        char name[BTRFS_INO_LOOKUP_PATH_MAX]; +}; + +struct btrfs_ioctl_search_key { +        /* which root are we searching.  0 is the tree of tree roots */ +        __u64 tree_id; + +        /* keys returned will be >= min and <= max */ +        __u64 min_objectid; +        __u64 max_objectid; + +        /* keys returned will be >= min and <= max */ +        __u64 min_offset; +        __u64 max_offset; + +        /* max and min transids to search for */ +        __u64 min_transid; +        __u64 max_transid; + +        /* keys returned will be >= min and <= max */ +        __u32 min_type; +        __u32 max_type; + +        /* +         * how many items did userland ask for, and how many are we +         * returning +         */ +        __u32 nr_items; + +        /* align to 64 bits */ +        __u32 unused; + +        /* some extra for later */ +        __u64 unused1; +        __u64 unused2; +        __u64 unused3; +        __u64 unused4; +}; + +struct btrfs_ioctl_search_header { +        __u64 transid; +        __u64 objectid; +        __u64 offset; +        __u32 type; +        __u32 len; +}; + + +struct btrfs_ioctl_search_args { +        struct btrfs_ioctl_search_key key; +        char buf[BTRFS_SEARCH_ARGS_BUFSIZE]; +}; + +struct btrfs_ioctl_clone_range_args { +        __s64 src_fd; +        __u64 src_offset, src_length; +        __u64 dest_offset; +}; + +#define BTRFS_QUOTA_CTL_ENABLE  1 +#define BTRFS_QUOTA_CTL_DISABLE 2 +#define BTRFS_QUOTA_CTL_RESCAN__NOTUSED 3 +struct btrfs_ioctl_quota_ctl_args { +        __u64 cmd; +        __u64 status; +}; +#endif + +#ifndef BTRFS_IOC_DEFRAG +#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \ +                                 struct btrfs_ioctl_vol_args) +#endif + +#ifndef BTRFS_IOC_RESIZE +#define BTRFS_IOC_RESIZE _IOW(BTRFS_IOCTL_MAGIC, 3, \ +                                 struct btrfs_ioctl_vol_args) +#endif + +#ifndef BTRFS_IOC_CLONE +#define BTRFS_IOC_CLONE _IOW(BTRFS_IOCTL_MAGIC, 9, int) +#endif + +#ifndef BTRFS_IOC_CLONE_RANGE +#define BTRFS_IOC_CLONE_RANGE _IOW(BTRFS_IOCTL_MAGIC, 13, \ +                                 struct btrfs_ioctl_clone_range_args) +#endif + +#ifndef BTRFS_IOC_SUBVOL_CREATE +#define BTRFS_IOC_SUBVOL_CREATE _IOW(BTRFS_IOCTL_MAGIC, 14, \ +                                 struct btrfs_ioctl_vol_args) +#endif + +#ifndef BTRFS_IOC_SNAP_DESTROY +#define BTRFS_IOC_SNAP_DESTROY _IOW(BTRFS_IOCTL_MAGIC, 15, \ +                                 struct btrfs_ioctl_vol_args) +#endif + +#ifndef BTRFS_IOC_TREE_SEARCH +#define BTRFS_IOC_TREE_SEARCH _IOWR(BTRFS_IOCTL_MAGIC, 17, \ +                                 struct btrfs_ioctl_search_args) +#endif + +#ifndef BTRFS_IOC_INO_LOOKUP +#define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, \ +                                 struct btrfs_ioctl_ino_lookup_args) +#endif + +#ifndef BTRFS_IOC_SNAP_CREATE_V2 +#define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \ +                                 struct btrfs_ioctl_vol_args_v2) +#endif + +#ifndef BTRFS_IOC_SUBVOL_GETFLAGS +#define BTRFS_IOC_SUBVOL_GETFLAGS _IOR(BTRFS_IOCTL_MAGIC, 25, __u64) +#endif + +#ifndef BTRFS_IOC_SUBVOL_SETFLAGS +#define BTRFS_IOC_SUBVOL_SETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 26, __u64) +#endif + +#ifndef BTRFS_IOC_DEV_INFO +#define BTRFS_IOC_DEV_INFO _IOWR(BTRFS_IOCTL_MAGIC, 30, \ +                                 struct btrfs_ioctl_dev_info_args) +#endif + +#ifndef BTRFS_IOC_FS_INFO +#define BTRFS_IOC_FS_INFO _IOR(BTRFS_IOCTL_MAGIC, 31, \ +                                 struct btrfs_ioctl_fs_info_args) +#endif + +#ifndef BTRFS_IOC_DEVICES_READY +#define BTRFS_IOC_DEVICES_READY _IOR(BTRFS_IOCTL_MAGIC, 39, \ +                                 struct btrfs_ioctl_vol_args) +#endif + +#ifndef BTRFS_IOC_QUOTA_CTL +#define BTRFS_IOC_QUOTA_CTL _IOWR(BTRFS_IOCTL_MAGIC, 40, \ +                               struct btrfs_ioctl_quota_ctl_args) +#endif + +#ifndef BTRFS_IOC_QGROUP_LIMIT +#define BTRFS_IOC_QGROUP_LIMIT _IOR(BTRFS_IOCTL_MAGIC, 43, \ +                               struct btrfs_ioctl_qgroup_limit_args) +#endif + +#ifndef BTRFS_IOC_QUOTA_RESCAN_WAIT +#define BTRFS_IOC_QUOTA_RESCAN_WAIT _IO(BTRFS_IOCTL_MAGIC, 46) +#endif + +#ifndef BTRFS_FIRST_FREE_OBJECTID +#define BTRFS_FIRST_FREE_OBJECTID 256 +#endif + +#ifndef BTRFS_LAST_FREE_OBJECTID +#define BTRFS_LAST_FREE_OBJECTID -256ULL +#endif + +#ifndef BTRFS_ROOT_TREE_OBJECTID +#define BTRFS_ROOT_TREE_OBJECTID 1 +#endif + +#ifndef BTRFS_QUOTA_TREE_OBJECTID +#define BTRFS_QUOTA_TREE_OBJECTID 8ULL +#endif + +#ifndef BTRFS_ROOT_ITEM_KEY +#define BTRFS_ROOT_ITEM_KEY 132 +#endif + +#ifndef BTRFS_QGROUP_STATUS_KEY +#define BTRFS_QGROUP_STATUS_KEY 240 +#endif + +#ifndef BTRFS_QGROUP_INFO_KEY +#define BTRFS_QGROUP_INFO_KEY 242 +#endif + +#ifndef BTRFS_QGROUP_LIMIT_KEY +#define BTRFS_QGROUP_LIMIT_KEY 244 +#endif + +#ifndef BTRFS_QGROUP_RELATION_KEY +#define BTRFS_QGROUP_RELATION_KEY 246 +#endif + +#ifndef BTRFS_ROOT_BACKREF_KEY +#define BTRFS_ROOT_BACKREF_KEY 144 +#endif + +#ifndef BTRFS_SUPER_MAGIC +#define BTRFS_SUPER_MAGIC 0x9123683E +#endif + +#ifndef CGROUP_SUPER_MAGIC +#define CGROUP_SUPER_MAGIC 0x27e0eb +#endif + +#ifndef CGROUP2_SUPER_MAGIC +#define CGROUP2_SUPER_MAGIC 0x63677270 +#endif + +#ifndef CLONE_NEWCGROUP +#define CLONE_NEWCGROUP 0x02000000 +#endif + +#ifndef TMPFS_MAGIC +#define TMPFS_MAGIC 0x01021994 +#endif + +#ifndef MQUEUE_MAGIC +#define MQUEUE_MAGIC 0x19800202 +#endif + +#ifndef SECURITYFS_MAGIC +#define SECURITYFS_MAGIC 0x73636673 +#endif + +#ifndef TRACEFS_MAGIC +#define TRACEFS_MAGIC 0x74726163 +#endif + +#ifndef BPF_FS_MAGIC +#define BPF_FS_MAGIC 0xcafe4a11 +#endif + +#ifndef MS_MOVE +#define MS_MOVE 8192 +#endif + +#ifndef MS_REC +#define MS_REC 16384 +#endif + +#ifndef MS_PRIVATE +#define MS_PRIVATE      (1<<18) +#endif + +#ifndef MS_REC +#define MS_REC          (1<<19) +#endif + +#ifndef MS_SHARED +#define MS_SHARED       (1<<20) +#endif + +#ifndef MS_RELATIME +#define MS_RELATIME     (1<<21) +#endif + +#ifndef MS_KERNMOUNT +#define MS_KERNMOUNT    (1<<22) +#endif + +#ifndef MS_I_VERSION +#define MS_I_VERSION    (1<<23) +#endif + +#ifndef MS_STRICTATIME +#define MS_STRICTATIME  (1<<24) +#endif + +#ifndef MS_LAZYTIME +#define MS_LAZYTIME     (1<<25) +#endif + +#ifndef SCM_SECURITY +#define SCM_SECURITY 0x03 +#endif + +#ifndef PR_SET_NO_NEW_PRIVS +#define PR_SET_NO_NEW_PRIVS 38 +#endif + +#ifndef PR_SET_CHILD_SUBREAPER +#define PR_SET_CHILD_SUBREAPER 36 +#endif + +#ifndef MAX_HANDLE_SZ +#define MAX_HANDLE_SZ 128 +#endif + +#ifndef HAVE_SECURE_GETENV +#  ifdef HAVE___SECURE_GETENV +#    define secure_getenv __secure_getenv +#  else +#    error "neither secure_getenv nor __secure_getenv are available" +#  endif +#endif + +#ifndef CIFS_MAGIC_NUMBER +#  define CIFS_MAGIC_NUMBER 0xFF534D42 +#endif + +#ifndef TFD_TIMER_CANCEL_ON_SET +#  define TFD_TIMER_CANCEL_ON_SET (1 << 1) +#endif + +#ifndef SO_REUSEPORT +#  define SO_REUSEPORT 15 +#endif + +#ifndef EVIOCREVOKE +#  define EVIOCREVOKE _IOW('E', 0x91, int) +#endif + +#ifndef DRM_IOCTL_SET_MASTER +#  define DRM_IOCTL_SET_MASTER _IO('d', 0x1e) +#endif + +#ifndef DRM_IOCTL_DROP_MASTER +#  define DRM_IOCTL_DROP_MASTER _IO('d', 0x1f) +#endif + +/* The precise definition of __O_TMPFILE is arch specific; use the + * values defined by the kernel (note: some are hexa, some are octal, + * duplicated as-is from the kernel definitions): + * - alpha, parisc, sparc: each has a specific value; + * - others: they use the "generic" value. + */ + +#ifndef __O_TMPFILE +#if defined(__alpha__) +#define __O_TMPFILE     0100000000 +#elif defined(__parisc__) || defined(__hppa__) +#define __O_TMPFILE     0400000000 +#elif defined(__sparc__) || defined(__sparc64__) +#define __O_TMPFILE     0x2000000 +#else +#define __O_TMPFILE     020000000 +#endif + +/* a horrid kludge trying to make sure that this will fail on old kernels */ +#ifndef O_TMPFILE +#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) +#endif + +#endif + +#if !HAVE_DECL_LO_FLAGS_PARTSCAN +#define LO_FLAGS_PARTSCAN 8 +#endif + +#ifndef LOOP_CTL_REMOVE +#define LOOP_CTL_REMOVE 0x4C81 +#endif + +#ifndef LOOP_CTL_GET_FREE +#define LOOP_CTL_GET_FREE 0x4C82 +#endif + +#if !HAVE_DECL_IFLA_INET6_ADDR_GEN_MODE +#define IFLA_INET6_UNSPEC 0 +#define IFLA_INET6_FLAGS 1 +#define IFLA_INET6_CONF 2 +#define IFLA_INET6_STATS 3 +#define IFLA_INET6_MCAST 4 +#define IFLA_INET6_CACHEINFO 5 +#define IFLA_INET6_ICMP6STATS 6 +#define IFLA_INET6_TOKEN 7 +#define IFLA_INET6_ADDR_GEN_MODE 8 +#define __IFLA_INET6_MAX 9 + +#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1) + +#define IN6_ADDR_GEN_MODE_EUI64 0 +#define IN6_ADDR_GEN_MODE_NONE 1 +#endif + +#if !HAVE_DECL_IN6_ADDR_GEN_MODE_STABLE_PRIVACY +#define IN6_ADDR_GEN_MODE_STABLE_PRIVACY 2 +#endif + +#if !HAVE_DECL_IFLA_MACVLAN_FLAGS +#define IFLA_MACVLAN_UNSPEC 0 +#define IFLA_MACVLAN_MODE 1 +#define IFLA_MACVLAN_FLAGS 2 +#define __IFLA_MACVLAN_MAX 3 + +#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1) +#endif + +#if !HAVE_DECL_IFLA_IPVLAN_MODE +#define IFLA_IPVLAN_UNSPEC 0 +#define IFLA_IPVLAN_MODE 1 +#define __IFLA_IPVLAN_MAX 2 + +#define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1) + +#define IPVLAN_MODE_L2 0 +#define IPVLAN_MODE_L3 1 +#define IPVLAN_MAX 2 +#endif + +#if !HAVE_DECL_IFLA_VTI_REMOTE +#define IFLA_VTI_UNSPEC 0 +#define IFLA_VTI_LINK 1 +#define IFLA_VTI_IKEY 2 +#define IFLA_VTI_OKEY 3 +#define IFLA_VTI_LOCAL 4 +#define IFLA_VTI_REMOTE 5 +#define __IFLA_VTI_MAX 6 + +#define IFLA_VTI_MAX (__IFLA_VTI_MAX - 1) +#endif + +#if !HAVE_DECL_IFLA_PHYS_PORT_ID +#define IFLA_EXT_MASK 29 +#undef IFLA_PROMISCUITY +#define IFLA_PROMISCUITY 30 +#define IFLA_NUM_TX_QUEUES 31 +#define IFLA_NUM_RX_QUEUES 32 +#define IFLA_CARRIER 33 +#define IFLA_PHYS_PORT_ID 34 +#define __IFLA_MAX 35 + +#define IFLA_MAX (__IFLA_MAX - 1) +#endif + +#if !HAVE_DECL_IFLA_BOND_AD_INFO +#define IFLA_BOND_UNSPEC 0 +#define IFLA_BOND_MODE 1 +#define IFLA_BOND_ACTIVE_SLAVE 2 +#define IFLA_BOND_MIIMON 3 +#define IFLA_BOND_UPDELAY 4 +#define IFLA_BOND_DOWNDELAY 5 +#define IFLA_BOND_USE_CARRIER 6 +#define IFLA_BOND_ARP_INTERVAL 7 +#define IFLA_BOND_ARP_IP_TARGET 8 +#define IFLA_BOND_ARP_VALIDATE 9 +#define IFLA_BOND_ARP_ALL_TARGETS 10 +#define IFLA_BOND_PRIMARY 11 +#define IFLA_BOND_PRIMARY_RESELECT 12 +#define IFLA_BOND_FAIL_OVER_MAC 13 +#define IFLA_BOND_XMIT_HASH_POLICY 14 +#define IFLA_BOND_RESEND_IGMP 15 +#define IFLA_BOND_NUM_PEER_NOTIF 16 +#define IFLA_BOND_ALL_SLAVES_ACTIVE 17 +#define IFLA_BOND_MIN_LINKS 18 +#define IFLA_BOND_LP_INTERVAL 19 +#define IFLA_BOND_PACKETS_PER_SLAVE 20 +#define IFLA_BOND_AD_LACP_RATE 21 +#define IFLA_BOND_AD_SELECT 22 +#define IFLA_BOND_AD_INFO 23 +#define __IFLA_BOND_MAX 24 + +#define IFLA_BOND_MAX   (__IFLA_BOND_MAX - 1) +#endif + +#if !HAVE_DECL_IFLA_VLAN_PROTOCOL +#define IFLA_VLAN_UNSPEC 0 +#define IFLA_VLAN_ID 1 +#define IFLA_VLAN_FLAGS 2 +#define IFLA_VLAN_EGRESS_QOS 3 +#define IFLA_VLAN_INGRESS_QOS 4 +#define IFLA_VLAN_PROTOCOL 5 +#define __IFLA_VLAN_MAX 6 + +#define IFLA_VLAN_MAX   (__IFLA_VLAN_MAX - 1) +#endif + +#if !HAVE_DECL_IFLA_VXLAN_REMCSUM_NOPARTIAL +#define IFLA_VXLAN_UNSPEC 0 +#define IFLA_VXLAN_ID 1 +#define IFLA_VXLAN_GROUP 2 +#define IFLA_VXLAN_LINK 3 +#define IFLA_VXLAN_LOCAL 4 +#define IFLA_VXLAN_TTL 5 +#define IFLA_VXLAN_TOS 6 +#define IFLA_VXLAN_LEARNING 7 +#define IFLA_VXLAN_AGEING 8 +#define IFLA_VXLAN_LIMIT 9 +#define IFLA_VXLAN_PORT_RANGE 10 +#define IFLA_VXLAN_PROXY 11 +#define IFLA_VXLAN_RSC 12 +#define IFLA_VXLAN_L2MISS 13 +#define IFLA_VXLAN_L3MISS 14 +#define IFLA_VXLAN_PORT 15 +#define IFLA_VXLAN_GROUP6 16 +#define IFLA_VXLAN_LOCAL6 17 +#define IFLA_VXLAN_UDP_CSUM 18 +#define IFLA_VXLAN_UDP_ZERO_CSUM6_TX 19 +#define IFLA_VXLAN_UDP_ZERO_CSUM6_RX 20 +#define IFLA_VXLAN_REMCSUM_TX 21 +#define IFLA_VXLAN_REMCSUM_RX 22 +#define IFLA_VXLAN_GBP 23 +#define IFLA_VXLAN_REMCSUM_NOPARTIAL 24 +#define __IFLA_VXLAN_MAX 25 + +#define IFLA_VXLAN_MAX  (__IFLA_VXLAN_MAX - 1) +#endif + +#if !HAVE_DECL_IFLA_IPTUN_ENCAP_DPORT +#define IFLA_IPTUN_UNSPEC 0 +#define IFLA_IPTUN_LINK 1 +#define IFLA_IPTUN_LOCAL 2 +#define IFLA_IPTUN_REMOTE 3 +#define IFLA_IPTUN_TTL 4 +#define IFLA_IPTUN_TOS 5 +#define IFLA_IPTUN_ENCAP_LIMIT 6 +#define IFLA_IPTUN_FLOWINFO 7 +#define IFLA_IPTUN_FLAGS 8 +#define IFLA_IPTUN_PROTO 9 +#define IFLA_IPTUN_PMTUDISC 10 +#define IFLA_IPTUN_6RD_PREFIX 11 +#define IFLA_IPTUN_6RD_RELAY_PREFIX 12 +#define IFLA_IPTUN_6RD_PREFIXLEN 13 +#define IFLA_IPTUN_6RD_RELAY_PREFIXLEN 14 +#define IFLA_IPTUN_ENCAP_TYPE 15 +#define IFLA_IPTUN_ENCAP_FLAGS 16 +#define IFLA_IPTUN_ENCAP_SPORT 17 +#define IFLA_IPTUN_ENCAP_DPORT 18 + +#define __IFLA_IPTUN_MAX 19 + +#define IFLA_IPTUN_MAX  (__IFLA_IPTUN_MAX - 1) +#endif + +#if !HAVE_DECL_IFLA_GRE_ENCAP_DPORT +#define IFLA_GRE_UNSPEC 0 +#define IFLA_GRE_LINK 1 +#define IFLA_GRE_IFLAGS 2 +#define IFLA_GRE_OFLAGS 3 +#define IFLA_GRE_IKEY 4 +#define IFLA_GRE_OKEY 5 +#define IFLA_GRE_LOCAL 6 +#define IFLA_GRE_REMOTE 7 +#define IFLA_GRE_TTL 8 +#define IFLA_GRE_TOS 9 +#define IFLA_GRE_PMTUDISC 10 +#define IFLA_GRE_ENCAP_LIMIT 11 +#define IFLA_GRE_FLOWINFO 12 +#define IFLA_GRE_FLAGS 13 +#define IFLA_GRE_ENCAP_TYPE 14 +#define IFLA_GRE_ENCAP_FLAGS 15 +#define IFLA_GRE_ENCAP_SPORT 16 +#define IFLA_GRE_ENCAP_DPORT 17 + +#define __IFLA_GRE_MAX 18 + +#define IFLA_GRE_MAX  (__IFLA_GRE_MAX - 1) +#endif + +#if !HAVE_DECL_IFLA_BRIDGE_VLAN_INFO +#define IFLA_BRIDGE_FLAGS 0 +#define IFLA_BRIDGE_MODE 1 +#define IFLA_BRIDGE_VLAN_INFO 2 +#define __IFLA_BRIDGE_MAX 3 + +#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1) +#endif + +#ifndef BRIDGE_VLAN_INFO_RANGE_BEGIN +#define BRIDGE_VLAN_INFO_RANGE_BEGIN (1<<3) /* VLAN is start of vlan range */ +#endif + +#ifndef BRIDGE_VLAN_INFO_RANGE_END +#define BRIDGE_VLAN_INFO_RANGE_END (1<<4) /* VLAN is end of vlan range */ +#endif + +#if !HAVE_DECL_IFLA_BR_VLAN_DEFAULT_PVID +#define IFLA_BR_UNSPEC 0 +#define IFLA_BR_FORWARD_DELAY 1 +#define IFLA_BR_HELLO_TIME 2 +#define IFLA_BR_MAX_AGE 3 +#define IFLA_BR_AGEING_TIME 4 +#define IFLA_BR_STP_STATE 5 +#define IFLA_BR_PRIORITY 6 +#define IFLA_BR_VLAN_FILTERING 7 +#define IFLA_BR_VLAN_PROTOCOL 8 +#define IFLA_BR_GROUP_FWD_MASK 9 +#define IFLA_BR_ROOT_ID 10 +#define IFLA_BR_BRIDGE_ID 11 +#define IFLA_BR_ROOT_PORT 12 +#define IFLA_BR_ROOT_PATH_COST 13 +#define IFLA_BR_TOPOLOGY_CHANGE 14 +#define IFLA_BR_TOPOLOGY_CHANGE_DETECTED 15 +#define IFLA_BR_HELLO_TIMER 16 +#define IFLA_BR_TCN_TIMER 17 +#define IFLA_BR_TOPOLOGY_CHANGE_TIMER 18 +#define IFLA_BR_GC_TIMER 19 +#define IFLA_BR_GROUP_ADDR 20 +#define IFLA_BR_FDB_FLUSH 21 +#define IFLA_BR_MCAST_ROUTER 22 +#define IFLA_BR_MCAST_SNOOPING 23 +#define IFLA_BR_MCAST_QUERY_USE_IFADDR 24 +#define IFLA_BR_MCAST_QUERIER 25 +#define IFLA_BR_MCAST_HASH_ELASTICITY 26 +#define IFLA_BR_MCAST_HASH_MAX 27 +#define IFLA_BR_MCAST_LAST_MEMBER_CNT 28 +#define IFLA_BR_MCAST_STARTUP_QUERY_CNT 29 +#define IFLA_BR_MCAST_LAST_MEMBER_INTVL 30 +#define IFLA_BR_MCAST_MEMBERSHIP_INTVL 31 +#define IFLA_BR_MCAST_QUERIER_INTVL 32 +#define IFLA_BR_MCAST_QUERY_INTVL 33 +#define IFLA_BR_MCAST_QUERY_RESPONSE_INTVL 34 +#define IFLA_BR_MCAST_STARTUP_QUERY_INTVL 35 +#define IFLA_BR_NF_CALL_IPTABLES 36 +#define IFLA_BR_NF_CALL_IP6TABLES 37 +#define IFLA_BR_NF_CALL_ARPTABLES 38 +#define IFLA_BR_VLAN_DEFAULT_PVID 39 +#define __IFLA_BR_MAX 40 + +#define IFLA_BR_MAX (__IFLA_BR_MAX - 1) +#endif + +#if !HAVE_DECL_IFLA_BRPORT_LEARNING_SYNC +#define IFLA_BRPORT_UNSPEC 0 +#define IFLA_BRPORT_STATE 1 +#define IFLA_BRPORT_PRIORITY 2 +#define IFLA_BRPORT_COST 3 +#define IFLA_BRPORT_MODE 4 +#define IFLA_BRPORT_GUARD 5 +#define IFLA_BRPORT_PROTECT 6 +#define IFLA_BRPORT_FAST_LEAVE 7 +#define IFLA_BRPORT_LEARNING 8 +#define IFLA_BRPORT_UNICAST_FLOOD 9 +#define IFLA_BRPORT_LEARNING_SYNC 11 +#define __IFLA_BRPORT_MAX 12 + +#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) +#endif + +#if !HAVE_DECL_IFLA_BRPORT_PROXYARP +#define IFLA_BRPORT_PROXYARP 10 +#endif + +#if !HAVE_DECL_IFLA_VRF_TABLE +#define IFLA_VRF_TABLE 1 +#endif + +#if !HAVE_DECL_NDA_IFINDEX +#define NDA_UNSPEC 0 +#define NDA_DST 1 +#define NDA_LLADDR 2 +#define NDA_CACHEINFO 3 +#define NDA_PROBES 4 +#define NDA_VLAN 5 +#define NDA_PORT 6 +#define NDA_VNI 7 +#define NDA_IFINDEX 8 +#define __NDA_MAX 9 + +#define NDA_MAX (__NDA_MAX - 1) +#endif + +#ifndef RTA_PREF +#define RTA_PREF 20 +#endif + +#ifndef IPV6_UNICAST_IF +#define IPV6_UNICAST_IF 76 +#endif + +#ifndef IPV6_MIN_MTU +#define IPV6_MIN_MTU 1280 +#endif + +#ifndef IFF_MULTI_QUEUE +#define IFF_MULTI_QUEUE 0x100 +#endif + +#ifndef IFF_LOWER_UP +#define IFF_LOWER_UP 0x10000 +#endif + +#ifndef IFF_DORMANT +#define IFF_DORMANT 0x20000 +#endif + +#ifndef BOND_XMIT_POLICY_ENCAP23 +#define BOND_XMIT_POLICY_ENCAP23 3 +#endif + +#ifndef BOND_XMIT_POLICY_ENCAP34 +#define BOND_XMIT_POLICY_ENCAP34 4 +#endif + +#ifndef NET_ADDR_RANDOM +#  define NET_ADDR_RANDOM 1 +#endif + +#ifndef NET_NAME_UNKNOWN +#  define NET_NAME_UNKNOWN 0 +#endif + +#ifndef NET_NAME_ENUM +#  define NET_NAME_ENUM 1 +#endif + +#ifndef NET_NAME_PREDICTABLE +#  define NET_NAME_PREDICTABLE 2 +#endif + +#ifndef NET_NAME_USER +#  define NET_NAME_USER 3 +#endif + +#ifndef NET_NAME_RENAMED +#  define NET_NAME_RENAMED 4 +#endif + +#ifndef BPF_XOR +#  define BPF_XOR 0xa0 +#endif + +/* Note that LOOPBACK_IFINDEX is currently not exported by the + * kernel/glibc, but hardcoded internally by the kernel.  However, as + * it is exported to userspace indirectly via rtnetlink and the + * ioctls, and made use of widely we define it here too, in a way that + * is compatible with the kernel's internal definition. */ +#ifndef LOOPBACK_IFINDEX +#define LOOPBACK_IFINDEX 1 +#endif + +#if !HAVE_DECL_IFA_FLAGS +#define IFA_FLAGS 8 +#endif + +#ifndef IFA_F_MANAGETEMPADDR +#define IFA_F_MANAGETEMPADDR 0x100 +#endif + +#ifndef IFA_F_NOPREFIXROUTE +#define IFA_F_NOPREFIXROUTE 0x200 +#endif + +#ifndef MAX_AUDIT_MESSAGE_LENGTH +#define MAX_AUDIT_MESSAGE_LENGTH 8970 +#endif + +#ifndef AUDIT_NLGRP_MAX +#define AUDIT_NLGRP_READLOG 1 +#endif + +#ifndef CAP_MAC_OVERRIDE +#define CAP_MAC_OVERRIDE 32 +#endif + +#ifndef CAP_MAC_ADMIN +#define CAP_MAC_ADMIN 33 +#endif + +#ifndef CAP_SYSLOG +#define CAP_SYSLOG 34 +#endif + +#ifndef CAP_WAKE_ALARM +#define CAP_WAKE_ALARM 35 +#endif + +#ifndef CAP_BLOCK_SUSPEND +#define CAP_BLOCK_SUSPEND 36 +#endif + +#ifndef CAP_AUDIT_READ +#define CAP_AUDIT_READ 37 +#endif + +#ifndef RENAME_NOREPLACE +#define RENAME_NOREPLACE (1 << 0) +#endif + +#ifndef KCMP_FILE +#define KCMP_FILE 0 +#endif + +#ifndef INPUT_PROP_POINTING_STICK +#define INPUT_PROP_POINTING_STICK 0x05 +#endif + +#ifndef INPUT_PROP_ACCELEROMETER +#define INPUT_PROP_ACCELEROMETER  0x06 +#endif + +#ifndef HAVE_KEY_SERIAL_T +typedef int32_t key_serial_t; +#endif + +#ifndef KEYCTL_READ +#define KEYCTL_READ 11 +#endif + +#ifndef KEYCTL_SET_TIMEOUT +#define KEYCTL_SET_TIMEOUT 15 +#endif + +#ifndef KEY_SPEC_USER_KEYRING +#define KEY_SPEC_USER_KEYRING -4 +#endif + +#ifndef PR_CAP_AMBIENT +#define PR_CAP_AMBIENT 47 +#endif + +#ifndef PR_CAP_AMBIENT_IS_SET +#define PR_CAP_AMBIENT_IS_SET 1 +#endif + +#ifndef PR_CAP_AMBIENT_RAISE +#define PR_CAP_AMBIENT_RAISE 2 +#endif + +#ifndef PR_CAP_AMBIENT_CLEAR_ALL +#define PR_CAP_AMBIENT_CLEAR_ALL 4 +#endif + +/* The following two defines are actually available in the kernel headers for longer, but we define them here anyway, + * since that makes it easier to use them in conjunction with the glibc net/if.h header which conflicts with + * linux/if.h. */ +#ifndef IF_OPER_UNKNOWN +#define IF_OPER_UNKNOWN 0 +#endif + +#ifndef IF_OPER_UP +#define IF_OPER_UP 6 + +#ifndef HAVE_CHAR32_T +#define char32_t uint32_t +#endif + +#ifndef HAVE_CHAR16_T +#define char16_t uint16_t +#endif + +#ifndef ETHERTYPE_LLDP +#define ETHERTYPE_LLDP 0x88cc +#endif + +#ifndef IFA_F_MCAUTOJOIN +#define IFA_F_MCAUTOJOIN 0x400 +#endif + +#endif + +#include "missing_syscall.h" diff --git a/src/libsystemd-basic/include/systemd-basic/missing_syscall.h b/src/libsystemd-basic/include/systemd-basic/missing_syscall.h new file mode 100644 index 0000000000..e6fd67cb9d --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/missing_syscall.h @@ -0,0 +1,300 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2010 Lennart Poettering +  Copyright 2016 Zbigniew JÄ™drzejewski-Szmek + +  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/>. +***/ + +/* Missing glibc definitions to access certain kernel APIs */ + +#if !HAVE_DECL_PIVOT_ROOT +static inline int pivot_root(const char *new_root, const char *put_old) { +        return syscall(SYS_pivot_root, new_root, put_old); +} +#endif + +/* ======================================================================= */ + +#if !HAVE_DECL_MEMFD_CREATE +#  ifndef __NR_memfd_create +#    if defined __x86_64__ +#      define __NR_memfd_create 319 +#    elif defined __arm__ +#      define __NR_memfd_create 385 +#    elif defined __aarch64__ +#      define __NR_memfd_create 279 +#    elif defined __s390__ +#      define __NR_memfd_create 350 +#    elif defined _MIPS_SIM +#      if _MIPS_SIM == _MIPS_SIM_ABI32 +#        define __NR_memfd_create 4354 +#      endif +#      if _MIPS_SIM == _MIPS_SIM_NABI32 +#        define __NR_memfd_create 6318 +#      endif +#      if _MIPS_SIM == _MIPS_SIM_ABI64 +#        define __NR_memfd_create 5314 +#      endif +#    elif defined __i386__ +#      define __NR_memfd_create 356 +#    else +#      warning "__NR_memfd_create unknown for your architecture" +#    endif +#  endif + +static inline int memfd_create(const char *name, unsigned int flags) { +#  ifdef __NR_memfd_create +        return syscall(__NR_memfd_create, name, flags); +#  else +        errno = ENOSYS; +        return -1; +#  endif +} +#endif + +/* ======================================================================= */ + +#if !HAVE_DECL_GETRANDOM +#  ifndef __NR_getrandom +#    if defined __x86_64__ +#      define __NR_getrandom 318 +#    elif defined(__i386__) +#      define __NR_getrandom 355 +#    elif defined(__arm__) +#      define __NR_getrandom 384 +#   elif defined(__aarch64__) +#      define __NR_getrandom 278 +#    elif defined(__ia64__) +#      define __NR_getrandom 1339 +#    elif defined(__m68k__) +#      define __NR_getrandom 352 +#    elif defined(__s390x__) +#      define __NR_getrandom 349 +#    elif defined(__powerpc__) +#      define __NR_getrandom 359 +#    elif defined _MIPS_SIM +#      if _MIPS_SIM == _MIPS_SIM_ABI32 +#        define __NR_getrandom 4353 +#      endif +#      if _MIPS_SIM == _MIPS_SIM_NABI32 +#        define __NR_getrandom 6317 +#      endif +#      if _MIPS_SIM == _MIPS_SIM_ABI64 +#        define __NR_getrandom 5313 +#      endif +#    else +#      warning "__NR_getrandom unknown for your architecture" +#    endif +#  endif + +static inline int getrandom(void *buffer, size_t count, unsigned flags) { +#  ifdef __NR_getrandom +        return syscall(__NR_getrandom, buffer, count, flags); +#  else +        errno = ENOSYS; +        return -1; +#  endif +} +#endif + +/* ======================================================================= */ + +#if !HAVE_DECL_GETTID +static inline pid_t gettid(void) { +        return (pid_t) syscall(SYS_gettid); +} +#endif + +/* ======================================================================= */ + +#if !HAVE_DECL_NAME_TO_HANDLE_AT +#  ifndef __NR_name_to_handle_at +#    if defined(__x86_64__) +#      define __NR_name_to_handle_at 303 +#    elif defined(__i386__) +#      define __NR_name_to_handle_at 341 +#    elif defined(__arm__) +#      define __NR_name_to_handle_at 370 +#    elif defined(__powerpc__) +#      define __NR_name_to_handle_at 345 +#    else +#      error "__NR_name_to_handle_at is not defined" +#    endif +#  endif + +struct file_handle { +        unsigned int handle_bytes; +        int handle_type; +        unsigned char f_handle[0]; +}; + +static inline int name_to_handle_at(int fd, const char *name, struct file_handle *handle, int *mnt_id, int flags) { +#  ifdef __NR_name_to_handle_at +        return syscall(__NR_name_to_handle_at, fd, name, handle, mnt_id, flags); +#  else +        errno = ENOSYS; +        return -1; +#  endif +} +#endif + +/* ======================================================================= */ + +#if !HAVE_DECL_SETNS +#  ifndef __NR_setns +#    if defined(__x86_64__) +#      define __NR_setns 308 +#    elif defined(__i386__) +#      define __NR_setns 346 +#    else +#      error "__NR_setns is not defined" +#    endif +#  endif + +static inline int setns(int fd, int nstype) { +#  ifdef __NR_setns +        return syscall(__NR_setns, fd, nstype); +#  else +        errno = ENOSYS; +        return -1; +#  endif +} +#endif + +/* ======================================================================= */ + +static inline pid_t raw_getpid(void) { +#if defined(__alpha__) +        return (pid_t) syscall(__NR_getxpid); +#else +        return (pid_t) syscall(__NR_getpid); +#endif +} + +/* ======================================================================= */ + +#if !HAVE_DECL_RENAMEAT2 +#  ifndef __NR_renameat2 +#    if defined __x86_64__ +#      define __NR_renameat2 316 +#    elif defined __arm__ +#      define __NR_renameat2 382 +#    elif defined _MIPS_SIM +#      if _MIPS_SIM == _MIPS_SIM_ABI32 +#        define __NR_renameat2 4351 +#      endif +#      if _MIPS_SIM == _MIPS_SIM_NABI32 +#        define __NR_renameat2 6315 +#      endif +#      if _MIPS_SIM == _MIPS_SIM_ABI64 +#        define __NR_renameat2 5311 +#      endif +#    elif defined __i386__ +#      define __NR_renameat2 353 +#    else +#      warning "__NR_renameat2 unknown for your architecture" +#    endif +#  endif + +static inline int renameat2(int oldfd, const char *oldname, int newfd, const char *newname, unsigned flags) { +#  ifdef __NR_renameat2 +        return syscall(__NR_renameat2, oldfd, oldname, newfd, newname, flags); +#  else +        errno = ENOSYS; +        return -1; +#  endif +} +#endif + +/* ======================================================================= */ + +#if !HAVE_DECL_KCMP +static inline int kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) { +#  ifdef __NR_kcmp +        return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2); +#  else +        errno = ENOSYS; +        return -1; +#  endif +} +#endif + +/* ======================================================================= */ + +#if !HAVE_DECL_KEYCTL +static inline long keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4,unsigned long arg5) { +#  ifdef __NR_keyctl +        return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5); +#  else +        errno = ENOSYS; +        return -1; +#  endif +} + +static inline key_serial_t add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid) { +#  ifdef __NR_add_key +        return syscall(__NR_add_key, type, description, payload, plen, ringid); +#  else +        errno = ENOSYS; +        return -1; +#  endif +} + +static inline key_serial_t request_key(const char *type, const char *description, const char * callout_info, key_serial_t destringid) { +#  ifdef __NR_request_key +        return syscall(__NR_request_key, type, description, callout_info, destringid); +#  else +        errno = ENOSYS; +        return -1; +#  endif +} +#endif + +/* ======================================================================= */ + +#if !HAVE_DECL_COPY_FILE_RANGE +#  ifndef __NR_copy_file_range +#    if defined(__x86_64__) +#      define __NR_copy_file_range 326 +#    elif defined(__i386__) +#      define __NR_copy_file_range 377 +#    elif defined __s390__ +#      define __NR_copy_file_range 375 +#    elif defined __arm__ +#      define __NR_copy_file_range 391 +#    elif defined __aarch64__ +#      define __NR_copy_file_range 285 +#    elif defined __powerpc__ +#      define __NR_copy_file_range 379 +#    else +#      warning "__NR_copy_file_range not defined for your architecture" +#    endif +#  endif + +static inline ssize_t copy_file_range(int fd_in, loff_t *off_in, +                                      int fd_out, loff_t *off_out, +                                      size_t len, +                                      unsigned int flags) { +#  ifdef __NR_copy_file_range +        return syscall(__NR_copy_file_range, fd_in, off_in, fd_out, off_out, len, flags); +#  else +        errno = ENOSYS; +        return -1; +#  endif +} +#endif diff --git a/src/libsystemd-basic/include/systemd-basic/mkdir.h b/src/libsystemd-basic/include/systemd-basic/mkdir.h new file mode 100644 index 0000000000..d564a3547f --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/mkdir.h @@ -0,0 +1,38 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2010 Lennart Poettering +  Copyright 2013 Kay Sievers + +  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/types.h> + +int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid); +int mkdir_parents(const char *path, mode_t mode); +int mkdir_p(const char *path, mode_t mode); + +/* mandatory access control(MAC) versions */ +int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid); +int mkdir_parents_label(const char *path, mode_t mode); +int mkdir_p_label(const char *path, mode_t mode); + +/* internally used */ +typedef int (*mkdir_func_t)(const char *pathname, mode_t mode); +int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkdir_func_t _mkdir); +int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir); +int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir); diff --git a/src/libsystemd-basic/include/systemd-basic/mount-util.h b/src/libsystemd-basic/include/systemd-basic/mount-util.h new file mode 100644 index 0000000000..4f305df19f --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/mount-util.h @@ -0,0 +1,63 @@ +#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 <fcntl.h> +#include <mntent.h> +#include <stdbool.h> +#include <stdio.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include "macro.h" +#include "missing.h" + +int fd_is_mount_point(int fd, const char *filename, int flags); +int path_is_mount_point(const char *path, int flags); + +int repeat_unmount(const char *path, int flags); + +int umount_recursive(const char *target, int flags); +int bind_remount_recursive(const char *prefix, bool ro, char **blacklist); + +int mount_move_root(const char *path); + +DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, endmntent); +#define _cleanup_endmntent_ _cleanup_(endmntentp) + +bool fstype_is_network(const char *fstype); + +union file_handle_union { +        struct file_handle handle; +        char padding[sizeof(struct file_handle) + MAX_HANDLE_SZ]; +}; + +const char* mode_to_inaccessible_node(mode_t mode); + +#define FILE_HANDLE_INIT { .handle.handle_bytes = MAX_HANDLE_SZ } + +int mount_verbose( +                int error_log_level, +                const char *what, +                const char *where, +                const char *type, +                unsigned long flags, +                const char *options); +int umount_verbose(const char *where); diff --git a/src/libsystemd-basic/include/systemd-basic/nss-util.h b/src/libsystemd-basic/include/systemd-basic/nss-util.h new file mode 100644 index 0000000000..e7844fff96 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/nss-util.h @@ -0,0 +1,199 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2014 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 <grp.h> +#include <netdb.h> +#include <nss.h> +#include <pwd.h> +#include <resolv.h> + +#define NSS_SIGNALS_BLOCK SIGALRM,SIGVTALRM,SIGPIPE,SIGCHLD,SIGTSTP,SIGIO,SIGHUP,SIGUSR1,SIGUSR2,SIGPROF,SIGURG,SIGWINCH + +#define NSS_GETHOSTBYNAME_PROTOTYPES(module)            \ +enum nss_status _nss_##module##_gethostbyname4_r(       \ +                const char *name,                       \ +                struct gaih_addrtuple **pat,            \ +                char *buffer, size_t buflen,            \ +                int *errnop, int *h_errnop,             \ +                int32_t *ttlp) _public_;                \ +enum nss_status _nss_##module##_gethostbyname3_r(       \ +                const char *name,                       \ +                int af,                                 \ +                struct hostent *host,                   \ +                char *buffer, size_t buflen,            \ +                int *errnop, int *h_errnop,             \ +                int32_t *ttlp,                          \ +                char **canonp) _public_;                \ +enum nss_status _nss_##module##_gethostbyname2_r(       \ +                const char *name,                       \ +                int af,                                 \ +                struct hostent *host,                   \ +                char *buffer, size_t buflen,            \ +                int *errnop, int *h_errnop) _public_;   \ +enum nss_status _nss_##module##_gethostbyname_r(        \ +                const char *name,                       \ +                struct hostent *host,                   \ +                char *buffer, size_t buflen,            \ +                int *errnop, int *h_errnop) _public_ + +#define NSS_GETHOSTBYADDR_PROTOTYPES(module)            \ +enum nss_status _nss_##module##_gethostbyaddr2_r(       \ +                const void* addr, socklen_t len,        \ +                int af,                                 \ +                struct hostent *host,                   \ +                char *buffer, size_t buflen,            \ +                int *errnop, int *h_errnop,             \ +                int32_t *ttlp) _public_;                \ +enum nss_status _nss_##module##_gethostbyaddr_r(        \ +                const void* addr, socklen_t len,        \ +                int af,                                 \ +                struct hostent *host,                   \ +                char *buffer, size_t buflen,            \ +                int *errnop, int *h_errnop) _public_ + +#define NSS_GETHOSTBYNAME_FALLBACKS(module)             \ +enum nss_status _nss_##module##_gethostbyname2_r(       \ +                const char *name,                       \ +                int af,                                 \ +                struct hostent *host,                   \ +                char *buffer, size_t buflen,            \ +                int *errnop, int *h_errnop) {           \ +        return _nss_##module##_gethostbyname3_r(        \ +                        name,                           \ +                        af,                             \ +                        host,                           \ +                        buffer, buflen,                 \ +                        errnop, h_errnop,               \ +                        NULL,                           \ +                        NULL);                          \ +}                                                       \ +enum nss_status _nss_##module##_gethostbyname_r(        \ +                const char *name,                       \ +                struct hostent *host,                   \ +                char *buffer, size_t buflen,            \ +                int *errnop, int *h_errnop) {           \ +        enum nss_status ret = NSS_STATUS_NOTFOUND;      \ +                                                        \ +        if (_res.options & RES_USE_INET6)               \ +                ret = _nss_##module##_gethostbyname3_r( \ +                        name,                           \ +                        AF_INET6,                       \ +                        host,                           \ +                        buffer, buflen,                 \ +                        errnop, h_errnop,               \ +                        NULL,                           \ +                        NULL);                          \ +        if (ret == NSS_STATUS_NOTFOUND)                 \ +                ret = _nss_##module##_gethostbyname3_r( \ +                        name,                           \ +                        AF_INET,                        \ +                        host,                           \ +                        buffer, buflen,                 \ +                        errnop, h_errnop,               \ +                        NULL,                           \ +                        NULL);                          \ +       return ret;                                      \ +}                                                       \ +struct __useless_struct_to_allow_trailing_semicolon__ + +#define NSS_GETHOSTBYADDR_FALLBACKS(module)             \ +enum nss_status _nss_##module##_gethostbyaddr_r(        \ +                const void* addr, socklen_t len,        \ +                int af,                                 \ +                struct hostent *host,                   \ +                char *buffer, size_t buflen,            \ +                int *errnop, int *h_errnop) {           \ +        return _nss_##module##_gethostbyaddr2_r(        \ +                        addr, len,                      \ +                        af,                             \ +                        host,                           \ +                        buffer, buflen,                 \ +                        errnop, h_errnop,               \ +                        NULL);                          \ +}                                                       \ +struct __useless_struct_to_allow_trailing_semicolon__ + +#define NSS_GETPW_PROTOTYPES(module)                    \ +enum nss_status _nss_##module##_getpwnam_r(             \ +                const char *name,                       \ +                struct passwd *pwd,                     \ +                char *buffer, size_t buflen,            \ +                int *errnop) _public_;                  \ +enum nss_status _nss_##module##_getpwuid_r(             \ +                uid_t uid,                              \ +                struct passwd *pwd,                     \ +                char *buffer, size_t buflen,            \ +                int *errnop) _public_ + +#define NSS_GETGR_PROTOTYPES(module)                    \ +enum nss_status _nss_##module##_getgrnam_r(             \ +                const char *name,                       \ +                struct group *gr,                       \ +                char *buffer, size_t buflen,            \ +                int *errnop) _public_;                  \ +enum nss_status _nss_##module##_getgrgid_r(             \ +                gid_t gid,                              \ +                struct group *gr,                       \ +                char *buffer, size_t buflen,            \ +                int *errnop) _public_ + +typedef enum nss_status (*_nss_gethostbyname4_r_t)( +                const char *name, +                struct gaih_addrtuple **pat, +                char *buffer, size_t buflen, +                int *errnop, int *h_errnop, +                int32_t *ttlp); + +typedef enum nss_status (*_nss_gethostbyname3_r_t)( +                const char *name, +                int af, +                struct hostent *result, +                char *buffer, size_t buflen, +                int *errnop, int *h_errnop, +                int32_t *ttlp, +                char **canonp); + +typedef enum nss_status (*_nss_gethostbyname2_r_t)( +                const char *name, +                int af, +                struct hostent *result, +                char *buffer, size_t buflen, +                int *errnop, int *h_errnop); + +typedef enum nss_status (*_nss_gethostbyname_r_t)( +                const char *name, +                struct hostent *result, +                char *buffer, size_t buflen, +                int *errnop, int *h_errnop); + +typedef enum nss_status (*_nss_gethostbyaddr2_r_t)( +                const void* addr, socklen_t len, +                int af, +                struct hostent *result, +                char *buffer, size_t buflen, +                int *errnop, int *h_errnop, +                int32_t *ttlp); +typedef enum nss_status (*_nss_gethostbyaddr_r_t)( +                const void* addr, socklen_t len, +                int af, +                struct hostent *host, +                char *buffer, size_t buflen, +                int *errnop, int *h_errnop); diff --git a/src/libsystemd-basic/include/systemd-basic/ordered-set.h b/src/libsystemd-basic/include/systemd-basic/ordered-set.h new file mode 100644 index 0000000000..e1dfc86380 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/ordered-set.h @@ -0,0 +1,74 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2015 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 "hashmap.h" + +typedef struct OrderedSet OrderedSet; + +static inline OrderedSet* ordered_set_new(const struct hash_ops *ops) { +        return (OrderedSet*) ordered_hashmap_new(ops); +} + +static inline int ordered_set_ensure_allocated(OrderedSet **s, const struct hash_ops *ops) { +        if (*s) +                return 0; + +        *s = ordered_set_new(ops); +        if (!*s) +                return -ENOMEM; + +        return 0; +} + +static inline OrderedSet* ordered_set_free(OrderedSet *s) { +        ordered_hashmap_free((OrderedHashmap*) s); +        return NULL; +} + +static inline OrderedSet* ordered_set_free_free(OrderedSet *s) { +        ordered_hashmap_free_free((OrderedHashmap*) s); +        return NULL; +} + +static inline int ordered_set_put(OrderedSet *s, void *p) { +        return ordered_hashmap_put((OrderedHashmap*) s, p, p); +} + +static inline bool ordered_set_isempty(OrderedSet *s) { +        return ordered_hashmap_isempty((OrderedHashmap*) s); +} + +static inline bool ordered_set_iterate(OrderedSet *s, Iterator *i, void **value) { +        return ordered_hashmap_iterate((OrderedHashmap*) s, i, value, NULL); +} + +int ordered_set_consume(OrderedSet *s, void *p); +int ordered_set_put_strdup(OrderedSet *s, const char *p); +int ordered_set_put_strdupv(OrderedSet *s, char **l); + +#define ORDERED_SET_FOREACH(e, s, i)                                    \ +        for ((i) = ITERATOR_FIRST; ordered_set_iterate((s), &(i), (void**)&(e)); ) + +DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedSet*, ordered_set_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedSet*, ordered_set_free_free); + +#define _cleanup_ordered_set_free_ _cleanup_(ordered_set_freep) +#define _cleanup_ordered_set_free_free_ _cleanup_(ordered_set_free_freep) diff --git a/src/libsystemd-basic/include/systemd-basic/parse-util.h b/src/libsystemd-basic/include/systemd-basic/parse-util.h new file mode 100644 index 0000000000..461e1cd4d8 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/parse-util.h @@ -0,0 +1,112 @@ +#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 <inttypes.h> +#include <limits.h> +#include <stddef.h> +#include <stdint.h> +#include <sys/types.h> + +#include "macro.h" + +#define MODE_INVALID ((mode_t) -1) + +int parse_boolean(const char *v) _pure_; +int parse_pid(const char *s, pid_t* ret_pid); +int parse_mode(const char *s, mode_t *ret); +int parse_ifindex(const char *s, int *ret); + +int parse_size(const char *t, uint64_t base, uint64_t *size); +int parse_range(const char *t, unsigned *lower, unsigned *upper); + +#define FORMAT_BYTES_MAX 8 +char *format_bytes(char *buf, size_t l, uint64_t t); + +int safe_atou(const char *s, unsigned *ret_u); +int safe_atoi(const char *s, int *ret_i); +int safe_atollu(const char *s, unsigned long long *ret_u); +int safe_atolli(const char *s, long long int *ret_i); + +int safe_atou8(const char *s, uint8_t *ret); + +int safe_atou16(const char *s, uint16_t *ret); +int safe_atoi16(const char *s, int16_t *ret); + +static inline int safe_atou32(const char *s, uint32_t *ret_u) { +        assert_cc(sizeof(uint32_t) == sizeof(unsigned)); +        return safe_atou(s, (unsigned*) ret_u); +} + +static inline int safe_atoi32(const char *s, int32_t *ret_i) { +        assert_cc(sizeof(int32_t) == sizeof(int)); +        return safe_atoi(s, (int*) ret_i); +} + +static inline int safe_atou64(const char *s, uint64_t *ret_u) { +        assert_cc(sizeof(uint64_t) == sizeof(unsigned long long)); +        return safe_atollu(s, (unsigned long long*) ret_u); +} + +static inline int safe_atoi64(const char *s, int64_t *ret_i) { +        assert_cc(sizeof(int64_t) == sizeof(long long int)); +        return safe_atolli(s, (long long int*) ret_i); +} + +#if LONG_MAX == INT_MAX +static inline int safe_atolu(const char *s, unsigned long *ret_u) { +        assert_cc(sizeof(unsigned long) == sizeof(unsigned)); +        return safe_atou(s, (unsigned*) ret_u); +} +static inline int safe_atoli(const char *s, long int *ret_u) { +        assert_cc(sizeof(long int) == sizeof(int)); +        return safe_atoi(s, (int*) ret_u); +} +#else +static inline int safe_atolu(const char *s, unsigned long *ret_u) { +        assert_cc(sizeof(unsigned long) == sizeof(unsigned long long)); +        return safe_atollu(s, (unsigned long long*) ret_u); +} +static inline int safe_atoli(const char *s, long int *ret_u) { +        assert_cc(sizeof(long int) == sizeof(long long int)); +        return safe_atolli(s, (long long int*) ret_u); +} +#endif + +#if SIZE_MAX == UINT_MAX +static inline int safe_atozu(const char *s, size_t *ret_u) { +        assert_cc(sizeof(size_t) == sizeof(unsigned)); +        return safe_atou(s, (unsigned *) ret_u); +} +#else +static inline int safe_atozu(const char *s, size_t *ret_u) { +        assert_cc(sizeof(size_t) == sizeof(long unsigned)); +        return safe_atolu(s, ret_u); +} +#endif + +int safe_atod(const char *s, double *ret_d); + +int parse_fractional_part_u(const char **s, size_t digits, unsigned *res); + +int parse_percent_unbounded(const char *p); +int parse_percent(const char *p); + +int parse_nice(const char *p, int *ret); diff --git a/src/libsystemd-basic/include/systemd-basic/path-util.h b/src/libsystemd-basic/include/systemd-basic/path-util.h new file mode 100644 index 0000000000..66545f52d9 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/path-util.h @@ -0,0 +1,130 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2010-2012 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 <alloca.h> +#include <stdbool.h> +#include <stddef.h> + +#include "macro.h" +#include "time-util.h" + +#define DEFAULT_PATH_NORMAL "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin" +#define DEFAULT_PATH_SPLIT_USR DEFAULT_PATH_NORMAL ":/sbin:/bin" + +#ifdef HAVE_SPLIT_USR +#  define DEFAULT_PATH DEFAULT_PATH_SPLIT_USR +#else +#  define DEFAULT_PATH DEFAULT_PATH_NORMAL +#endif + +bool is_path(const char *p) _pure_; +int path_split_and_make_absolute(const char *p, char ***ret); +bool path_is_absolute(const char *p) _pure_; +char* path_make_absolute(const char *p, const char *prefix); +int path_make_absolute_cwd(const char *p, char **ret); +int path_make_relative(const char *from_dir, const char *to_path, char **_r); +char* path_kill_slashes(char *path); +char* path_startswith(const char *path, const char *prefix) _pure_; +int path_compare(const char *a, const char *b) _pure_; +bool path_equal(const char *a, const char *b) _pure_; +bool path_equal_or_files_same(const char *a, const char *b); +char* path_join(const char *root, const char *path, const char *rest); + +static inline bool path_equal_ptr(const char *a, const char *b) { +        return !!a == !!b && (!a || path_equal(a, b)); +} + +/* Note: the search terminates on the first NULL item. */ +#define PATH_IN_SET(p, ...)                                     \ +        ({                                                      \ +                char **s;                                       \ +                bool _found = false;                            \ +                STRV_FOREACH(s, STRV_MAKE(__VA_ARGS__))         \ +                        if (path_equal(p, *s)) {                \ +                               _found = true;                   \ +                               break;                           \ +                        }                                       \ +                _found;                                         \ +        }) + +int path_strv_make_absolute_cwd(char **l); +char** path_strv_resolve(char **l, const char *prefix); +char** path_strv_resolve_uniq(char **l, const char *prefix); + +int find_binary(const char *name, char **filename); + +bool paths_check_timestamp(const char* const* paths, usec_t *paths_ts_usec, bool update); + +int fsck_exists(const char *fstype); +int mkfs_exists(const char *fstype); + +/* Iterates through the path prefixes of the specified path, going up + * the tree, to root. Also returns "" (and not "/"!) for the root + * directory. Excludes the specified directory itself */ +#define PATH_FOREACH_PREFIX(prefix, path) \ +        for (char *_slash = ({ path_kill_slashes(strcpy(prefix, path)); streq(prefix, "/") ? NULL : strrchr(prefix, '/'); }); _slash && ((*_slash = 0), true); _slash = strrchr((prefix), '/')) + +/* Same as PATH_FOREACH_PREFIX but also includes the specified path itself */ +#define PATH_FOREACH_PREFIX_MORE(prefix, path) \ +        for (char *_slash = ({ path_kill_slashes(strcpy(prefix, path)); if (streq(prefix, "/")) prefix[0] = 0; strrchr(prefix, 0); }); _slash && ((*_slash = 0), true); _slash = strrchr((prefix), '/')) + +char *prefix_root(const char *root, const char *path); + +/* Similar to prefix_root(), but returns an alloca() buffer, or + * possibly a const pointer into the path parameter */ +#define prefix_roota(root, path)                                        \ +        ({                                                              \ +                const char* _path = (path), *_root = (root), *_ret;     \ +                char *_p, *_n;                                          \ +                size_t _l;                                              \ +                while (_path[0] == '/' && _path[1] == '/')              \ +                        _path ++;                                       \ +                if (isempty(_root) || path_equal(_root, "/"))           \ +                        _ret = _path;                                   \ +                else {                                                  \ +                        _l = strlen(_root) + 1 + strlen(_path) + 1;     \ +                        _n = alloca(_l);                                \ +                        _p = stpcpy(_n, _root);                         \ +                        while (_p > _n && _p[-1] == '/')                \ +                                _p--;                                   \ +                        if (_path[0] != '/')                            \ +                                *(_p++) = '/';                          \ +                        strcpy(_p, _path);                              \ +                        _ret = _n;                                      \ +                }                                                       \ +                _ret;                                                   \ +        }) + +int parse_path_argument_and_warn(const char *path, bool suppress_root, char **arg); + +char* dirname_malloc(const char *path); + +bool filename_is_valid(const char *p) _pure_; +bool path_is_safe(const char *p) _pure_; + +char *file_in_same_dir(const char *path, const char *filename); + +bool hidden_or_backup_file(const char *filename) _pure_; + +bool is_device_path(const char *path); +bool is_deviceallow_pattern(const char *path); + +int systemd_installation_has_version(const char *root, unsigned minimal_version); diff --git a/src/libsystemd-basic/include/systemd-basic/prioq.h b/src/libsystemd-basic/include/systemd-basic/prioq.h new file mode 100644 index 0000000000..113c73d040 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/prioq.h @@ -0,0 +1,43 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2013 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 "hashmap.h" +#include "macro.h" + +typedef struct Prioq Prioq; + +#define PRIOQ_IDX_NULL ((unsigned) -1) + +Prioq *prioq_new(compare_func_t compare); +Prioq *prioq_free(Prioq *q); +int prioq_ensure_allocated(Prioq **q, compare_func_t compare_func); + +int prioq_put(Prioq *q, void *data, unsigned *idx); +int prioq_remove(Prioq *q, void *data, unsigned *idx); +int prioq_reshuffle(Prioq *q, void *data, unsigned *idx); + +void *prioq_peek(Prioq *q) _pure_; +void *prioq_pop(Prioq *q); + +unsigned prioq_size(Prioq *q) _pure_; +bool prioq_isempty(Prioq *q) _pure_; diff --git a/src/libsystemd-basic/include/systemd-basic/proc-cmdline.h b/src/libsystemd-basic/include/systemd-basic/proc-cmdline.h new file mode 100644 index 0000000000..6d6ee95c11 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/proc-cmdline.h @@ -0,0 +1,29 @@ +#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/>. +***/ + +int proc_cmdline(char **ret); +int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value, void *data), +                       void *data, +                       bool strip_prefix); +int get_proc_cmdline_key(const char *parameter, char **value); + +int shall_restore_state(void); +const char* runlevel_to_target(const char *rl); diff --git a/src/libsystemd-basic/include/systemd-basic/process-util.h b/src/libsystemd-basic/include/systemd-basic/process-util.h new file mode 100644 index 0000000000..aa51357172 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/process-util.h @@ -0,0 +1,110 @@ +#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 <alloca.h> +#include <signal.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> +#include <sys/resource.h> +#include <sys/types.h> + +#include "formats-util.h" +#include "macro.h" + +#define procfs_file_alloca(pid, field)                                  \ +        ({                                                              \ +                pid_t _pid_ = (pid);                                    \ +                const char *_r_;                                        \ +                if (_pid_ == 0) {                                       \ +                        _r_ = ("/proc/self/" field);                    \ +                } else {                                                \ +                        _r_ = alloca(strlen("/proc/") + DECIMAL_STR_MAX(pid_t) + 1 + sizeof(field)); \ +                        sprintf((char*) _r_, "/proc/"PID_FMT"/" field, _pid_);                       \ +                }                                                       \ +                _r_;                                                    \ +        }) + +int get_process_state(pid_t pid); +int get_process_comm(pid_t pid, char **name); +int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line); +int get_process_exe(pid_t pid, char **name); +int get_process_uid(pid_t pid, uid_t *uid); +int get_process_gid(pid_t pid, gid_t *gid); +int get_process_capeff(pid_t pid, char **capeff); +int get_process_cwd(pid_t pid, char **cwd); +int get_process_root(pid_t pid, char **root); +int get_process_environ(pid_t pid, char **environ); +int get_process_ppid(pid_t pid, pid_t *ppid); + +int wait_for_terminate(pid_t pid, siginfo_t *status); +int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code); + +void sigkill_wait(pid_t pid); +void sigkill_waitp(pid_t *pid); + +int kill_and_sigcont(pid_t pid, int sig); + +void rename_process(const char name[8]); +int is_kernel_thread(pid_t pid); + +int getenv_for_pid(pid_t pid, const char *field, char **_value); + +bool pid_is_alive(pid_t pid); +bool pid_is_unwaited(pid_t pid); +int pid_from_same_root_fs(pid_t pid); + +bool is_main_thread(void); + +noreturn void freeze(void); + +bool oom_score_adjust_is_valid(int oa); + +#ifndef PERSONALITY_INVALID +/* personality(7) documents that 0xffffffffUL is used for querying the + * current personality, hence let's use that here as error + * indicator. */ +#define PERSONALITY_INVALID 0xffffffffLU +#endif + +unsigned long personality_from_string(const char *p); +const char *personality_to_string(unsigned long); + +int ioprio_class_to_string_alloc(int i, char **s); +int ioprio_class_from_string(const char *s); + +const char *sigchld_code_to_string(int i) _const_; +int sigchld_code_from_string(const char *s) _pure_; + +int sched_policy_to_string_alloc(int i, char **s); +int sched_policy_from_string(const char *s); + +#define PTR_TO_PID(p) ((pid_t) ((uintptr_t) p)) +#define PID_TO_PTR(p) ((void*) ((uintptr_t) p)) + +void valgrind_summary_hack(void); + +int pid_compare_func(const void *a, const void *b); + +static inline bool nice_is_valid(int n) { +        return n >= PRIO_MIN && n < PRIO_MAX; +} diff --git a/src/libsystemd-basic/include/systemd-basic/random-util.h b/src/libsystemd-basic/include/systemd-basic/random-util.h new file mode 100644 index 0000000000..3cee4c5014 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/random-util.h @@ -0,0 +1,39 @@ +#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 <stddef.h> +#include <stdint.h> + +int dev_urandom(void *p, size_t n); +void random_bytes(void *p, size_t n); +void initialize_srand(void); + +static inline uint64_t random_u64(void) { +        uint64_t u; +        random_bytes(&u, sizeof(u)); +        return u; +} + +static inline uint32_t random_u32(void) { +        uint32_t u; +        random_bytes(&u, sizeof(u)); +        return u; +} diff --git a/src/libsystemd-basic/include/systemd-basic/ratelimit.h b/src/libsystemd-basic/include/systemd-basic/ratelimit.h new file mode 100644 index 0000000000..9c8dddf5ad --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/ratelimit.h @@ -0,0 +1,58 @@ +#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 "time-util.h" +#include "util.h" + +typedef struct RateLimit { +        usec_t interval; +        usec_t begin; +        unsigned burst; +        unsigned num; +} RateLimit; + +#define RATELIMIT_DEFINE(_name, _interval, _burst)       \ +        RateLimit _name = {                              \ +                .interval = (_interval),                 \ +                .burst = (_burst),                       \ +                .num = 0,                                \ +                .begin = 0                               \ +        } + +#define RATELIMIT_INIT(v, _interval, _burst)             \ +        do {                                             \ +                RateLimit *_r = &(v);                    \ +                _r->interval = (_interval);              \ +                _r->burst = (_burst);                    \ +                _r->num = 0;                             \ +                _r->begin = 0;                           \ +        } while (false) + +#define RATELIMIT_RESET(v)                               \ +        do {                                             \ +                RateLimit *_r = &(v);                    \ +                _r->num = 0;                             \ +                _r->begin = 0;                           \ +        } while (false) + +bool ratelimit_test(RateLimit *r); diff --git a/src/libsystemd-basic/include/systemd-basic/raw-clone.h b/src/libsystemd-basic/include/systemd-basic/raw-clone.h new file mode 100644 index 0000000000..d473828999 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/raw-clone.h @@ -0,0 +1,81 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2010 Lennart Poettering +  Copyright 2016 Michael Karcher +  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 <sched.h> +#include <sys/syscall.h> + +#include "log.h" +#include "macro.h" + +/** + * raw_clone() - uses clone to create a new process with clone flags + * @flags: Flags to pass to the clone system call + * + * Uses the clone system call to create a new process with the cloning + * flags and termination signal passed in the flags parameter. Opposed + * to glibc's clone funtion, using this function does not set up a + * separate stack for the child, but relies on copy-on-write semantics + * on the one stack at a common virtual address, just as fork does. + * + * To obtain copy-on-write semantics, flags must not contain CLONE_VM, + * and thus CLONE_THREAD and CLONE_SIGHAND (which require CLONE_VM) are + * not usabale. + * Additionally, as this function does not pass the ptid, newtls and ctid + * parameters to the kernel, flags must not contain CLONE_PARENT_SETTID, + * CLONE_CHILD_SETTID, CLONE_CHILD_CLEARTID or CLONE_SETTLS. + * + * Returns: 0 in the child process and the child process id in the parent. + */ +static inline int raw_clone(unsigned long flags) { +        assert((flags & (CLONE_VM|CLONE_PARENT_SETTID|CLONE_CHILD_SETTID| +                         CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0); +#if defined(__s390__) || defined(__CRIS__) +        /* On s390 and cris the order of the first and second arguments +         * of the raw clone() system call is reversed. */ +        return (int) syscall(__NR_clone, NULL, flags); +#elif defined(__sparc__) && defined(__arch64__) +        { +                /** +                 * sparc64 always returns the other process id in %o0, and +                 * a boolean flag whether this is the child or the parent in +                 * %o1. Inline assembly is needed to get the flag returned +                 * in %o1. +                 */ +                int in_child; +                int child_pid; +                asm volatile("mov %2, %%g1\n\t" +                             "mov %3, %%o0\n\t" +                             "mov 0 , %%o1\n\t" +                             "t 0x6d\n\t" +                             "mov %%o1, %0\n\t" +                             "mov %%o0, %1" : +                             "=r"(in_child), "=r"(child_pid) : +                             "i"(__NR_clone), "r"(flags) : +                             "%o1", "%o0", "%g1" ); +                if (in_child) +                        return 0; +                else +                        return child_pid; +        } +#else +        return (int) syscall(__NR_clone, flags, NULL); +#endif +} diff --git a/src/libsystemd-basic/include/systemd-basic/refcnt.h b/src/libsystemd-basic/include/systemd-basic/refcnt.h new file mode 100644 index 0000000000..1d77a6445a --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/refcnt.h @@ -0,0 +1,34 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2013 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/>. +***/ + +/* A type-safe atomic refcounter. + * + * DO NOT USE THIS UNLESS YOU ACTUALLY CARE ABOUT THREAD SAFETY! */ + +typedef struct { +        volatile unsigned _value; +} RefCount; + +#define REFCNT_GET(r) ((r)._value) +#define REFCNT_INC(r) (__sync_add_and_fetch(&(r)._value, 1)) +#define REFCNT_DEC(r) (__sync_sub_and_fetch(&(r)._value, 1)) + +#define REFCNT_INIT ((RefCount) { ._value = 1 }) diff --git a/src/libsystemd-basic/include/systemd-basic/replace-var.h b/src/libsystemd-basic/include/systemd-basic/replace-var.h new file mode 100644 index 0000000000..78412910b2 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/replace-var.h @@ -0,0 +1,22 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2012 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/>. +***/ + +char *replace_var(const char *text, char *(*lookup)(const char *variable, void*userdata), void *userdata); diff --git a/src/libsystemd-basic/include/systemd-basic/rlimit-util.h b/src/libsystemd-basic/include/systemd-basic/rlimit-util.h new file mode 100644 index 0000000000..d4594eccd6 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/rlimit-util.h @@ -0,0 +1,36 @@ +#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 <sys/resource.h> + +#include "macro.h" + +const char *rlimit_to_string(int i) _const_; +int rlimit_from_string(const char *s) _pure_; + +int setrlimit_closest(int resource, const struct rlimit *rlim); + +int rlimit_parse_one(int resource, const char *val, rlim_t *ret); +int rlimit_parse(int resource, const char *val, struct rlimit *ret); + +int rlimit_format(const struct rlimit *rl, char **ret); + +#define RLIMIT_MAKE_CONST(lim) ((struct rlimit) { lim, lim }) diff --git a/src/libsystemd-basic/include/systemd-basic/rm-rf.h b/src/libsystemd-basic/include/systemd-basic/rm-rf.h new file mode 100644 index 0000000000..f693a5bb7c --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/rm-rf.h @@ -0,0 +1,41 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2015 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/stat.h> + +typedef enum RemoveFlags { +        REMOVE_ONLY_DIRECTORIES = 1, +        REMOVE_ROOT = 2, +        REMOVE_PHYSICAL = 4, /* if not set, only removes files on tmpfs, never physical file systems */ +        REMOVE_SUBVOLUME = 8, +} RemoveFlags; + +int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev); +int rm_rf(const char *path, RemoveFlags flags); + +/* Useful for usage with _cleanup_(), destroys a directory and frees the pointer */ +static inline void rm_rf_physical_and_free(char *p) { +        if (!p) +                return; +        (void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL); +        free(p); +} +DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rm_rf_physical_and_free); diff --git a/src/libsystemd-basic/include/systemd-basic/securebits.h b/src/libsystemd-basic/include/systemd-basic/securebits.h new file mode 100644 index 0000000000..98fbe0d433 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/securebits.h @@ -0,0 +1,45 @@ +#ifndef _LINUX_SECUREBITS_H +#define _LINUX_SECUREBITS_H 1 + +/* This is minimal version of Linux' linux/securebits.h header file, + * which is licensed GPL2 */ + +#define SECUREBITS_DEFAULT 0x00000000 + +/* When set UID 0 has no special privileges. When unset, we support +   inheritance of root-permissions and suid-root executable under +   compatibility mode. We raise the effective and inheritable bitmasks +   *of the executable file* if the effective uid of the new process is +   0. If the real uid is 0, we raise the effective (legacy) bit of the +   executable file. */ +#define SECURE_NOROOT			0 +#define SECURE_NOROOT_LOCKED		1  /* make bit-0 immutable */ + +/* When set, setuid to/from uid 0 does not trigger capability-"fixup". +   When unset, to provide compatibility with old programs relying on +   set*uid to gain/lose privilege, transitions to/from uid 0 cause +   capabilities to be gained/lost. */ +#define SECURE_NO_SETUID_FIXUP		2 +#define SECURE_NO_SETUID_FIXUP_LOCKED	3  /* make bit-2 immutable */ + +/* When set, a process can retain its capabilities even after +   transitioning to a non-root user (the set-uid fixup suppressed by +   bit 2). Bit-4 is cleared when a process calls exec(); setting both +   bit 4 and 5 will create a barrier through exec that no exec()'d +   child can use this feature again. */ +#define SECURE_KEEP_CAPS		4 +#define SECURE_KEEP_CAPS_LOCKED		5  /* make bit-4 immutable */ + +/* Each securesetting is implemented using two bits. One bit specifies +   whether the setting is on or off. The other bit specify whether the +   setting is locked or not. A setting which is locked cannot be +   changed from user-level. */ +#define issecure_mask(X)	(1 << (X)) +#define issecure(X)		(issecure_mask(X) & current_cred_xxx(securebits)) + +#define SECURE_ALL_BITS		(issecure_mask(SECURE_NOROOT) | \ +                                 issecure_mask(SECURE_NO_SETUID_FIXUP) | \ +                                 issecure_mask(SECURE_KEEP_CAPS)) +#define SECURE_ALL_LOCKS	(SECURE_ALL_BITS << 1) + +#endif /* !_LINUX_SECUREBITS_H */ diff --git a/src/libsystemd-basic/include/systemd-basic/selinux-util.h b/src/libsystemd-basic/include/systemd-basic/selinux-util.h new file mode 100644 index 0000000000..ce6bc8e44c --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/selinux-util.h @@ -0,0 +1,51 @@ +#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/socket.h> +#include <sys/types.h> + +#include "macro.h" + +bool mac_selinux_use(void); +bool mac_selinux_have(void); +void mac_selinux_retest(void); + +int mac_selinux_init(void); +void mac_selinux_finish(void); + +int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs); +int mac_selinux_apply(const char *path, const char *label); + +int mac_selinux_get_create_label_from_exe(const char *exe, char **label); +int mac_selinux_get_our_label(char **label); +int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *exec_label, char **label); +char* mac_selinux_free(char *label); + +int mac_selinux_create_file_prepare(const char *path, mode_t mode); +void mac_selinux_create_file_clear(void); + +int mac_selinux_create_socket_prepare(const char *label); +void mac_selinux_create_socket_clear(void); + +int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen); + +DEFINE_TRIVIAL_CLEANUP_FUNC(char*, mac_selinux_free); diff --git a/src/libsystemd-basic/include/systemd-basic/set.h b/src/libsystemd-basic/include/systemd-basic/set.h new file mode 100644 index 0000000000..a5f8beb0c4 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/set.h @@ -0,0 +1,138 @@ +#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 "extract-word.h" +#include "hashmap.h" +#include "macro.h" + +Set *internal_set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); +#define set_new(ops) internal_set_new(ops HASHMAP_DEBUG_SRC_ARGS) + +static inline Set *set_free(Set *s) { +        internal_hashmap_free(HASHMAP_BASE(s)); +        return NULL; +} + +static inline Set *set_free_free(Set *s) { +        internal_hashmap_free_free(HASHMAP_BASE(s)); +        return NULL; +} + +/* no set_free_free_free */ + +static inline Set *set_copy(Set *s) { +        return (Set*) internal_hashmap_copy(HASHMAP_BASE(s)); +} + +int internal_set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); +#define set_ensure_allocated(h, ops) internal_set_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS) + +int set_put(Set *s, const void *key); +/* no set_update */ +/* no set_replace */ +static inline void *set_get(Set *s, void *key) { +        return internal_hashmap_get(HASHMAP_BASE(s), key); +} +/* no set_get2 */ + +static inline bool set_contains(Set *s, const void *key) { +        return internal_hashmap_contains(HASHMAP_BASE(s), key); +} + +static inline void *set_remove(Set *s, const void *key) { +        return internal_hashmap_remove(HASHMAP_BASE(s), key); +} + +/* no set_remove2 */ +/* no set_remove_value */ +int set_remove_and_put(Set *s, const void *old_key, const void *new_key); +/* no set_remove_and_replace */ +int set_merge(Set *s, Set *other); + +static inline int set_reserve(Set *h, unsigned entries_add) { +        return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add); +} + +static inline int set_move(Set *s, Set *other) { +        return internal_hashmap_move(HASHMAP_BASE(s), HASHMAP_BASE(other)); +} + +static inline int set_move_one(Set *s, Set *other, const void *key) { +        return internal_hashmap_move_one(HASHMAP_BASE(s), HASHMAP_BASE(other), key); +} + +static inline unsigned set_size(Set *s) { +        return internal_hashmap_size(HASHMAP_BASE(s)); +} + +static inline bool set_isempty(Set *s) { +        return set_size(s) == 0; +} + +static inline unsigned set_buckets(Set *s) { +        return internal_hashmap_buckets(HASHMAP_BASE(s)); +} + +bool set_iterate(Set *s, Iterator *i, void **value); + +static inline void set_clear(Set *s) { +        internal_hashmap_clear(HASHMAP_BASE(s)); +} + +static inline void set_clear_free(Set *s) { +        internal_hashmap_clear_free(HASHMAP_BASE(s)); +} + +/* no set_clear_free_free */ + +static inline void *set_steal_first(Set *s) { +        return internal_hashmap_steal_first(HASHMAP_BASE(s)); +} + +/* no set_steal_first_key */ +/* no set_first_key */ + +static inline void *set_first(Set *s) { +        return internal_hashmap_first(HASHMAP_BASE(s)); +} + +/* no set_next */ + +static inline char **set_get_strv(Set *s) { +        return internal_hashmap_get_strv(HASHMAP_BASE(s)); +} + +int set_consume(Set *s, void *value); +int set_put_strdup(Set *s, const char *p); +int set_put_strdupv(Set *s, char **l); +int set_put_strsplit(Set *s, const char *v, const char *separators, ExtractFlags flags); + +#define SET_FOREACH(e, s, i) \ +        for ((i) = ITERATOR_FIRST; set_iterate((s), &(i), (void**)&(e)); ) + +#define SET_FOREACH_MOVE(e, d, s)                                       \ +        for (; ({ e = set_first(s); assert_se(!e || set_move_one(d, s, e) >= 0); e; }); ) + +DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free_free); + +#define _cleanup_set_free_ _cleanup_(set_freep) +#define _cleanup_set_free_free_ _cleanup_(set_free_freep) diff --git a/src/libsystemd-basic/include/systemd-basic/sigbus.h b/src/libsystemd-basic/include/systemd-basic/sigbus.h new file mode 100644 index 0000000000..980243d9ce --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/sigbus.h @@ -0,0 +1,25 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2014 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/>. +***/ + +void sigbus_install(void); +void sigbus_reset(void); + +int sigbus_pop(void **ret); diff --git a/src/libsystemd-basic/include/systemd-basic/signal-util.h b/src/libsystemd-basic/include/systemd-basic/signal-util.h new file mode 100644 index 0000000000..dfd6eb564d --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/signal-util.h @@ -0,0 +1,56 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2010-2015 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 <signal.h> + +#include "macro.h" + +int reset_all_signal_handlers(void); +int reset_signal_mask(void); + +int ignore_signals(int sig, ...); +int default_signals(int sig, ...); +int sigaction_many(const struct sigaction *sa, ...); + +int sigset_add_many(sigset_t *ss, ...); +int sigprocmask_many(int how, sigset_t *old, ...); + +const char *signal_to_string(int i) _const_; +int signal_from_string(const char *s) _pure_; + +int signal_from_string_try_harder(const char *s); + +void nop_signal_handler(int sig); + +static inline void block_signals_reset(sigset_t *ss) { +        assert_se(sigprocmask(SIG_SETMASK, ss, NULL) >= 0); +} + +#define BLOCK_SIGNALS(...)                                                        \ +        _cleanup_(block_signals_reset) _unused_ sigset_t _saved_sigset = ({       \ +                sigset_t t;                                                       \ +                assert_se(sigprocmask_many(SIG_BLOCK, &t, __VA_ARGS__, -1) >= 0); \ +                t;                                                                \ +        }) + +static inline bool SIGNAL_VALID(int signo) { +        return signo > 0 && signo < _NSIG; +} diff --git a/src/libsystemd-basic/include/systemd-basic/siphash24.h b/src/libsystemd-basic/include/systemd-basic/siphash24.h new file mode 100644 index 0000000000..54e2420cc6 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/siphash24.h @@ -0,0 +1,23 @@ +#pragma once + +#include <inttypes.h> +#include <stddef.h> +#include <stdint.h> +#include <sys/types.h> + +struct siphash { +        uint64_t v0; +        uint64_t v1; +        uint64_t v2; +        uint64_t v3; +        uint64_t padding; +        size_t inlen; +}; + +void siphash24_init(struct siphash *state, const uint8_t k[16]); +void siphash24_compress(const void *in, size_t inlen, struct siphash *state); +#define siphash24_compress_byte(byte, state) siphash24_compress((const uint8_t[]) { (byte) }, 1, (state)) + +uint64_t siphash24_finalize(struct siphash *state); + +uint64_t siphash24(const void *in, size_t inlen, const uint8_t k[16]); diff --git a/src/libsystemd-basic/include/systemd-basic/smack-util.h b/src/libsystemd-basic/include/systemd-basic/smack-util.h new file mode 100644 index 0000000000..f90ba0a027 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/smack-util.h @@ -0,0 +1,54 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2013 Intel Corporation + +  Author: Auke Kok <auke-jan.h.kok@intel.com> + +  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 "macro.h" + +#define SMACK_FLOOR_LABEL "_" +#define SMACK_STAR_LABEL  "*" + +typedef enum SmackAttr { +        SMACK_ATTR_ACCESS = 0, +        SMACK_ATTR_EXEC = 1, +        SMACK_ATTR_MMAP = 2, +        SMACK_ATTR_TRANSMUTE = 3, +        SMACK_ATTR_IPIN = 4, +        SMACK_ATTR_IPOUT = 5, +        _SMACK_ATTR_MAX, +        _SMACK_ATTR_INVALID = -1, +} SmackAttr; + +bool mac_smack_use(void); + +int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs); + +const char* smack_attr_to_string(SmackAttr i) _const_; +SmackAttr smack_attr_from_string(const char *s) _pure_; +int mac_smack_read(const char *path, SmackAttr attr, char **label); +int mac_smack_read_fd(int fd, SmackAttr attr, char **label); +int mac_smack_apply(const char *path, SmackAttr attr, const char *label); +int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label); +int mac_smack_apply_pid(pid_t pid, const char *label); +int mac_smack_copy(const char *dest, const char *src); diff --git a/src/libsystemd-basic/include/systemd-basic/socket-util.h b/src/libsystemd-basic/include/systemd-basic/socket-util.h new file mode 100644 index 0000000000..7f1a87bc3e --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/socket-util.h @@ -0,0 +1,159 @@ +#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 <netinet/ether.h> +#include <netinet/in.h> +#include <stdbool.h> +#include <stddef.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/un.h> + +#include <linux/netlink.h> +#include <linux/if_packet.h> + +#include "macro.h" +#include "util.h" + +union sockaddr_union { +        struct sockaddr sa; +        struct sockaddr_in in; +        struct sockaddr_in6 in6; +        struct sockaddr_un un; +        struct sockaddr_nl nl; +        struct sockaddr_storage storage; +        struct sockaddr_ll ll; +}; + +typedef struct SocketAddress { +        union sockaddr_union sockaddr; + +        /* We store the size here explicitly due to the weird +         * sockaddr_un semantics for abstract sockets */ +        socklen_t size; + +        /* Socket type, i.e. SOCK_STREAM, SOCK_DGRAM, ... */ +        int type; + +        /* Socket protocol, IPPROTO_xxx, usually 0, except for netlink */ +        int protocol; +} SocketAddress; + +typedef enum SocketAddressBindIPv6Only { +        SOCKET_ADDRESS_DEFAULT, +        SOCKET_ADDRESS_BOTH, +        SOCKET_ADDRESS_IPV6_ONLY, +        _SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX, +        _SOCKET_ADDRESS_BIND_IPV6_ONLY_INVALID = -1 +} SocketAddressBindIPv6Only; + +#define socket_address_family(a) ((a)->sockaddr.sa.sa_family) + +int socket_address_parse(SocketAddress *a, const char *s); +int socket_address_parse_and_warn(SocketAddress *a, const char *s); +int socket_address_parse_netlink(SocketAddress *a, const char *s); +int socket_address_print(const SocketAddress *a, char **p); +int socket_address_verify(const SocketAddress *a) _pure_; +int socket_address_unlink(SocketAddress *a); + +bool socket_address_can_accept(const SocketAddress *a) _pure_; + +int socket_address_listen( +                const SocketAddress *a, +                int flags, +                int backlog, +                SocketAddressBindIPv6Only only, +                const char *bind_to_device, +                bool reuse_port, +                bool free_bind, +                bool transparent, +                mode_t directory_mode, +                mode_t socket_mode, +                const char *label); +int make_socket_fd(int log_level, const char* address, int type, int flags); + +bool socket_address_is(const SocketAddress *a, const char *s, int type); +bool socket_address_is_netlink(const SocketAddress *a, const char *s); + +bool socket_address_matches_fd(const SocketAddress *a, int fd); + +bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) _pure_; + +const char* socket_address_get_path(const SocketAddress *a); + +bool socket_ipv6_is_supported(void); + +int sockaddr_port(const struct sockaddr *_sa) _pure_; + +int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret); +int getpeername_pretty(int fd, bool include_port, char **ret); +int getsockname_pretty(int fd, char **ret); + +int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret); +int getnameinfo_pretty(int fd, char **ret); + +const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b) _const_; +SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s) _pure_; + +int netlink_family_to_string_alloc(int b, char **s); +int netlink_family_from_string(const char *s) _pure_; + +bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b); + +int fd_inc_sndbuf(int fd, size_t n); +int fd_inc_rcvbuf(int fd, size_t n); + +int ip_tos_to_string_alloc(int i, char **s); +int ip_tos_from_string(const char *s); + +bool ifname_valid(const char *p); + +int getpeercred(int fd, struct ucred *ucred); +int getpeersec(int fd, char **ret); + +int send_one_fd_sa(int transport_fd, +                   int fd, +                   const struct sockaddr *sa, socklen_t len, +                   int flags); +#define send_one_fd(transport_fd, fd, flags) send_one_fd_sa(transport_fd, fd, NULL, 0, flags) +int receive_one_fd(int transport_fd, int flags); + +ssize_t next_datagram_size_fd(int fd); + +int flush_accept(int fd); + +#define CMSG_FOREACH(cmsg, mh)                                          \ +        for ((cmsg) = CMSG_FIRSTHDR(mh); (cmsg); (cmsg) = CMSG_NXTHDR((mh), (cmsg))) + +struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length); + +/* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */ +#define SOCKADDR_UN_LEN(sa)                                             \ +        ({                                                              \ +                const struct sockaddr_un *_sa = &(sa);                  \ +                assert(_sa->sun_family == AF_UNIX);                     \ +                offsetof(struct sockaddr_un, sun_path) +                \ +                        (_sa->sun_path[0] == 0 ?                        \ +                         1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \ +                         strnlen(_sa->sun_path, sizeof(_sa->sun_path))); \ +        }) + +int socket_ioctl_fd(void); diff --git a/src/libsystemd-basic/include/systemd-basic/sparse-endian.h b/src/libsystemd-basic/include/systemd-basic/sparse-endian.h new file mode 100644 index 0000000000..a3573b84a9 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/sparse-endian.h @@ -0,0 +1,91 @@ +/* Copyright (c) 2012 Josh Triplett <josh@joshtriplett.org> + * + * 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. + */ +#ifndef SPARSE_ENDIAN_H +#define SPARSE_ENDIAN_H + +#include <byteswap.h> +#include <endian.h> +#include <stdint.h> + +#ifdef __CHECKER__ +#define __sd_bitwise __attribute__((bitwise)) +#define __sd_force __attribute__((force)) +#else +#define __sd_bitwise +#define __sd_force +#endif + +typedef uint16_t __sd_bitwise le16_t; +typedef uint16_t __sd_bitwise be16_t; +typedef uint32_t __sd_bitwise le32_t; +typedef uint32_t __sd_bitwise be32_t; +typedef uint64_t __sd_bitwise le64_t; +typedef uint64_t __sd_bitwise be64_t; + +#undef htobe16 +#undef htole16 +#undef be16toh +#undef le16toh +#undef htobe32 +#undef htole32 +#undef be32toh +#undef le32toh +#undef htobe64 +#undef htole64 +#undef be64toh +#undef le64toh + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define bswap_16_on_le(x) __bswap_16(x) +#define bswap_32_on_le(x) __bswap_32(x) +#define bswap_64_on_le(x) __bswap_64(x) +#define bswap_16_on_be(x) (x) +#define bswap_32_on_be(x) (x) +#define bswap_64_on_be(x) (x) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define bswap_16_on_le(x) (x) +#define bswap_32_on_le(x) (x) +#define bswap_64_on_le(x) (x) +#define bswap_16_on_be(x) __bswap_16(x) +#define bswap_32_on_be(x) __bswap_32(x) +#define bswap_64_on_be(x) __bswap_64(x) +#endif + +static inline le16_t htole16(uint16_t value) { return (le16_t __sd_force) bswap_16_on_be(value); } +static inline le32_t htole32(uint32_t value) { return (le32_t __sd_force) bswap_32_on_be(value); } +static inline le64_t htole64(uint64_t value) { return (le64_t __sd_force) bswap_64_on_be(value); } + +static inline be16_t htobe16(uint16_t value) { return (be16_t __sd_force) bswap_16_on_le(value); } +static inline be32_t htobe32(uint32_t value) { return (be32_t __sd_force) bswap_32_on_le(value); } +static inline be64_t htobe64(uint64_t value) { return (be64_t __sd_force) bswap_64_on_le(value); } + +static inline uint16_t le16toh(le16_t value) { return bswap_16_on_be((uint16_t __sd_force)value); } +static inline uint32_t le32toh(le32_t value) { return bswap_32_on_be((uint32_t __sd_force)value); } +static inline uint64_t le64toh(le64_t value) { return bswap_64_on_be((uint64_t __sd_force)value); } + +static inline uint16_t be16toh(be16_t value) { return bswap_16_on_le((uint16_t __sd_force)value); } +static inline uint32_t be32toh(be32_t value) { return bswap_32_on_le((uint32_t __sd_force)value); } +static inline uint64_t be64toh(be64_t value) { return bswap_64_on_le((uint64_t __sd_force)value); } + +#undef __sd_bitwise +#undef __sd_force + +#endif /* SPARSE_ENDIAN_H */ diff --git a/src/libsystemd-basic/include/systemd-basic/special.h b/src/libsystemd-basic/include/systemd-basic/special.h new file mode 100644 index 0000000000..5276bcf598 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/special.h @@ -0,0 +1,122 @@ +#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/>. +***/ + +#define SPECIAL_DEFAULT_TARGET "default.target" + +/* Shutdown targets */ +#define SPECIAL_UMOUNT_TARGET "umount.target" +/* This is not really intended to be started by directly. This is + * mostly so that other targets (reboot/halt/poweroff) can depend on + * it to bring all services down that want to be brought down on + * system shutdown. */ +#define SPECIAL_SHUTDOWN_TARGET "shutdown.target" +#define SPECIAL_HALT_TARGET "halt.target" +#define SPECIAL_POWEROFF_TARGET "poweroff.target" +#define SPECIAL_REBOOT_TARGET "reboot.target" +#define SPECIAL_KEXEC_TARGET "kexec.target" +#define SPECIAL_EXIT_TARGET "exit.target" +#define SPECIAL_SUSPEND_TARGET "suspend.target" +#define SPECIAL_HIBERNATE_TARGET "hibernate.target" +#define SPECIAL_HYBRID_SLEEP_TARGET "hybrid-sleep.target" + +/* Special boot targets */ +#define SPECIAL_RESCUE_TARGET "rescue.target" +#define SPECIAL_EMERGENCY_TARGET "emergency.target" +#define SPECIAL_MULTI_USER_TARGET "multi-user.target" +#define SPECIAL_GRAPHICAL_TARGET "graphical.target" + +/* Early boot targets */ +#define SPECIAL_SYSINIT_TARGET "sysinit.target" +#define SPECIAL_SOCKETS_TARGET "sockets.target" +#define SPECIAL_BUSNAMES_TARGET "busnames.target" +#define SPECIAL_TIMERS_TARGET "timers.target" +#define SPECIAL_PATHS_TARGET "paths.target" +#define SPECIAL_LOCAL_FS_TARGET "local-fs.target" +#define SPECIAL_LOCAL_FS_PRE_TARGET "local-fs-pre.target" +#define SPECIAL_INITRD_FS_TARGET "initrd-fs.target" +#define SPECIAL_INITRD_ROOT_DEVICE_TARGET "initrd-root-device.target" +#define SPECIAL_INITRD_ROOT_FS_TARGET "initrd-root-fs.target" +#define SPECIAL_REMOTE_FS_TARGET "remote-fs.target"       /* LSB's $remote_fs */ +#define SPECIAL_REMOTE_FS_PRE_TARGET "remote-fs-pre.target" +#define SPECIAL_SWAP_TARGET "swap.target" +#define SPECIAL_NETWORK_ONLINE_TARGET "network-online.target" +#define SPECIAL_TIME_SYNC_TARGET "time-sync.target"       /* LSB's $time */ +#define SPECIAL_BASIC_TARGET "basic.target" + +/* LSB compatibility */ +#define SPECIAL_NETWORK_TARGET "network.target"           /* LSB's $network */ +#define SPECIAL_NSS_LOOKUP_TARGET "nss-lookup.target"     /* LSB's $named */ +#define SPECIAL_RPCBIND_TARGET "rpcbind.target"           /* LSB's $portmap */ + +/* + * Rules regarding adding further high level targets like the above: + * + * - Be conservative, only add more of these when we really need + *   them. We need strong usecases for further additions. + * + * - When there can be multiple implementations running side-by-side, + *   it needs to be a .target unit which can pull in all + *   implementations. + * + * - If something can be implemented with socket activation, and + *   without, it needs to be a .target unit, so that it can pull in + *   the appropriate unit. + * + * - Otherwise, it should be a .service unit. + * + * - In some cases it is OK to have both a .service and a .target + *   unit, i.e. if there can be multiple parallel implementations, but + *   only one is the "system" one. Example: syslog. + * + * Or to put this in other words: .service symlinks can be used to + * arbitrate between multiple implementations if there can be only one + * of a kind. .target units can be used to support multiple + * implementations that can run side-by-side. + */ + +/* Magic early boot services */ +#define SPECIAL_FSCK_SERVICE "systemd-fsck@.service" +#define SPECIAL_QUOTACHECK_SERVICE "systemd-quotacheck.service" +#define SPECIAL_QUOTAON_SERVICE "quotaon.service" +#define SPECIAL_REMOUNT_FS_SERVICE "systemd-remount-fs.service" + +/* Services systemd relies on */ +#define SPECIAL_DBUS_SERVICE "dbus.service" +#define SPECIAL_DBUS_SOCKET "dbus.socket" +#define SPECIAL_JOURNALD_SOCKET "systemd-journald.socket" +#define SPECIAL_JOURNALD_SERVICE "systemd-journald.service" + +/* Magic init signals */ +#define SPECIAL_KBREQUEST_TARGET "kbrequest.target" +#define SPECIAL_SIGPWR_TARGET "sigpwr.target" +#define SPECIAL_CTRL_ALT_DEL_TARGET "ctrl-alt-del.target" + +/* Where we add all our system units, users and machines by default */ +#define SPECIAL_SYSTEM_SLICE "system.slice" +#define SPECIAL_USER_SLICE "user.slice" +#define SPECIAL_MACHINE_SLICE "machine.slice" +#define SPECIAL_ROOT_SLICE "-.slice" + +/* The scope unit systemd itself lives in. */ +#define SPECIAL_INIT_SCOPE "init.scope" + +/* The root directory. */ +#define SPECIAL_ROOT_MOUNT "-.mount" diff --git a/src/libsystemd-basic/include/systemd-basic/stat-util.h b/src/libsystemd-basic/include/systemd-basic/stat-util.h new file mode 100644 index 0000000000..56d28f791e --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/stat-util.h @@ -0,0 +1,69 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2010-2012 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 <stddef.h> +#include <sys/stat.h> +#include <sys/statfs.h> +#include <sys/types.h> +#include <sys/vfs.h> + +#include "macro.h" + +int is_symlink(const char *path); +int is_dir(const char *path, bool follow); +int is_device_node(const char *path); + +int dir_is_empty(const char *path); + +static inline int dir_is_populated(const char *path) { +        int r; +        r = dir_is_empty(path); +        if (r < 0) +                return r; +        return !r; +} + +bool null_or_empty(struct stat *st) _pure_; +int null_or_empty_path(const char *fn); +int null_or_empty_fd(int fd); + +int path_is_read_only_fs(const char *path); +int path_is_os_tree(const char *path); + +int files_same(const char *filea, const char *fileb); + +/* The .f_type field of struct statfs is really weird defined on + * different archs. Let's give its type a name. */ +typedef typeof(((struct statfs*)NULL)->f_type) statfs_f_type_t; + +bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) _pure_; +int fd_check_fstype(int fd, statfs_f_type_t magic_value); +int path_check_fstype(const char *path, statfs_f_type_t magic_value); + +bool is_temporary_fs(const struct statfs *s) _pure_; +int fd_is_temporary_fs(int fd); + +/* Because statfs.t_type can be int on some architectures, we have to cast + * the const magic to the type, otherwise the compiler warns about + * signed/unsigned comparison, because the magic can be 32 bit unsigned. + */ +#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b) diff --git a/src/libsystemd-basic/include/systemd-basic/stdio-util.h b/src/libsystemd-basic/include/systemd-basic/stdio-util.h new file mode 100644 index 0000000000..bd1144b4c9 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/stdio-util.h @@ -0,0 +1,76 @@ +#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 <printf.h> +#include <stdarg.h> +#include <stdio.h> +#include <sys/types.h> + +#include "macro.h" + +#define xsprintf(buf, fmt, ...) \ +        assert_message_se((size_t) snprintf(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__) < ELEMENTSOF(buf), "xsprintf: " #buf "[] must be big enough") + + +#define VA_FORMAT_ADVANCE(format, ap)                                   \ +do {                                                                    \ +        int _argtypes[128];                                             \ +        size_t _i, _k;                                                  \ +        _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \ +        assert(_k < ELEMENTSOF(_argtypes));                             \ +        for (_i = 0; _i < _k; _i++) {                                   \ +                if (_argtypes[_i] & PA_FLAG_PTR)  {                     \ +                        (void) va_arg(ap, void*);                       \ +                        continue;                                       \ +                }                                                       \ +                                                                        \ +                switch (_argtypes[_i]) {                                \ +                case PA_INT:                                            \ +                case PA_INT|PA_FLAG_SHORT:                              \ +                case PA_CHAR:                                           \ +                        (void) va_arg(ap, int);                         \ +                        break;                                          \ +                case PA_INT|PA_FLAG_LONG:                               \ +                        (void) va_arg(ap, long int);                    \ +                        break;                                          \ +                case PA_INT|PA_FLAG_LONG_LONG:                          \ +                        (void) va_arg(ap, long long int);               \ +                        break;                                          \ +                case PA_WCHAR:                                          \ +                        (void) va_arg(ap, wchar_t);                     \ +                        break;                                          \ +                case PA_WSTRING:                                        \ +                case PA_STRING:                                         \ +                case PA_POINTER:                                        \ +                        (void) va_arg(ap, void*);                       \ +                        break;                                          \ +                case PA_FLOAT:                                          \ +                case PA_DOUBLE:                                         \ +                        (void) va_arg(ap, double);                      \ +                        break;                                          \ +                case PA_DOUBLE|PA_FLAG_LONG_DOUBLE:                     \ +                        (void) va_arg(ap, long double);                 \ +                        break;                                          \ +                default:                                                \ +                        assert_not_reached("Unknown format string argument."); \ +                }                                                       \ +        }                                                               \ +} while (false) diff --git a/src/libsystemd-basic/include/systemd-basic/strbuf.h b/src/libsystemd-basic/include/systemd-basic/strbuf.h new file mode 100644 index 0000000000..a1632da0e8 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/strbuf.h @@ -0,0 +1,54 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2012 Kay Sievers <kay@vrfy.org> + +  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 <stddef.h> +#include <stdint.h> +#include <sys/types.h> + +struct strbuf { +        char *buf; +        size_t len; +        struct strbuf_node *root; + +        size_t nodes_count; +        size_t in_count; +        size_t in_len; +        size_t dedup_len; +        size_t dedup_count; +}; + +struct strbuf_node { +        size_t value_off; +        size_t value_len; + +        struct strbuf_child_entry *children; +        uint8_t children_count; +}; + +struct strbuf_child_entry { +        uint8_t c; +        struct strbuf_node *child; +}; + +struct strbuf *strbuf_new(void); +ssize_t strbuf_add_string(struct strbuf *str, const char *s, size_t len); +void strbuf_complete(struct strbuf *str); +void strbuf_cleanup(struct strbuf *str); diff --git a/src/libsystemd-basic/include/systemd-basic/string-table.h b/src/libsystemd-basic/include/systemd-basic/string-table.h new file mode 100644 index 0000000000..369610efc8 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/string-table.h @@ -0,0 +1,119 @@ + +#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 <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> + +#include "macro.h" +#include "parse-util.h" +#include "string-util.h" + +ssize_t string_table_lookup(const char * const *table, size_t len, const char *key); + +/* For basic lookup tables with strictly enumerated entries */ +#define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope)          \ +        scope const char *name##_to_string(type i) {                    \ +                if (i < 0 || i >= (type) ELEMENTSOF(name##_table))      \ +                        return NULL;                                    \ +                return name##_table[i];                                 \ +        } + +#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope)        \ +        scope type name##_from_string(const char *s) {                  \ +                return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \ +        } + +#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \ +        scope type name##_from_string(const char *s) {                  \ +                int b;                                                  \ +                if (!s)                                                 \ +                        return -1;                                      \ +                b = parse_boolean(s);                                   \ +                if (b == 0)                                             \ +                        return (type) 0;                                \ +                else if (b > 0)                                         \ +                        return yes;                                     \ +                return (type) string_table_lookup(name##_table, ELEMENTSOF(name##_table), s); \ +        } + +#define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,scope) \ +        scope int name##_to_string_alloc(type i, char **str) {          \ +                char *s;                                                \ +                if (i < 0 || i > max)                                   \ +                        return -ERANGE;                                 \ +                if (i < (type) ELEMENTSOF(name##_table)) {              \ +                        s = strdup(name##_table[i]);                    \ +                        if (!s)                                         \ +                                return -ENOMEM;                         \ +                } else {                                                \ +                        if (asprintf(&s, "%i", i) < 0)                  \ +                                return -ENOMEM;                         \ +                }                                                       \ +                *str = s;                                               \ +                return 0;                                               \ +        } + +#define _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,scope) \ +        type name##_from_string(const char *s) {                        \ +                type i;                                                 \ +                unsigned u = 0;                                         \ +                if (!s)                                                 \ +                        return (type) -1;                               \ +                for (i = 0; i < (type) ELEMENTSOF(name##_table); i++)   \ +                        if (streq_ptr(name##_table[i], s))              \ +                                return i;                               \ +                if (safe_atou(s, &u) >= 0 && u <= max)                  \ +                        return (type) u;                                \ +                return (type) -1;                                       \ +        }                                                               \ + + +#define _DEFINE_STRING_TABLE_LOOKUP(name,type,scope)                    \ +        _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope)          \ +        _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope)        \ +        struct __useless_struct_to_allow_trailing_semicolon__ + +#define _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,scope)   \ +        _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope)          \ +        _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(name,type,yes,scope) \ +        struct __useless_struct_to_allow_trailing_semicolon__ + +#define DEFINE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,) +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) _DEFINE_STRING_TABLE_LOOKUP(name,type,static) +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,static) +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(name,type) _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,static) + +#define DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes) _DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(name,type,yes,) + +/* For string conversions where numbers are also acceptable */ +#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max)         \ +        _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,)  \ +        _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,) \ +        struct __useless_struct_to_allow_trailing_semicolon__ + +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max) \ +        _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,static) +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max) \ +        _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,static) diff --git a/src/libsystemd-basic/include/systemd-basic/string-util.h b/src/libsystemd-basic/include/systemd-basic/string-util.h new file mode 100644 index 0000000000..d029d538bd --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/string-util.h @@ -0,0 +1,201 @@ +#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 <alloca.h> +#include <stdbool.h> +#include <stddef.h> +#include <string.h> + +#include "macro.h" + +/* What is interpreted as whitespace? */ +#define WHITESPACE        " \t\n\r" +#define NEWLINE           "\n\r" +#define QUOTES            "\"\'" +#define COMMENTS          "#;" +#define GLOB_CHARS        "*?[" +#define DIGITS            "0123456789" +#define LOWERCASE_LETTERS "abcdefghijklmnopqrstuvwxyz" +#define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define LETTERS           LOWERCASE_LETTERS UPPERCASE_LETTERS +#define ALPHANUMERICAL    LETTERS DIGITS +#define HEXDIGITS         DIGITS "abcdefABCDEF" + +#define streq(a,b) (strcmp((a),(b)) == 0) +#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) +#define strcaseeq(a,b) (strcasecmp((a),(b)) == 0) +#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0) + +int strcmp_ptr(const char *a, const char *b) _pure_; + +static inline bool streq_ptr(const char *a, const char *b) { +        return strcmp_ptr(a, b) == 0; +} + +static inline const char* strempty(const char *s) { +        return s ? s : ""; +} + +static inline const char* strnull(const char *s) { +        return s ? s : "(null)"; +} + +static inline const char *strna(const char *s) { +        return s ? s : "n/a"; +} + +static inline bool isempty(const char *p) { +        return !p || !p[0]; +} + +static inline const char *empty_to_null(const char *p) { +        return isempty(p) ? NULL : p; +} + +static inline const char *strdash_if_empty(const char *str) { +        return isempty(str) ? "-" : str; +} + +static inline char *startswith(const char *s, const char *prefix) { +        size_t l; + +        l = strlen(prefix); +        if (strncmp(s, prefix, l) == 0) +                return (char*) s + l; + +        return NULL; +} + +static inline char *startswith_no_case(const char *s, const char *prefix) { +        size_t l; + +        l = strlen(prefix); +        if (strncasecmp(s, prefix, l) == 0) +                return (char*) s + l; + +        return NULL; +} + +char *endswith(const char *s, const char *postfix) _pure_; +char *endswith_no_case(const char *s, const char *postfix) _pure_; + +char *first_word(const char *s, const char *word) _pure_; + +const char* split(const char **state, size_t *l, const char *separator, bool quoted); + +#define FOREACH_WORD(word, length, s, state)                            \ +        _FOREACH_WORD(word, length, s, WHITESPACE, false, state) + +#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state)       \ +        _FOREACH_WORD(word, length, s, separator, false, state) + +#define FOREACH_WORD_QUOTED(word, length, s, state)                     \ +        _FOREACH_WORD(word, length, s, WHITESPACE, true, state) + +#define _FOREACH_WORD(word, length, s, separator, quoted, state)        \ +        for ((state) = (s), (word) = split(&(state), &(length), (separator), (quoted)); (word); (word) = split(&(state), &(length), (separator), (quoted))) + +char *strappend(const char *s, const char *suffix); +char *strnappend(const char *s, const char *suffix, size_t length); + +char *strjoin(const char *x, ...) _sentinel_; + +#define strjoina(a, ...)                                                \ +        ({                                                              \ +                const char *_appendees_[] = { a, __VA_ARGS__ };         \ +                char *_d_, *_p_;                                        \ +                int _len_ = 0;                                          \ +                unsigned _i_;                                           \ +                for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \ +                        _len_ += strlen(_appendees_[_i_]);              \ +                _p_ = _d_ = alloca(_len_ + 1);                          \ +                for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \ +                        _p_ = stpcpy(_p_, _appendees_[_i_]);            \ +                *_p_ = 0;                                               \ +                _d_;                                                    \ +        }) + +char *strstrip(char *s); +char *delete_chars(char *s, const char *bad); +char *truncate_nl(char *s); + +char ascii_tolower(char x); +char *ascii_strlower(char *s); +char *ascii_strlower_n(char *s, size_t n); + +char ascii_toupper(char x); +char *ascii_strupper(char *s); + +int ascii_strcasecmp_n(const char *a, const char *b, size_t n); +int ascii_strcasecmp_nn(const char *a, size_t n, const char *b, size_t m); + +bool chars_intersect(const char *a, const char *b) _pure_; + +static inline bool _pure_ in_charset(const char *s, const char* charset) { +        assert(s); +        assert(charset); +        return s[strspn(s, charset)] == '\0'; +} + +bool string_has_cc(const char *p, const char *ok) _pure_; + +char *ellipsize_mem(const char *s, size_t old_length_bytes, size_t new_length_columns, unsigned percent); +char *ellipsize(const char *s, size_t length, unsigned percent); + +bool nulstr_contains(const char*nulstr, const char *needle); + +char* strshorten(char *s, size_t l); + +char *strreplace(const char *text, const char *old_string, const char *new_string); + +char *strip_tab_ansi(char **p, size_t *l); + +char *strextend(char **x, ...) _sentinel_; + +char *strrep(const char *s, unsigned n); + +int split_pair(const char *s, const char *sep, char **l, char **r); + +int free_and_strdup(char **p, const char *s); + +/* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */ +static inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) { + +        if (needlelen <= 0) +                return (void*) haystack; + +        if (haystacklen < needlelen) +                return NULL; + +        assert(haystack); +        assert(needle); + +        return memmem(haystack, haystacklen, needle, needlelen); +} + +void* memory_erase(void *p, size_t l); +char *string_erase(char *x); + +char *string_free_erase(char *s); +DEFINE_TRIVIAL_CLEANUP_FUNC(char *, string_free_erase); +#define _cleanup_string_free_erase_ _cleanup_(string_free_erasep) + +bool string_is_safe(const char *p) _pure_; diff --git a/src/libsystemd-basic/include/systemd-basic/strv.h b/src/libsystemd-basic/include/systemd-basic/strv.h new file mode 100644 index 0000000000..385ad17779 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/strv.h @@ -0,0 +1,182 @@ +#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 <fnmatch.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stddef.h> + +#include "alloc-util.h" +#include "extract-word.h" +#include "macro.h" +#include "util.h" + +char *strv_find(char **l, const char *name) _pure_; +char *strv_find_prefix(char **l, const char *name) _pure_; +char *strv_find_startswith(char **l, const char *name) _pure_; + +char **strv_free(char **l); +DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free); +#define _cleanup_strv_free_ _cleanup_(strv_freep) + +char **strv_free_erase(char **l); +DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free_erase); +#define _cleanup_strv_free_erase_ _cleanup_(strv_free_erasep) + +void strv_clear(char **l); + +char **strv_copy(char * const *l); +unsigned strv_length(char * const *l) _pure_; + +int strv_extend_strv(char ***a, char **b, bool filter_duplicates); +int strv_extend_strv_concat(char ***a, char **b, const char *suffix); +int strv_extend(char ***l, const char *value); +int strv_extendf(char ***l, const char *format, ...) _printf_(2,0); +int strv_extend_front(char ***l, const char *value); +int strv_push(char ***l, char *value); +int strv_push_pair(char ***l, char *a, char *b); +int strv_push_prepend(char ***l, char *value); +int strv_consume(char ***l, char *value); +int strv_consume_pair(char ***l, char *a, char *b); +int strv_consume_prepend(char ***l, char *value); + +char **strv_remove(char **l, const char *s); +char **strv_uniq(char **l); +bool strv_is_uniq(char **l); + +bool strv_equal(char **a, char **b); + +#define strv_contains(l, s) (!!strv_find((l), (s))) + +char **strv_new(const char *x, ...) _sentinel_; +char **strv_new_ap(const char *x, va_list ap); + +#define STRV_IGNORE ((const char *) -1) + +static inline const char* STRV_IFNOTNULL(const char *x) { +        return x ? x : STRV_IGNORE; +} + +static inline bool strv_isempty(char * const *l) { +        return !l || !*l; +} + +char **strv_split(const char *s, const char *separator); +char **strv_split_newlines(const char *s); + +int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags); + +char *strv_join(char **l, const char *separator); +char *strv_join_quoted(char **l); + +char **strv_parse_nulstr(const char *s, size_t l); +char **strv_split_nulstr(const char *s); +int strv_make_nulstr(char **l, char **p, size_t *n); + +bool strv_overlap(char **a, char **b) _pure_; + +#define STRV_FOREACH(s, l)                      \ +        for ((s) = (l); (s) && *(s); (s)++) + +#define STRV_FOREACH_BACKWARDS(s, l)                                \ +        for (s = ({                                                 \ +                        char **_l = l;                              \ +                        _l ? _l + strv_length(_l) - 1U : NULL;      \ +                        });                                         \ +             (l) && ((s) >= (l));                                   \ +             (s)--) + +#define STRV_FOREACH_PAIR(x, y, l)               \ +        for ((x) = (l), (y) = (x+1); (x) && *(x) && *(y); (x) += 2, (y) = (x + 1)) + +char **strv_sort(char **l); +void strv_print(char **l); + +#define STRV_MAKE(...) ((char**) ((const char*[]) { __VA_ARGS__, NULL })) + +#define STRV_MAKE_EMPTY ((char*[1]) { NULL }) + +#define strv_from_stdarg_alloca(first)                          \ +        ({                                                      \ +                char **_l;                                      \ +                                                                \ +                if (!first)                                     \ +                        _l = (char**) &first;                   \ +                else {                                          \ +                        unsigned _n;                            \ +                        va_list _ap;                            \ +                                                                \ +                        _n = 1;                                 \ +                        va_start(_ap, first);                   \ +                        while (va_arg(_ap, char*))              \ +                                _n++;                           \ +                        va_end(_ap);                            \ +                                                                \ +                        _l = newa(char*, _n+1);                 \ +                        _l[_n = 0] = (char*) first;             \ +                        va_start(_ap, first);                   \ +                        for (;;) {                              \ +                                _l[++_n] = va_arg(_ap, char*);  \ +                                if (!_l[_n])                    \ +                                        break;                  \ +                        }                                       \ +                        va_end(_ap);                            \ +                }                                               \ +                _l;                                             \ +        }) + +#define STR_IN_SET(x, ...) strv_contains(STRV_MAKE(__VA_ARGS__), x) +#define STRPTR_IN_SET(x, ...)                                    \ +        ({                                                       \ +                const char* _x = (x);                            \ +                _x && strv_contains(STRV_MAKE(__VA_ARGS__), _x); \ +        }) + +#define FOREACH_STRING(x, ...)                               \ +        for (char **_l = ({                                  \ +                char **_ll = STRV_MAKE(__VA_ARGS__);         \ +                x = _ll ? _ll[0] : NULL;                     \ +                _ll;                                         \ +        });                                                  \ +        _l && *_l;                                           \ +        x = ({                                               \ +                _l ++;                                       \ +                _l[0];                                       \ +        })) + +char **strv_reverse(char **l); +char **strv_shell_escape(char **l, const char *bad); + +bool strv_fnmatch(char* const* patterns, const char *s, int flags); + +static inline bool strv_fnmatch_or_empty(char* const* patterns, const char *s, int flags) { +        assert(s); +        return strv_isempty(patterns) || +               strv_fnmatch(patterns, s, flags); +} + +char ***strv_free_free(char ***l); + +char **strv_skip(char **l, size_t n); + +int strv_extend_n(char ***l, const char *value, size_t n); + +int fputstrv(FILE *f, char **l, const char *separator, bool *space); diff --git a/src/libsystemd-basic/include/systemd-basic/strxcpyx.h b/src/libsystemd-basic/include/systemd-basic/strxcpyx.h new file mode 100644 index 0000000000..80ff58726b --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/strxcpyx.h @@ -0,0 +1,31 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2013 Kay Sievers + +  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 <stddef.h> + +#include "macro.h" + +size_t strpcpy(char **dest, size_t size, const char *src); +size_t strpcpyf(char **dest, size_t size, const char *src, ...) _printf_(3, 4); +size_t strpcpyl(char **dest, size_t size, const char *src, ...) _sentinel_; +size_t strscpy(char *dest, size_t size, const char *src); +size_t strscpyl(char *dest, size_t size, const char *src, ...) _sentinel_; diff --git a/src/libsystemd-basic/include/systemd-basic/syslog-util.h b/src/libsystemd-basic/include/systemd-basic/syslog-util.h new file mode 100644 index 0000000000..5cb606a1bf --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/syslog-util.h @@ -0,0 +1,32 @@ +#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> + +int log_facility_unshifted_to_string_alloc(int i, char **s); +int log_facility_unshifted_from_string(const char *s); +bool log_facility_unshifted_is_valid(int faciliy); + +int log_level_to_string_alloc(int i, char **s); +int log_level_from_string(const char *s); +bool log_level_is_valid(int level); + +int syslog_parse_priority(const char **p, int *priority, bool with_facility); diff --git a/src/libsystemd-basic/include/systemd-basic/terminal-util.h b/src/libsystemd-basic/include/systemd-basic/terminal-util.h new file mode 100644 index 0000000000..b862bfaf05 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/terminal-util.h @@ -0,0 +1,119 @@ +#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 <stdarg.h> +#include <stdbool.h> +#include <stdio.h> +#include <sys/types.h> + +#include "macro.h" +#include "time-util.h" + +#define ANSI_RED "\x1B[0;31m" +#define ANSI_GREEN "\x1B[0;32m" +#define ANSI_UNDERLINE "\x1B[0;4m" +#define ANSI_HIGHLIGHT "\x1B[0;1;39m" +#define ANSI_HIGHLIGHT_RED "\x1B[0;1;31m" +#define ANSI_HIGHLIGHT_GREEN "\x1B[0;1;32m" +#define ANSI_HIGHLIGHT_YELLOW "\x1B[0;1;33m" +#define ANSI_HIGHLIGHT_BLUE "\x1B[0;1;34m" +#define ANSI_HIGHLIGHT_UNDERLINE "\x1B[0;1;4m" +#define ANSI_HIGHLIGHT_RED_UNDERLINE "\x1B[0;1;4;31m" +#define ANSI_HIGHLIGHT_GREEN_UNDERLINE "\x1B[0;1;4;32m" +#define ANSI_HIGHLIGHT_YELLOW_UNDERLINE "\x1B[0;1;4;33m" +#define ANSI_HIGHLIGHT_BLUE_UNDERLINE "\x1B[0;1;4;34m" +#define ANSI_NORMAL "\x1B[0m" + +#define ANSI_ERASE_TO_END_OF_LINE "\x1B[K" + +/* Set cursor to top left corner and clear screen */ +#define ANSI_HOME_CLEAR "\x1B[H\x1B[2J" + +int reset_terminal_fd(int fd, bool switch_to_text); +int reset_terminal(const char *name); + +int open_terminal(const char *name, int mode); +int acquire_terminal(const char *name, bool fail, bool force, bool ignore_tiocstty_eperm, usec_t timeout); +int release_terminal(void); + +int terminal_vhangup_fd(int fd); +int terminal_vhangup(const char *name); + +int chvt(int vt); + +int read_one_char(FILE *f, char *ret, usec_t timeout, bool *need_nl); +int ask_char(char *ret, const char *replies, const char *text, ...) _printf_(3, 4); +int ask_string(char **ret, const char *text, ...) _printf_(2, 3); + +int vt_disallocate(const char *name); + +char *resolve_dev_console(char **active); +int get_kernel_consoles(char ***consoles); +bool tty_is_vc(const char *tty); +bool tty_is_vc_resolve(const char *tty); +bool tty_is_console(const char *tty) _pure_; +int vtnr_from_tty(const char *tty); +const char *default_term_for_tty(const char *tty); + +int make_stdio(int fd); +int make_null_stdio(void); +int make_console_stdio(void); + +int fd_columns(int fd); +unsigned columns(void); +int fd_lines(int fd); +unsigned lines(void); +void columns_lines_cache_reset(int _unused_ signum); + +bool on_tty(void); +bool terminal_is_dumb(void); +bool colors_enabled(void); + +#define DEFINE_ANSI_FUNC(name, NAME)                            \ +        static inline const char *ansi_##name(void) {           \ +                return colors_enabled() ? ANSI_##NAME : "";     \ +        }                                                       \ +        struct __useless_struct_to_allow_trailing_semicolon__ + +DEFINE_ANSI_FUNC(underline,                  UNDERLINE); +DEFINE_ANSI_FUNC(highlight,                  HIGHLIGHT); +DEFINE_ANSI_FUNC(highlight_underline,        HIGHLIGHT_UNDERLINE); +DEFINE_ANSI_FUNC(highlight_red,              HIGHLIGHT_RED); +DEFINE_ANSI_FUNC(highlight_green,            HIGHLIGHT_GREEN); +DEFINE_ANSI_FUNC(highlight_yellow,           HIGHLIGHT_YELLOW); +DEFINE_ANSI_FUNC(highlight_blue,             HIGHLIGHT_BLUE); +DEFINE_ANSI_FUNC(highlight_red_underline,    HIGHLIGHT_RED_UNDERLINE); +DEFINE_ANSI_FUNC(highlight_green_underline,  HIGHLIGHT_GREEN_UNDERLINE); +DEFINE_ANSI_FUNC(highlight_yellow_underline, HIGHLIGHT_YELLOW_UNDERLINE); +DEFINE_ANSI_FUNC(highlight_blue_underline,   HIGHLIGHT_BLUE_UNDERLINE); +DEFINE_ANSI_FUNC(normal,                     NORMAL); + +int get_ctty_devnr(pid_t pid, dev_t *d); +int get_ctty(pid_t, dev_t *_devnr, char **r); + +int getttyname_malloc(int fd, char **r); +int getttyname_harder(int fd, char **r); + +int ptsname_malloc(int fd, char **ret); +int ptsname_namespace(int pty, char **ret); + +int openpt_in_namespace(pid_t pid, int flags); +int open_terminal_in_namespace(pid_t pid, const char *name, int mode); diff --git a/src/libsystemd-basic/include/systemd-basic/time-util.h b/src/libsystemd-basic/include/systemd-basic/time-util.h new file mode 100644 index 0000000000..558b0b5b7f --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/time-util.h @@ -0,0 +1,181 @@ +#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 <inttypes.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <time.h> + +typedef uint64_t usec_t; +typedef uint64_t nsec_t; + +#define NSEC_FMT "%" PRIu64 +#define USEC_FMT "%" PRIu64 + +#include "macro.h" + +typedef struct dual_timestamp { +        usec_t realtime; +        usec_t monotonic; +} dual_timestamp; + +typedef struct triple_timestamp { +        usec_t realtime; +        usec_t monotonic; +        usec_t boottime; +} triple_timestamp; + +#define USEC_INFINITY ((usec_t) -1) +#define NSEC_INFINITY ((nsec_t) -1) + +#define MSEC_PER_SEC  1000ULL +#define USEC_PER_SEC  ((usec_t) 1000000ULL) +#define USEC_PER_MSEC ((usec_t) 1000ULL) +#define NSEC_PER_SEC  ((nsec_t) 1000000000ULL) +#define NSEC_PER_MSEC ((nsec_t) 1000000ULL) +#define NSEC_PER_USEC ((nsec_t) 1000ULL) + +#define USEC_PER_MINUTE ((usec_t) (60ULL*USEC_PER_SEC)) +#define NSEC_PER_MINUTE ((nsec_t) (60ULL*NSEC_PER_SEC)) +#define USEC_PER_HOUR ((usec_t) (60ULL*USEC_PER_MINUTE)) +#define NSEC_PER_HOUR ((nsec_t) (60ULL*NSEC_PER_MINUTE)) +#define USEC_PER_DAY ((usec_t) (24ULL*USEC_PER_HOUR)) +#define NSEC_PER_DAY ((nsec_t) (24ULL*NSEC_PER_HOUR)) +#define USEC_PER_WEEK ((usec_t) (7ULL*USEC_PER_DAY)) +#define NSEC_PER_WEEK ((nsec_t) (7ULL*NSEC_PER_DAY)) +#define USEC_PER_MONTH ((usec_t) (2629800ULL*USEC_PER_SEC)) +#define NSEC_PER_MONTH ((nsec_t) (2629800ULL*NSEC_PER_SEC)) +#define USEC_PER_YEAR ((usec_t) (31557600ULL*USEC_PER_SEC)) +#define NSEC_PER_YEAR ((nsec_t) (31557600ULL*NSEC_PER_SEC)) + +/* We assume a maximum timezone length of 6. TZNAME_MAX is not defined on Linux, but glibc internally initializes this + * to 6. Let's rely on that. */ +#define FORMAT_TIMESTAMP_MAX (3+1+10+1+8+1+6+1+6+1) +#define FORMAT_TIMESTAMP_WIDTH 28 /* when outputting, assume this width */ +#define FORMAT_TIMESTAMP_RELATIVE_MAX 256 +#define FORMAT_TIMESPAN_MAX 64 + +#define TIME_T_MAX (time_t)((UINTMAX_C(1) << ((sizeof(time_t) << 3) - 1)) - 1) + +#define DUAL_TIMESTAMP_NULL ((struct dual_timestamp) {}) +#define TRIPLE_TIMESTAMP_NULL ((struct triple_timestamp) {}) + +usec_t now(clockid_t clock); +nsec_t now_nsec(clockid_t clock); + +dual_timestamp* dual_timestamp_get(dual_timestamp *ts); +dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u); +dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u); +dual_timestamp* dual_timestamp_from_boottime_or_monotonic(dual_timestamp *ts, usec_t u); + +triple_timestamp* triple_timestamp_get(triple_timestamp *ts); +triple_timestamp* triple_timestamp_from_realtime(triple_timestamp *ts, usec_t u); + +#define DUAL_TIMESTAMP_HAS_CLOCK(clock)                               \ +        IN_SET(clock, CLOCK_REALTIME, CLOCK_REALTIME_ALARM, CLOCK_MONOTONIC) + +#define TRIPLE_TIMESTAMP_HAS_CLOCK(clock)                               \ +        IN_SET(clock, CLOCK_REALTIME, CLOCK_REALTIME_ALARM, CLOCK_MONOTONIC, CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM) + +static inline bool dual_timestamp_is_set(dual_timestamp *ts) { +        return ((ts->realtime > 0 && ts->realtime != USEC_INFINITY) || +                (ts->monotonic > 0 && ts->monotonic != USEC_INFINITY)); +} + +static inline bool triple_timestamp_is_set(triple_timestamp *ts) { +        return ((ts->realtime > 0 && ts->realtime != USEC_INFINITY) || +                (ts->monotonic > 0 && ts->monotonic != USEC_INFINITY) || +                (ts->boottime > 0 && ts->boottime != USEC_INFINITY)); +} + +usec_t triple_timestamp_by_clock(triple_timestamp *ts, clockid_t clock); + +usec_t timespec_load(const struct timespec *ts) _pure_; +nsec_t timespec_load_nsec(const struct timespec *ts) _pure_; +struct timespec *timespec_store(struct timespec *ts, usec_t u); + +usec_t timeval_load(const struct timeval *tv) _pure_; +struct timeval *timeval_store(struct timeval *tv, usec_t u); + +char *format_timestamp(char *buf, size_t l, usec_t t); +char *format_timestamp_utc(char *buf, size_t l, usec_t t); +char *format_timestamp_us(char *buf, size_t l, usec_t t); +char *format_timestamp_us_utc(char *buf, size_t l, usec_t t); +char *format_timestamp_relative(char *buf, size_t l, usec_t t); +char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy); + +void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t); +int dual_timestamp_deserialize(const char *value, dual_timestamp *t); +int timestamp_deserialize(const char *value, usec_t *timestamp); + +int parse_timestamp(const char *t, usec_t *usec); + +int parse_sec(const char *t, usec_t *usec); +int parse_time(const char *t, usec_t *usec, usec_t default_unit); +int parse_nsec(const char *t, nsec_t *nsec); + +bool ntp_synced(void); + +int get_timezones(char ***l); +bool timezone_is_valid(const char *name); + +bool clock_boottime_supported(void); +bool clock_supported(clockid_t clock); +clockid_t clock_boottime_or_monotonic(void); + +#define xstrftime(buf, fmt, tm) \ +        assert_message_se(strftime(buf, ELEMENTSOF(buf), fmt, tm) > 0, \ +                          "xstrftime: " #buf "[] must be big enough") + +int get_timezone(char **timezone); + +time_t mktime_or_timegm(struct tm *tm, bool utc); +struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc); + +unsigned long usec_to_jiffies(usec_t usec); + +static inline usec_t usec_add(usec_t a, usec_t b) { +        usec_t c; + +        /* Adds two time values, and makes sure USEC_INFINITY as input results as USEC_INFINITY in output, and doesn't +         * overflow. */ + +        c = a + b; +        if (c < a || c < b) /* overflow check */ +                return USEC_INFINITY; + +        return c; +} + +static inline usec_t usec_sub(usec_t timestamp, int64_t delta) { +        if (delta < 0) +                return usec_add(timestamp, (usec_t) (-delta)); + +        if (timestamp == USEC_INFINITY) /* Make sure infinity doesn't degrade */ +                return USEC_INFINITY; + +        if (timestamp < (usec_t) delta) +                return 0; + +        return timestamp - delta; +} diff --git a/src/libsystemd-basic/include/systemd-basic/umask-util.h b/src/libsystemd-basic/include/systemd-basic/umask-util.h new file mode 100644 index 0000000000..359d87d27c --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/umask-util.h @@ -0,0 +1,46 @@ +#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/stat.h> +#include <sys/types.h> + +#include "macro.h" + +static inline void umaskp(mode_t *u) { +        umask(*u); +} + +#define _cleanup_umask_ _cleanup_(umaskp) + +struct _umask_struct_ { +        mode_t mask; +        bool quit; +}; + +static inline void _reset_umask_(struct _umask_struct_ *s) { +        umask(s->mask); +}; + +#define RUN_WITH_UMASK(mask)                                            \ +        for (_cleanup_(_reset_umask_) struct _umask_struct_ _saved_umask_ = { umask(mask), false }; \ +             !_saved_umask_.quit ;                                      \ +             _saved_umask_.quit = true) diff --git a/src/libsystemd-basic/include/systemd-basic/unaligned.h b/src/libsystemd-basic/include/systemd-basic/unaligned.h new file mode 100644 index 0000000000..7c847a3ccb --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/unaligned.h @@ -0,0 +1,129 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2014 Tom Gundersen + +  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 <endian.h> +#include <stdint.h> + +/* BE */ + +static inline uint16_t unaligned_read_be16(const void *_u) { +        const uint8_t *u = _u; + +        return (((uint16_t) u[0]) << 8) | +                ((uint16_t) u[1]); +} + +static inline uint32_t unaligned_read_be32(const void *_u) { +        const uint8_t *u = _u; + +        return (((uint32_t) unaligned_read_be16(u)) << 16) | +                ((uint32_t) unaligned_read_be16(u + 2)); +} + +static inline uint64_t unaligned_read_be64(const void *_u) { +        const uint8_t *u = _u; + +        return (((uint64_t) unaligned_read_be32(u)) << 32) | +                ((uint64_t) unaligned_read_be32(u + 4)); +} + +static inline void unaligned_write_be16(void *_u, uint16_t a) { +        uint8_t *u = _u; + +        u[0] = (uint8_t) (a >> 8); +        u[1] = (uint8_t) a; +} + +static inline void unaligned_write_be32(void *_u, uint32_t a) { +        uint8_t *u = _u; + +        unaligned_write_be16(u, (uint16_t) (a >> 16)); +        unaligned_write_be16(u + 2, (uint16_t) a); +} + +static inline void unaligned_write_be64(void *_u, uint64_t a) { +        uint8_t *u = _u; + +        unaligned_write_be32(u, (uint32_t) (a >> 32)); +        unaligned_write_be32(u + 4, (uint32_t) a); +} + +/* LE */ + +static inline uint16_t unaligned_read_le16(const void *_u) { +        const uint8_t *u = _u; + +        return (((uint16_t) u[1]) << 8) | +                ((uint16_t) u[0]); +} + +static inline uint32_t unaligned_read_le32(const void *_u) { +        const uint8_t *u = _u; + +        return (((uint32_t) unaligned_read_le16(u + 2)) << 16) | +                ((uint32_t) unaligned_read_le16(u)); +} + +static inline uint64_t unaligned_read_le64(const void *_u) { +        const uint8_t *u = _u; + +        return (((uint64_t) unaligned_read_le32(u + 4)) << 32) | +                ((uint64_t) unaligned_read_le32(u)); +} + +static inline void unaligned_write_le16(void *_u, uint16_t a) { +        uint8_t *u = _u; + +        u[0] = (uint8_t) a; +        u[1] = (uint8_t) (a >> 8); +} + +static inline void unaligned_write_le32(void *_u, uint32_t a) { +        uint8_t *u = _u; + +        unaligned_write_le16(u, (uint16_t) a); +        unaligned_write_le16(u + 2, (uint16_t) (a >> 16)); +} + +static inline void unaligned_write_le64(void *_u, uint64_t a) { +        uint8_t *u = _u; + +        unaligned_write_le32(u, (uint32_t) a); +        unaligned_write_le32(u + 4, (uint32_t) (a >> 32)); +} + +#if __BYTE_ORDER == __BIG_ENDIAN +#define unaligned_read_ne16 unaligned_read_be16 +#define unaligned_read_ne32 unaligned_read_be32 +#define unaligned_read_ne64 unaligned_read_be64 + +#define unaligned_write_ne16 unaligned_write_be16 +#define unaligned_write_ne32 unaligned_write_be32 +#define unaligned_write_ne64 unaligned_write_be64 +#else +#define unaligned_read_ne16 unaligned_read_le16 +#define unaligned_read_ne32 unaligned_read_le32 +#define unaligned_read_ne64 unaligned_read_le64 + +#define unaligned_write_ne16 unaligned_write_le16 +#define unaligned_write_ne32 unaligned_write_le32 +#define unaligned_write_ne64 unaligned_write_le64 +#endif diff --git a/src/libsystemd-basic/include/systemd-basic/unit-name.h b/src/libsystemd-basic/include/systemd-basic/unit-name.h new file mode 100644 index 0000000000..44eadf0347 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/unit-name.h @@ -0,0 +1,367 @@ +#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 "macro.h" + +#define UNIT_NAME_MAX 256 + +typedef enum UnitType { +        UNIT_SERVICE = 0, +        UNIT_SOCKET, +        UNIT_BUSNAME, +        UNIT_TARGET, +        UNIT_DEVICE, +        UNIT_MOUNT, +        UNIT_AUTOMOUNT, +        UNIT_SWAP, +        UNIT_TIMER, +        UNIT_PATH, +        UNIT_SLICE, +        UNIT_SCOPE, +        _UNIT_TYPE_MAX, +        _UNIT_TYPE_INVALID = -1 +} UnitType; + +typedef enum UnitLoadState { +        UNIT_STUB = 0, +        UNIT_LOADED, +        UNIT_NOT_FOUND, +        UNIT_ERROR, +        UNIT_MERGED, +        UNIT_MASKED, +        _UNIT_LOAD_STATE_MAX, +        _UNIT_LOAD_STATE_INVALID = -1 +} UnitLoadState; + +typedef enum UnitActiveState { +        UNIT_ACTIVE, +        UNIT_RELOADING, +        UNIT_INACTIVE, +        UNIT_FAILED, +        UNIT_ACTIVATING, +        UNIT_DEACTIVATING, +        _UNIT_ACTIVE_STATE_MAX, +        _UNIT_ACTIVE_STATE_INVALID = -1 +} UnitActiveState; + +typedef enum AutomountState { +        AUTOMOUNT_DEAD, +        AUTOMOUNT_WAITING, +        AUTOMOUNT_RUNNING, +        AUTOMOUNT_FAILED, +        _AUTOMOUNT_STATE_MAX, +        _AUTOMOUNT_STATE_INVALID = -1 +} AutomountState; + +typedef enum BusNameState { +        BUSNAME_DEAD, +        BUSNAME_MAKING, +        BUSNAME_REGISTERED, +        BUSNAME_LISTENING, +        BUSNAME_RUNNING, +        BUSNAME_SIGTERM, +        BUSNAME_SIGKILL, +        BUSNAME_FAILED, +        _BUSNAME_STATE_MAX, +        _BUSNAME_STATE_INVALID = -1 +} BusNameState; + +/* We simply watch devices, we cannot plug/unplug them. That + * simplifies the state engine greatly */ +typedef enum DeviceState { +        DEVICE_DEAD, +        DEVICE_TENTATIVE, /* mounted or swapped, but not (yet) announced by udev */ +        DEVICE_PLUGGED,   /* announced by udev */ +        _DEVICE_STATE_MAX, +        _DEVICE_STATE_INVALID = -1 +} DeviceState; + +typedef enum MountState { +        MOUNT_DEAD, +        MOUNT_MOUNTING,               /* /usr/bin/mount is running, but the mount is not done yet. */ +        MOUNT_MOUNTING_DONE,          /* /usr/bin/mount is running, and the mount is done. */ +        MOUNT_MOUNTED, +        MOUNT_REMOUNTING, +        MOUNT_UNMOUNTING, +        MOUNT_MOUNTING_SIGTERM, +        MOUNT_MOUNTING_SIGKILL, +        MOUNT_REMOUNTING_SIGTERM, +        MOUNT_REMOUNTING_SIGKILL, +        MOUNT_UNMOUNTING_SIGTERM, +        MOUNT_UNMOUNTING_SIGKILL, +        MOUNT_FAILED, +        _MOUNT_STATE_MAX, +        _MOUNT_STATE_INVALID = -1 +} MountState; + +typedef enum PathState { +        PATH_DEAD, +        PATH_WAITING, +        PATH_RUNNING, +        PATH_FAILED, +        _PATH_STATE_MAX, +        _PATH_STATE_INVALID = -1 +} PathState; + +typedef enum ScopeState { +        SCOPE_DEAD, +        SCOPE_RUNNING, +        SCOPE_ABANDONED, +        SCOPE_STOP_SIGTERM, +        SCOPE_STOP_SIGKILL, +        SCOPE_FAILED, +        _SCOPE_STATE_MAX, +        _SCOPE_STATE_INVALID = -1 +} ScopeState; + +typedef enum ServiceState { +        SERVICE_DEAD, +        SERVICE_START_PRE, +        SERVICE_START, +        SERVICE_START_POST, +        SERVICE_RUNNING, +        SERVICE_EXITED,            /* Nothing is running anymore, but RemainAfterExit is true hence this is OK */ +        SERVICE_RELOAD, +        SERVICE_STOP,              /* No STOP_PRE state, instead just register multiple STOP executables */ +        SERVICE_STOP_SIGABRT,      /* Watchdog timeout */ +        SERVICE_STOP_SIGTERM, +        SERVICE_STOP_SIGKILL, +        SERVICE_STOP_POST, +        SERVICE_FINAL_SIGTERM,     /* In case the STOP_POST executable hangs, we shoot that down, too */ +        SERVICE_FINAL_SIGKILL, +        SERVICE_FAILED, +        SERVICE_AUTO_RESTART, +        _SERVICE_STATE_MAX, +        _SERVICE_STATE_INVALID = -1 +} ServiceState; + +typedef enum SliceState { +        SLICE_DEAD, +        SLICE_ACTIVE, +        _SLICE_STATE_MAX, +        _SLICE_STATE_INVALID = -1 +} SliceState; + +typedef enum SocketState { +        SOCKET_DEAD, +        SOCKET_START_PRE, +        SOCKET_START_CHOWN, +        SOCKET_START_POST, +        SOCKET_LISTENING, +        SOCKET_RUNNING, +        SOCKET_STOP_PRE, +        SOCKET_STOP_PRE_SIGTERM, +        SOCKET_STOP_PRE_SIGKILL, +        SOCKET_STOP_POST, +        SOCKET_FINAL_SIGTERM, +        SOCKET_FINAL_SIGKILL, +        SOCKET_FAILED, +        _SOCKET_STATE_MAX, +        _SOCKET_STATE_INVALID = -1 +} SocketState; + +typedef enum SwapState { +        SWAP_DEAD, +        SWAP_ACTIVATING,               /* /sbin/swapon is running, but the swap not yet enabled. */ +        SWAP_ACTIVATING_DONE,          /* /sbin/swapon is running, and the swap is done. */ +        SWAP_ACTIVE, +        SWAP_DEACTIVATING, +        SWAP_ACTIVATING_SIGTERM, +        SWAP_ACTIVATING_SIGKILL, +        SWAP_DEACTIVATING_SIGTERM, +        SWAP_DEACTIVATING_SIGKILL, +        SWAP_FAILED, +        _SWAP_STATE_MAX, +        _SWAP_STATE_INVALID = -1 +} SwapState; + +typedef enum TargetState { +        TARGET_DEAD, +        TARGET_ACTIVE, +        _TARGET_STATE_MAX, +        _TARGET_STATE_INVALID = -1 +} TargetState; + +typedef enum TimerState { +        TIMER_DEAD, +        TIMER_WAITING, +        TIMER_RUNNING, +        TIMER_ELAPSED, +        TIMER_FAILED, +        _TIMER_STATE_MAX, +        _TIMER_STATE_INVALID = -1 +} TimerState; + +typedef enum UnitDependency { +        /* Positive dependencies */ +        UNIT_REQUIRES, +        UNIT_REQUISITE, +        UNIT_WANTS, +        UNIT_BINDS_TO, +        UNIT_PART_OF, + +        /* Inverse of the above */ +        UNIT_REQUIRED_BY,             /* inverse of 'requires' is 'required_by' */ +        UNIT_REQUISITE_OF,            /* inverse of 'requisite' is 'requisite_of' */ +        UNIT_WANTED_BY,               /* inverse of 'wants' */ +        UNIT_BOUND_BY,                /* inverse of 'binds_to' */ +        UNIT_CONSISTS_OF,             /* inverse of 'part_of' */ + +        /* Negative dependencies */ +        UNIT_CONFLICTS,               /* inverse of 'conflicts' is 'conflicted_by' */ +        UNIT_CONFLICTED_BY, + +        /* Order */ +        UNIT_BEFORE,                  /* inverse of 'before' is 'after' and vice versa */ +        UNIT_AFTER, + +        /* On Failure */ +        UNIT_ON_FAILURE, + +        /* Triggers (i.e. a socket triggers a service) */ +        UNIT_TRIGGERS, +        UNIT_TRIGGERED_BY, + +        /* Propagate reloads */ +        UNIT_PROPAGATES_RELOAD_TO, +        UNIT_RELOAD_PROPAGATED_FROM, + +        /* Joins namespace of */ +        UNIT_JOINS_NAMESPACE_OF, + +        /* Reference information for GC logic */ +        UNIT_REFERENCES,              /* Inverse of 'references' is 'referenced_by' */ +        UNIT_REFERENCED_BY, + +        _UNIT_DEPENDENCY_MAX, +        _UNIT_DEPENDENCY_INVALID = -1 +} UnitDependency; + +typedef enum UnitNameFlags { +        UNIT_NAME_PLAIN = 1,      /* Allow foo.service */ +        UNIT_NAME_INSTANCE = 2,   /* Allow foo@bar.service */ +        UNIT_NAME_TEMPLATE = 4,   /* Allow foo@.service */ +        UNIT_NAME_ANY = UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE|UNIT_NAME_TEMPLATE, +} UnitNameFlags; + +bool unit_name_is_valid(const char *n, UnitNameFlags flags) _pure_; +bool unit_prefix_is_valid(const char *p) _pure_; +bool unit_instance_is_valid(const char *i) _pure_; +bool unit_suffix_is_valid(const char *s) _pure_; + +static inline int unit_prefix_and_instance_is_valid(const char *p) { +        /* For prefix+instance and instance the same rules apply */ +        return unit_instance_is_valid(p); +} + +int unit_name_to_prefix(const char *n, char **prefix); +int unit_name_to_instance(const char *n, char **instance); +int unit_name_to_prefix_and_instance(const char *n, char **ret); + +UnitType unit_name_to_type(const char *n) _pure_; + +int unit_name_change_suffix(const char *n, const char *suffix, char **ret); + +int unit_name_build(const char *prefix, const char *instance, const char *suffix, char **ret); + +char *unit_name_escape(const char *f); +int unit_name_unescape(const char *f, char **ret); +int unit_name_path_escape(const char *f, char **ret); +int unit_name_path_unescape(const char *f, char **ret); + +int unit_name_replace_instance(const char *f, const char *i, char **ret); + +int unit_name_template(const char *f, char **ret); + +int unit_name_from_path(const char *path, const char *suffix, char **ret); +int unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix, char **ret); +int unit_name_to_path(const char *name, char **ret); + +char *unit_dbus_path_from_name(const char *name); +int unit_name_from_dbus_path(const char *path, char **name); + +const char* unit_dbus_interface_from_type(UnitType t); +const char *unit_dbus_interface_from_name(const char *name); + +typedef enum UnitNameMangle { +        UNIT_NAME_NOGLOB, +        UNIT_NAME_GLOB, +} UnitNameMangle; + +int unit_name_mangle_with_suffix(const char *name, UnitNameMangle allow_globs, const char *suffix, char **ret); + +static inline int unit_name_mangle(const char *name, UnitNameMangle allow_globs, char **ret) { +        return unit_name_mangle_with_suffix(name, allow_globs, ".service", ret); +} + +int slice_build_parent_slice(const char *slice, char **ret); +int slice_build_subslice(const char *slice, const char*name, char **subslice); +bool slice_name_is_valid(const char *name); + +const char *unit_type_to_string(UnitType i) _const_; +UnitType unit_type_from_string(const char *s) _pure_; + +const char *unit_load_state_to_string(UnitLoadState i) _const_; +UnitLoadState unit_load_state_from_string(const char *s) _pure_; + +const char *unit_active_state_to_string(UnitActiveState i) _const_; +UnitActiveState unit_active_state_from_string(const char *s) _pure_; + +const char* automount_state_to_string(AutomountState i) _const_; +AutomountState automount_state_from_string(const char *s) _pure_; + +const char* busname_state_to_string(BusNameState i) _const_; +BusNameState busname_state_from_string(const char *s) _pure_; + +const char* device_state_to_string(DeviceState i) _const_; +DeviceState device_state_from_string(const char *s) _pure_; + +const char* mount_state_to_string(MountState i) _const_; +MountState mount_state_from_string(const char *s) _pure_; + +const char* path_state_to_string(PathState i) _const_; +PathState path_state_from_string(const char *s) _pure_; + +const char* scope_state_to_string(ScopeState i) _const_; +ScopeState scope_state_from_string(const char *s) _pure_; + +const char* service_state_to_string(ServiceState i) _const_; +ServiceState service_state_from_string(const char *s) _pure_; + +const char* slice_state_to_string(SliceState i) _const_; +SliceState slice_state_from_string(const char *s) _pure_; + +const char* socket_state_to_string(SocketState i) _const_; +SocketState socket_state_from_string(const char *s) _pure_; + +const char* swap_state_to_string(SwapState i) _const_; +SwapState swap_state_from_string(const char *s) _pure_; + +const char* target_state_to_string(TargetState i) _const_; +TargetState target_state_from_string(const char *s) _pure_; + +const char *timer_state_to_string(TimerState i) _const_; +TimerState timer_state_from_string(const char *s) _pure_; + +const char *unit_dependency_to_string(UnitDependency i) _const_; +UnitDependency unit_dependency_from_string(const char *s) _pure_; diff --git a/src/libsystemd-basic/include/systemd-basic/user-util.h b/src/libsystemd-basic/include/systemd-basic/user-util.h new file mode 100644 index 0000000000..dfea561bde --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/user-util.h @@ -0,0 +1,90 @@ +#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 <stdint.h> +#include <sys/types.h> +#include <unistd.h> + +bool uid_is_valid(uid_t uid); + +static inline bool gid_is_valid(gid_t gid) { +        return uid_is_valid((uid_t) gid); +} + +int parse_uid(const char *s, uid_t* ret_uid); + +static inline int parse_gid(const char *s, gid_t *ret_gid) { +        return parse_uid(s, (uid_t*) ret_gid); +} + +char* getlogname_malloc(void); +char* getusername_malloc(void); + +int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell); +int get_user_creds_clean(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell); +int get_group_creds(const char **groupname, gid_t *gid); + +char* uid_to_name(uid_t uid); +char* gid_to_name(gid_t gid); + +int in_gid(gid_t gid); +int in_group(const char *name); + +int get_home_dir(char **ret); +int get_shell(char **_ret); + +int reset_uid_gid(void); + +int take_etc_passwd_lock(const char *root); + +#define UID_INVALID ((uid_t) -1) +#define GID_INVALID ((gid_t) -1) + +/* Let's pick a UIDs within the 16bit range, so that we are compatible with containers using 16bit + * user namespacing. At least on Fedora normal users are allocated until UID 60000, hence do not + * allocate from below this. Also stay away from the upper end of the range as that is often used + * for overflow/nobody users. */ +#define DYNAMIC_UID_MIN ((uid_t) UINT32_C(0x0000EF00)) +#define DYNAMIC_UID_MAX ((uid_t) UINT32_C(0x0000FFEF)) + +static inline bool uid_is_dynamic(uid_t uid) { +        return DYNAMIC_UID_MIN <= uid && uid <= DYNAMIC_UID_MAX; +} + +/* The following macros add 1 when converting things, since UID 0 is a valid UID, while the pointer + * NULL is special */ +#define PTR_TO_UID(p) ((uid_t) (((uintptr_t) (p))-1)) +#define UID_TO_PTR(u) ((void*) (((uintptr_t) (u))+1)) + +#define PTR_TO_GID(p) ((gid_t) (((uintptr_t) (p))-1)) +#define GID_TO_PTR(u) ((void*) (((uintptr_t) (u))+1)) + +static inline bool userns_supported(void) { +        return access("/proc/self/uid_map", F_OK) >= 0; +} + +bool valid_user_group_name(const char *u); +bool valid_user_group_name_or_id(const char *u); +bool valid_gecos(const char *d); +bool valid_home(const char *p); + +int maybe_setgroups(size_t size, const gid_t *list); diff --git a/src/libsystemd-basic/include/systemd-basic/utf8.h b/src/libsystemd-basic/include/systemd-basic/utf8.h new file mode 100644 index 0000000000..f9b9c9468b --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/utf8.h @@ -0,0 +1,60 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2012 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 <stddef.h> +#include <stdint.h> +#include <uchar.h> + +#include "macro.h" +#include "missing.h" + +#define UTF8_REPLACEMENT_CHARACTER "\xef\xbf\xbd" +#define UTF8_BYTE_ORDER_MARK "\xef\xbb\xbf" + +bool unichar_is_valid(char32_t c); + +const char *utf8_is_valid(const char *s) _pure_; +char *ascii_is_valid(const char *s) _pure_; + +bool utf8_is_printable_newline(const char* str, size_t length, bool newline) _pure_; +#define utf8_is_printable(str, length) utf8_is_printable_newline(str, length, true) + +char *utf8_escape_invalid(const char *s); +char *utf8_escape_non_printable(const char *str); + +size_t utf8_encode_unichar(char *out_utf8, char32_t g); +char *utf16_to_utf8(const void *s, size_t length); + +int utf8_encoded_valid_unichar(const char *str); +int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar); + +static inline bool utf16_is_surrogate(char16_t c) { +        return (0xd800 <= c && c <= 0xdfff); +} + +static inline bool utf16_is_trailing_surrogate(char16_t c) { +        return (0xdc00 <= c && c <= 0xdfff); +} + +static inline char32_t utf16_surrogate_pair_to_unichar(char16_t lead, char16_t trail) { +                return ((lead - 0xd800) << 10) + (trail - 0xdc00) + 0x10000; +} diff --git a/src/libsystemd-basic/include/systemd-basic/util.h b/src/libsystemd-basic/include/systemd-basic/util.h new file mode 100644 index 0000000000..bb2fc318ef --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/util.h @@ -0,0 +1,196 @@ +#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 <alloca.h> +#include <errno.h> +#include <fcntl.h> +#include <inttypes.h> +#include <limits.h> +#include <locale.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/inotify.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/statfs.h> +#include <sys/sysmacros.h> +#include <sys/types.h> +#include <time.h> +#include <unistd.h> + +#include "formats-util.h" +#include "macro.h" +#include "missing.h" +#include "time-util.h" + +size_t page_size(void) _pure_; +#define PAGE_ALIGN(l) ALIGN_TO((l), page_size()) + +static inline const char* yes_no(bool b) { +        return b ? "yes" : "no"; +} + +static inline const char* true_false(bool b) { +        return b ? "true" : "false"; +} + +static inline const char* one_zero(bool b) { +        return b ? "1" : "0"; +} + +static inline const char* enable_disable(bool b) { +        return b ? "enable" : "disable"; +} + +void execute_directories(const char* const* directories, usec_t timeout, char *argv[]); + +bool plymouth_running(void); + +bool display_is_local(const char *display) _pure_; +int socket_from_display(const char *display, char **path); + +int block_get_whole_disk(dev_t d, dev_t *ret); + +#define NULSTR_FOREACH(i, l)                                    \ +        for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) + +#define NULSTR_FOREACH_PAIR(i, j, l)                             \ +        for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i)) + +extern int saved_argc; +extern char **saved_argv; + +bool kexec_loaded(void); + +int prot_from_flags(int flags) _const_; + +int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...); + +bool in_initrd(void); +void in_initrd_force(bool value); + +void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, +                 int (*compar) (const void *, const void *, void *), +                 void *arg); + +/** + * Normal qsort requires base to be nonnull. Here were require + * that only if nmemb > 0. + */ +static inline void qsort_safe(void *base, size_t nmemb, size_t size, comparison_fn_t compar) { +        if (nmemb <= 1) +                return; + +        assert(base); +        qsort(base, nmemb, size, compar); +} + +/** + * Normal memcpy requires src to be nonnull. We do nothing if n is 0. + */ +static inline void memcpy_safe(void *dst, const void *src, size_t n) { +        if (n == 0) +                return; +        assert(src); +        memcpy(dst, src, n); +} + +int on_ac_power(void); + +#define memzero(x,l) (memset((x), 0, (l))) +#define zero(x) (memzero(&(x), sizeof(x))) + +static inline void *mempset(void *s, int c, size_t n) { +        memset(s, c, n); +        return (uint8_t*)s + n; +} + +static inline void _reset_errno_(int *saved_errno) { +        errno = *saved_errno; +} + +#define PROTECT_ERRNO _cleanup_(_reset_errno_) __attribute__((unused)) int _saved_errno_ = errno + +static inline int negative_errno(void) { +        /* This helper should be used to shut up gcc if you know 'errno' is +         * negative. Instead of "return -errno;", use "return negative_errno();" +         * It will suppress bogus gcc warnings in case it assumes 'errno' might +         * be 0 and thus the caller's error-handling might not be triggered. */ +        assert_return(errno > 0, -EINVAL); +        return -errno; +} + +static inline unsigned u64log2(uint64_t n) { +#if __SIZEOF_LONG_LONG__ == 8 +        return (n > 1) ? (unsigned) __builtin_clzll(n) ^ 63U : 0; +#else +#error "Wut?" +#endif +} + +static inline unsigned u32ctz(uint32_t n) { +#if __SIZEOF_INT__ == 4 +        return __builtin_ctz(n); +#else +#error "Wut?" +#endif +} + +static inline unsigned log2i(int x) { +        assert(x > 0); + +        return __SIZEOF_INT__ * 8 - __builtin_clz(x) - 1; +} + +static inline unsigned log2u(unsigned x) { +        assert(x > 0); + +        return sizeof(unsigned) * 8 - __builtin_clz(x) - 1; +} + +static inline unsigned log2u_round_up(unsigned x) { +        assert(x > 0); + +        if (x == 1) +                return 0; + +        return log2u(x - 1) + 1; +} + +int container_get_leader(const char *machine, pid_t *pid); + +int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd); +int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd); + +uint64_t physical_memory(void); +uint64_t physical_memory_scale(uint64_t v, uint64_t max); + +uint64_t system_tasks_max(void); +uint64_t system_tasks_max_scale(uint64_t v, uint64_t max); + +int update_reboot_parameter_and_warn(const char *param); + +int version(void); diff --git a/src/libsystemd-basic/include/systemd-basic/verbs.h b/src/libsystemd-basic/include/systemd-basic/verbs.h new file mode 100644 index 0000000000..7b5e18510f --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/verbs.h @@ -0,0 +1,33 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2014 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/>. +***/ + +#define VERB_ANY ((unsigned) -1) +#define VERB_DEFAULT 1U +#define VERB_NOCHROOT 2U + +typedef struct { +        const char *verb; +        unsigned min_args, max_args; +        unsigned flags; +        int (* const dispatch)(int argc, char *argv[], void *userdata); +} Verb; + +int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata); diff --git a/src/libsystemd-basic/include/systemd-basic/virt.h b/src/libsystemd-basic/include/systemd-basic/virt.h new file mode 100644 index 0000000000..7d15169112 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/virt.h @@ -0,0 +1,74 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2011 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 "macro.h" + +enum { +        VIRTUALIZATION_NONE = 0, + +        VIRTUALIZATION_VM_FIRST, +        VIRTUALIZATION_KVM = VIRTUALIZATION_VM_FIRST, +        VIRTUALIZATION_QEMU, +        VIRTUALIZATION_BOCHS, +        VIRTUALIZATION_XEN, +        VIRTUALIZATION_UML, +        VIRTUALIZATION_VMWARE, +        VIRTUALIZATION_ORACLE, +        VIRTUALIZATION_MICROSOFT, +        VIRTUALIZATION_ZVM, +        VIRTUALIZATION_PARALLELS, +        VIRTUALIZATION_BHYVE, +        VIRTUALIZATION_VM_OTHER, +        VIRTUALIZATION_VM_LAST = VIRTUALIZATION_VM_OTHER, + +        VIRTUALIZATION_CONTAINER_FIRST, +        VIRTUALIZATION_SYSTEMD_NSPAWN = VIRTUALIZATION_CONTAINER_FIRST, +        VIRTUALIZATION_LXC_LIBVIRT, +        VIRTUALIZATION_LXC, +        VIRTUALIZATION_OPENVZ, +        VIRTUALIZATION_DOCKER, +        VIRTUALIZATION_RKT, +        VIRTUALIZATION_CONTAINER_OTHER, +        VIRTUALIZATION_CONTAINER_LAST = VIRTUALIZATION_CONTAINER_OTHER, + +        _VIRTUALIZATION_MAX, +        _VIRTUALIZATION_INVALID = -1 +}; + +static inline bool VIRTUALIZATION_IS_VM(int x) { +        return x >= VIRTUALIZATION_VM_FIRST && x <= VIRTUALIZATION_VM_LAST; +} + +static inline bool VIRTUALIZATION_IS_CONTAINER(int x) { +        return x >= VIRTUALIZATION_CONTAINER_FIRST && x <= VIRTUALIZATION_CONTAINER_LAST; +} + +int detect_vm(void); +int detect_container(void); +int detect_virtualization(void); + +int running_in_userns(void); +int running_in_chroot(void); + +const char *virtualization_to_string(int v) _const_; +int virtualization_from_string(const char *s) _pure_; diff --git a/src/libsystemd-basic/include/systemd-basic/web-util.h b/src/libsystemd-basic/include/systemd-basic/web-util.h new file mode 100644 index 0000000000..e6bb6b53f5 --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/web-util.h @@ -0,0 +1,30 @@ +#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 "macro.h" + +bool http_url_is_valid(const char *url) _pure_; + +bool documentation_url_is_valid(const char *url) _pure_; + +bool http_etag_is_valid(const char *etag); diff --git a/src/libsystemd-basic/include/systemd-basic/xattr-util.h b/src/libsystemd-basic/include/systemd-basic/xattr-util.h new file mode 100644 index 0000000000..6fa097bf7e --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/xattr-util.h @@ -0,0 +1,37 @@ +#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 <stddef.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); diff --git a/src/libsystemd-basic/include/systemd-basic/xml.h b/src/libsystemd-basic/include/systemd-basic/xml.h new file mode 100644 index 0000000000..41cb69f0dc --- /dev/null +++ b/src/libsystemd-basic/include/systemd-basic/xml.h @@ -0,0 +1,32 @@ +#pragma once + +/*** +  This file is part of systemd. + +  Copyright 2013 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/>. +***/ + +enum { +        XML_END, +        XML_TEXT, +        XML_TAG_OPEN, +        XML_TAG_CLOSE, +        XML_TAG_CLOSE_EMPTY, +        XML_ATTRIBUTE_NAME, +        XML_ATTRIBUTE_VALUE, +}; + +int xml_tokenize(const char **p, char **name, void **state, unsigned *line); | 
