Commit Graph
500 Commits
Author SHA1 Message Date
Yu Watanabe a74b3e1778 dlopen-note: move all dlopen notes to dlopen-note.h
This also switches all these notes to be defined via SD_ELF_NOTE_DLOPEN_ANCHORED().
Consequently, any notes added within unreachable or unused functions will be
automatically garbage-collected by the linker (--gc-sections) instead of
bloating the final binary.

E.g. unused p11-kit library dependency is now dropped from
systemd-repart.standalone binary.

Before:
```
$ systemd-analyze dlopen-metadata build/systemd-repart.standalone
FEATURE    DESCRIPTION                                                SONAME                        PRIORITY
cryptsetup Support for disk encryption, integrity, and authentication libcryptsetup.so.12           recommended
blkid      Support for block device identification                    libblkid.so.1                 required
libcrypto  Support for cryptographic operations                       libcrypto.so.4 libcrypto.so.3 recommended
mount      Support for mount enumeration                              libmount.so.1                 required
fdisk      Support for reading and writing partition tables           libfdisk.so.1                 required
blkid      Support for block device identification                    libblkid.so.1                 recommended
libcrypto  Support for cryptographic operations                       libcrypto.so.4 libcrypto.so.3 suggested
cryptsetup Support for disk encryption, integrity, and authentication libcryptsetup.so.12           suggested
fdisk      Support for reading and writing partition tables           libfdisk.so.1                 suggested
idn        Support for internationalized domain names                 libidn2.so.0                  suggested
mount      Support for mount enumeration                              libmount.so.1                 recommended
selinux    Support for SELinux                                        libselinux.so.1               recommended
tpm        Support for TPM                                            libtss2-esys.so.0             suggested
tpm        Support for TPM                                            libtss2-rc.so.0               suggested
tpm        Support for TPM                                            libtss2-mu.so.0               suggested
tpm        Support for TPM                                            libtss2-tcti-device.so.0      suggested
p11-kit    Support for PKCS11 hardware tokens                         libp11-kit.so.0               suggested
```

After:
```
$ systemd-analyze dlopen-metadata build/systemd-repart.standalone
FEATURE    DESCRIPTION                                                SONAME                        PRIORITY
cryptsetup Support for disk encryption, integrity, and authentication libcryptsetup.so.12           recommended
blkid      Support for block device identification                    libblkid.so.1                 required
libcrypto  Support for cryptographic operations                       libcrypto.so.4 libcrypto.so.3 recommended
mount      Support for mount enumeration                              libmount.so.1                 required
fdisk      Support for reading and writing partition tables           libfdisk.so.1                 required
blkid      Support for block device identification                    libblkid.so.1                 recommended
libcrypto  Support for cryptographic operations                       libcrypto.so.4 libcrypto.so.3 suggested
cryptsetup Support for disk encryption, integrity, and authentication libcryptsetup.so.12           suggested
fdisk      Support for reading and writing partition tables           libfdisk.so.1                 suggested
mount      Support for mount enumeration                              libmount.so.1                 recommended
selinux    Support for SELinux                                        libselinux.so.1               recommended
tpm        Support for TPM                                            libtss2-esys.so.0             suggested
tpm        Support for TPM                                            libtss2-rc.so.0               suggested
tpm        Support for TPM                                            libtss2-mu.so.0               suggested
tpm        Support for TPM                                            libtss2-tcti-device.so.0      suggested
```
2026-07-10 16:34:26 +09:00
Zbigniew Jędrzejewski-Szmek aad1e61010 meson: adjust naming of '*extract*' variables 2026-07-07 13:40:13 +02:00
Zbigniew Jędrzejewski-Szmek f00ccf93b7 meson: rename extract+objects to export+import
We have two concepts: a list of files that should be extracted from an
intermediate build artifact to be used in a later build artifact, and for a
given artifact, a list "donors". The first list was called "extract", because
it is passed to the .extract_objects() meson function, and the second was
called "objects", because that is the meson parameter to specify pre-built
objects files (6350d2dbd9). But this naming is
confusing: we don't care about the 'extract' step, this is something internal
to the build machinery. And 'objects' is a very generic term.

Let's use 'export' for the stuff that is "exported" for other binaries to use,
and 'import' to say where to import from. Those terms are symmetrical and the
association between them should be intuitive. (If you think the terms are
actually assymetrical, there are precedents for confusing the import with the
import sources. E.g. in modern English, turkeys are called so because they were
imported from the Americas and guineafowls were imported from Africa via
Türkiye and all that foreign stuff is alike.)
2026-07-07 13:40:13 +02:00
Yu Watanabe 5280cd7bdb tree-wide: check if necessary cflags dependencies are set
This makes each `foo_cflags` dependency define a `SYSTEMD_CFLAGS_MARKER_FOO`
macro, and checks if the macro is set when headers provided by external
libraries are included.

With this, we can fail fast at compile time if necessary `_cflags`
dependencies are omitted in meson.build. Missing dependencies found by this
mechanism have been added across the tree.
2026-07-03 21:50:45 +09:00
Luca Boccassi 5ce1786227 polkit: check if user authenticated as admin
The new polkit will return a new detail regarding a successful
authentication: the actual result type, which we can use to
see whether the user authenticated as admin. This can be used
to grant additional privileges.
2026-06-25 10:39:11 +01:00
Adam Williamson d66c58f1d6 kbd-model-map: add Arabic mapping
kbd has a switched 'ara' console layout, but we don't have a
corresponding line in kbd-model-map. When converting 'us,ara' to a
legacy layout we wind up with us-acentos, which is definitely
wrong. This will fix it.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
2026-06-06 13:44:07 +01:00
Daan De Meyer 74d392ed1b tree-wide: standardize header names across src/fundamental, src/basic and src/shared
Drop the -fundamental suffix from src/fundamental/ headers in favor of names
that match their src/basic/ or src/shared/ counterparts (e.g.
macro-fundamental.h -> macro.h, assert-fundamental.h -> assert-util.h,
cleanup-fundamental.h -> cleanup-util.h). Rename src/basic/{btrfs,label}.{c,h}
to use the -util suffix to match the existing shared/btrfs-util and
shared/label-util siblings. Rename src/shared/mkdir-label.{c,h} to mkdir.{c,h}
and src/shared/tmpfile-util-label.{c,h} to tmpfile-util.{c,h} to match the
corresponding src/basic names.

This saves us from having to come up with separate names for files that do
the same thing across tiers, and it makes it easier to move stuff between
src/fundamental, src/basic and src/shared: consumers just #include "foo.h"
and pick up whichever tier their -I path resolves to first, so call sites
don't need to be updated when an API moves between layers.

Where a higher-tier wrapper exists (e.g. src/basic/macro.h wrapping
src/fundamental/macro.h), the wrapper uses an explicit "../fundamental/foo.h"
or "../basic/foo.h" relative include for the lower-tier header. We can't use
GCC's #include_next directive for this — when the wrapper is reachable both
via same-dir-as-source lookup and via -I (e.g. -Isrc/shared) for the
directory it lives in, #include_next advances by exactly one slot in libcpp's
internal directory chain and lands on the same physical directory it was
already in, never reaching the lower-tier sibling (see make_cpp_dir() in
gcc/libcpp/files.cc:1986).

To make sure the right headers are always picked up, the include directories
are reordered so that e.g. src/shared always takes priority over src/basic and
similar for the other directories.

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 10:33:03 +09:00
Daan De Meyer d158595dc7 tree-wide: move static dl handles into their dlopen_*() functions
Each dlopen_*() wrapper kept its dl handle as a file-scope
'static void *xxx_dl = NULL;' even though only the wrapper itself
ever referenced it. Move each one inside the corresponding function
so its scope matches its actual use, leaving the rest of each
translation unit free of the unused file-scope name.

In pcre2-util.c the assert(pcre2_dl) in pattern_matches_and_log()
becomes assert(sym_pcre2_match), which carries the same invariant
(pattern_compile_and_log() ran dlopen_pcre2()).
2026-05-19 19:22:06 +00:00
Daan De Meyer a14adac423 meson: drop libdl, threads, and librt dependencies
Our baseline glibc is 2.34, which merged libdl, libpthread (the
dependency('threads') target), and librt into libc. Empty .so/.a stubs
remain for backward compatibility with old binaries, but new builds
resolve dl_*, pthread_*, mq_*, timer_*, etc. directly from libc.
On musl the same libraries are likewise empty stubs.

Drop the libdl, threads, and librt entries from every meson.build, and
remove the now-stale 'Libs.private: -lrt -pthread' from libudev.pc.in
since both flags resolve to empty link-time stubs on glibc 2.34+ and
musl.

Verified with readelf -d that libsystemd.so, libudev.so, and systemd no
longer carry DT_NEEDED entries for libdl/libpthread/librt.
2026-05-18 21:17:38 +00:00
Zbigniew Jędrzejewski-Szmek 39a3647539 tree-wide: get rid of old dispatch_verb
Also rename dispatch_verb_with_args to dispatch_verb.
2026-05-16 18:37:10 +02:00
Zbigniew Jędrzejewski-Szmek cab5c5ef81 shared/verbs: add VERB_DEFAULT_NOARG 2026-05-16 15:54:18 +02:00
Zbigniew Jędrzejewski-Szmek b333fcf9da localectl: convert to the new option and verb parsers
The verb synopses are long, so they got broken up:
===============================================================================
> localectl [OPTIONS…] COMMAND …

Query or change system locale and keyboard settings.

Commands:
  [status]                      Show current locale settings
  set-locale LOCALE...          Set system locale
  list-locales                  Show known locales
  set-keymap MAP [MAP]          Set console and X11 keyboard mappings
  list-keymaps                  Show known virtual console keyboard mappings
  set-x11-keymap LAYOUT [MODEL  Set X11 and console keyboard mappings
    [VARIANT [OPTIONS]]]
  list-x11-keymap-models        Show known X11 keyboard mapping models
  list-x11-keymap-layouts       Show known X11 keyboard mapping layouts
  list-x11-keymap-variants      Show known X11 keyboard mapping variants
    [LAYOUT]
  list-x11-keymap-options       Show known X11 keyboard mapping options

Options:
  -h --help                     Show this help
     --version                  Show package version
  -l --full                     Do not ellipsize output
     --no-pager                 Do not start a pager
     --no-ask-password          Do not prompt for password
  -H --host=[USER@]HOST         Operate on remote host
  -M --machine=CONTAINER        Operate on local container
     --no-convert               Don't convert keyboard mappings

See the localectl(1) man page for details.
===============================================================================

But I think this is OK. Everything is readable. On a more normal terminal,
everything fits nicely.

Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-14 14:15:52 +02:00
Daan De Meyer 7b9d76cba7 boot,vconsole: Propagate UEFI HII keyboard layout to the OS
UEFI firmware can report the currently-active keyboard layout via
EFI_HII_DATABASE_PROTOCOL.GetKeyboardLayout(). The layout descriptor
includes an RFC 4646 / BCP 47 language tag (e.g. "en-US"). Query this
from sd-boot/sd-stub and write it to a new LoaderKeyboardLayout EFI
variable, advertised through a new EFI_LOADER_FEATURE_KEYBOARD_LAYOUT
feature bit.

On the OS side, systemd-vconsole-setup reads the variable as a
lowest-priority fallback for the console keymap. To map the BCP 47
tag to a vconsole keymap we extend /usr/share/systemd/kbd-model-map
with an optional sixth column listing the comma-separated BCP 47 tags
each row covers; a new find_vconsole_keymap_for_bcp47() helper walks
the file, preferring an exact tag match and otherwise falling back to
the row whose tag matches the input's primary subtag. Credentials,
/etc/vconsole.conf, and vconsole.keymap= on the kernel command line
continue to take precedence.

bootctl status surfaces the new variable, printing the language tag
or "n/a (not reported by firmware)" when sd-boot advertises the
feature but the firmware HII database didn't expose a layout (common
on QEMU without a USB keyboard, since EDK2's PS/2 driver does not
register an HII keyboard layout).
2026-05-11 21:10:11 +02:00
Diego Viola 5d17215c7e treewide: fix typos in the entire codebase
Signed-off-by: Diego Viola <diego.viola@gmail.com>
2026-05-05 17:22:26 +02:00
Daan De Meyer d49f3f287a dlopen: take log_level argument and log in fallback stubs
Every dlopen_xxx() helper now takes an int log_level argument. It is
passed through to dlopen_many_sym_or_warn() (which in turn propagates it
to dlopen_verbose() for the library-not-installed case), and is used by
the fallback stub when support for the library is not compiled in to
emit a "<lib> support is not compiled in." message at the caller's level.
Callers pass LOG_DEBUG when gracefully degrading, or a higher level when
the failure should surface, and no longer need to log redundantly at the
call site.

As part of this, dlopen_bpf_full() (which already took a log_level) is
merged into dlopen_bpf() rather than keeping both.

The static inline fallbacks used to live in the headers, which required
pulling log.h in from every header that declared a dlopen_xxx(). Move
them into the .c files instead: the declaration is always outside the
#if HAVE_XXX block, the impl sits outside the outer #if HAVE_XXX wrap
with its own internal #if HAVE_XXX/#else/#endif, and apparmor-util.c,
idn-util.c, libmount-util.c and pam-util.c are now always compiled so
they can host their stubs.
2026-04-22 17:41:42 +02:00
Kajus Naujokaitis 72e894c590 localed-util: respect env var when writing vconsole.conf 2026-04-22 15:24:33 +02:00
Zbigniew Jędrzejewski-Szmek 1008583c91 tree-wide: print error if table_print() fails
We generally want to print an error message if table_print()
fails. Add a helper function for this and use it consistently.
This does one of the three things depending on the call site:
- a no-change reformatting of the code
- change from a custom message to the generic one
- addition of the error message where previously none was printed

In the third case, the actual use impact is very small, since the
table formatting is very unlikely to fail. But if it did, we would
often return an error without any message whatsoever, which we
never want to do.
2026-04-03 13:05:03 +02:00
Zbigniew Jędrzejewski-Szmek 0ce5a8fb4e tree-wide: drop flush&check step after table printing
Almost all callers of table_print() specify stdout or NULL (equivalent
to stdout) as the output stream. Simplify things by not requiring the
the stream to be specified.

In almost all cases, the printing of the table is surrounded by normal
printfs() that don't do explicit flushing and for which we don't check
the output stream status. Let's simplify most callers and skip this
step. The reason is not so much to avoid the extra step itself, but
instead to avoid the _handling_ of the potential failure. We generally
only want to print an error message for ENOMEM and other "internal"
errors, so strictly speaking we should filter out the errors from the
stream. By skipping the flush&check step we implicitly do this.
2026-04-03 13:04:40 +02:00
Zbigniew Jędrzejewski-Szmek 26230ed5c1 Rename verb functions for consistency and add per-verb constant parameter (#41003)
We often have a pattern where the same verb function is used for
multiple actions. This leads to an antipattern where we figure out what
action needs to be taken from argv[0] multiple times: often once in
arse_argv() to figure out what options are allowed, then once again
implicitly in dispatch_verb(), and then again in the action verb itself.
Let's allow passing a parameter into the verb to simplify this.
2026-03-18 16:46:13 +01:00
Zbigniew Jędrzejewski-Szmek 31ddd87da0 tree-wide: extend verbs functions with extra per-verb data parameter
We often have a pattern where the same verb function is used for
multiple actions. This leads to an antipattern where we figure out what
action needs to be taken from argv[0] multiple times: often once in
parse_argv() to figure out what options are allowed, then once again
implicitly in dispatch_verb(), and then again in the action verb itself.
Let's allow passing a parameter into the verb to simplify this.

This matches a pattern we have in conf-parser.h, where we have both
void *userdata (more global) and void *data (per-config item). Here,
I opted for uintptr_t userdata. It seems that most of the time we'll
want to just pass an enum value. This works OK with no casts. I also
tried a void* and union. In both cases, much more boilerplate is needed:
either a cast or a macro to help avoid compiler warnings. uintptr_t
seems generic enough to cover foreseeable usecases with no fuss.

This is a noop refactoring. See next commit for an example.
2026-03-18 10:28:47 +00:00
Zbigniew Jędrzejewski-Szmek 65c10b815b localectl: call all verb functions verb_* 2026-03-18 10:28:47 +00:00
Christian Brauner 8b12350b75 dlfcn-util: migrate to public SD_ELF_NOTE_DLOPEN() API
Switch all internal callers from the private ELF_NOTE_DLOPEN() macro to
the new public SD_ELF_NOTE_DLOPEN() API from sd-dlopen.h, and remove
the now-redundant macro definitions from dlfcn-util.h.

Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-03-18 10:28:11 +00:00
Yu Watanabe 30b9fa495c clang-tidy: Enable more warnings (#39910) 2026-01-03 06:00:30 +09:00
Daan De Meyer 52ecf376fa tree-wide: Migrate to pidref_safe_fork()
Let's migrate all remaining callers of safe_fork()
to pidref_safe_fork() and get rid of safe_fork().
2026-01-02 20:08:41 +01:00
Daan De Meyer a7e07aeaac locale: Gate conditional includes behind ifdef
Let's make sure clang-tidy doesn't complain on
distributions without locale-gen.
2026-01-02 09:39:32 +01:00
Yu Watanabe 93378148d4 tree-wide: normalize comment style 2025-12-15 08:50:13 +09:00
Zbigniew Jędrzejewski-Szmek 5220bb8c3f meson: automatically add 'extract' to 'sources'
In all cases, everything that we list in 'extract', we also list in
'sources'. We can simplify things by automatically appending the first
list to the second.

In the listings, move 'extract' key right below 'sources', since now
they are both "sources", just with slightly different meanings.
2025-11-20 10:03:48 +09:00
Yu Watanabe 5e385fe16e locale: use include directory for libxkbcommon
To support the case the headers are installed at an unusual place.
2025-10-25 13:06:02 +09:00
Yu Watanabe 53dceb8a6d xkbcommon-util: drop 'sym_' prefix from cleanup functions 2025-10-25 11:25:41 +09:00
Daan De Meyer f102bc3e5f tree-wide: Introduce sd-forward.h and shared-forward.h headers
Let's not leak details from src/shared and src/libsystemd into
src/basic, even though you can't actually do anything useful with
just forward declarations from src/shared.

The sd-forward.h header is put in src/libsystemd/sd-common as we
don't have a directory for shared internal headers for libsystemd
yet.

Let's also rename forward.h to basic-forward.h to keep things
self-explanatory.
2025-10-16 17:00:29 +02:00
Lennart Poettering b7f6bdbbd3 service-util: add generic parser for runtime scope 2025-09-25 22:43:59 +02:00
ners 7b7f0983e0 localectl: use XKB path specified from environment variable 2025-09-19 15:37:52 +09:00
Yu Watanabe 0464222aed locale: escape invalid keymap on logging
The keymap string may come from dbus method and may contain invalid
characters.
2025-07-27 00:58:02 +01:00
Yu Watanabe 5c34d85c74 tree-wide: normalize usage of %m 2025-07-22 03:05:54 +09:00
Valentin David 0dc39dffbd Use paths specified from environment variables for /etc configuration files
Some configuration files that need updates are directly under in /etc. To
update them atomically, we need write access to /etc. For Ubuntu Core this is
an issue as /etc is not writable. Only a selection of subdirectories can be
writable. The general solution is symlinks or bind mounts to writable places.
But for atomic writes in /etc, that does not work. So Ubuntu has had a patch
for that that did not age well.

Instead we would like to introduce some environment variables for alternate
paths.

 * SYSTEMD_ETC_HOSTNAME: /etc/hostname
 * SYSTEMD_ETC_MACHINE_INFO: /etc/machine-info
 * SYSTEMD_ETC_LOCALTIME: /etc/localtime
 * SYSTEMD_ETC_LOCALE_CONF: /etc/locale.conf
 * SYSTEMD_ETC_VCONSOLE_CONF: /etc/vconsole.conf
 * SYSTEMD_ETC_ADJTIME: /etc/adjtime

While it is for now expected that there is a symlink from the standard, we
still try to read them from that alternate path. This is important for
`/etc/localtime`, which is a symlink, so we cannot have an indirect symlink or
bind mount for it.

Since machine-id is typically written only once and not updated. This commit
does not cover it. An initrd can properly create it and bind mount it.
2025-06-23 15:32:11 +02:00
Lennart Poettering 3e5320e27d env-file: port write_env_file() to label_ops_pre()
Let's make more use of label_ops_pre()/label_ops_post(), and replace
write_env_file_label() by a flag to write_env_file().

This simplifies and normalizes the code.

This also makes one relevant change: it sets the new
WRITE_ENV_FILE_LABEL flag in firstboot.c when we write locale.conf,
where we previously did not (but should have). This should address one
detail of #37857.
2025-06-18 10:21:26 +02:00
Mike Yuan a59cc3860b tree-wide: check --machine= specification
Addresses https://github.com/systemd/systemd/pull/37741#discussion_r2128482378
2025-06-17 02:10:37 +02:00
Daan De Meyer 1e35e81b2c tree-wide: Clean up includes
Preparation for cleaning up includes in src/shared.
2025-05-22 21:10:15 +02:00
Daan De Meyer 86b9a3e31d tree-wide: Clean up includes
This removes more unused includes from the components already cleaned
up in #37467 and #37457.

Split out of #37344.
2025-05-21 10:49:42 +02:00
Daan De Meyer a583b34416 meson: Extract more objects instead of compiling multiple times
Also, let's deflatten the lists of sources in preparation for the
next commit at the same time.

In systemctl, we split out systemctl-main.c to make sure the definition
of main() is in a separate object which allows us to extract the systemctl.c
object and link it in the fuzzer target without getting a multiple definition
error when linking.
2025-05-20 10:29:58 +02:00
Daan De Meyer a7dad604d7 locale: Clean up includes
Split out of #37344.
2025-05-15 00:01:59 +02:00
Daan De Meyer 6350d2dbd9 meson: Extract objects instead of creating intermediate static libraries
Currently, when we want to add unit tests for code that is compiled into
an executable, we either compile the code at least twice (once for the
executable, and once for each test that uses it) or we create a static
library which is then used by both the executable and all the tests.

Both of these options are not ideal, compiling source files more than
once slows down the build for no reason and creating the intermediate
static libraries takes a lot of boilerplate.

Instead, let's use the extract_objects() method that meson exposes on
build targets. This allows us to extract the objects corresponding to
specific source files and use them in other executables. Because we
define all executables upfront into a dictionary, we integrate this into
the dictionary approach by adding two new fields:

- 'extract' takes a list of files for which objects should be extracted.
  The extracted objects are stored in a dict keyed by the executable name
  from which they were extracted.
- 'objects' takes the name of an executable from which the extracted
  objects should be added to the current executable.

One side effect of this approach is that we can't build test executables
anymore without building the main executable, so we stop building test
executables unless we're also building the main executable. This allows
us to switch to using subdir_done() in all of these subdirectories to skip
parsing them if the corresponding component is disabled.

These changes get me down from 2439 => 2403 ninja targets on a full rebuild
from scratch.
2025-05-12 13:35:50 +02:00
Daan De Meyer decad4826d static-destruct: Reduce transitive includes 2025-05-07 22:04:46 +09:00
Daan De Meyer 6553db6063 strv: Reduce transitive includes 2025-05-07 22:04:46 +09:00
Daan De Meyer fda652117e fs-util: Reduce transitive includes 2025-05-07 22:04:46 +09:00
Daan De Meyer e4a08721c3 string-util: Remove utf8.h and alloc-util.h includes 2025-05-06 13:27:54 +02:00
Daan De Meyer 76d62b63ef main-func: Reduce transitive includes
Let's move some logic from _DEFINE_MAIN_FUNCTION() and other places
in main-func.h into functions that we implement in main-func.c to
allow moving some included headers from the header to the .c file.
2025-05-06 10:07:27 +02:00
Daan De Meyer 792a8bfb8a daemon-util: Rename starting/stopping message constants
Currently, NOTIFY_READY from daemon-util.h conflicts with NOTIFY_READY
from NotifyState from service.h so let's rename the constants to avoid
the conflict.
2025-05-01 14:02:17 +02:00
Daan De Meyer 1cf40697e3 tree-wide: Sort includes
This was done by running a locally built clang-format with
https://github.com/llvm/llvm-project/pull/137617 and
https://github.com/llvm/llvm-project/pull/137840 applied on all .c
and .h files.
2025-04-30 09:30:51 +02:00
Daan De Meyer 93a1f7921a basic: Stop including log.h in macro.h
Now that the necessary functions from log.h have been moved to macro.h,
we can stop including log.h in macro.h. This requires modifying source
files all over the tree to include log.h instead.
2025-04-18 14:19:15 +02:00