path-util.c revision 112cfb181453e38d3ef4a74fba23abbb53392002
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/***
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering This file is part of systemd.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Copyright 2010-2012 Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering systemd is free software; you can redistribute it and/or modify it
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering under the terms of the GNU Lesser General Public License as published by
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering (at your option) any later version.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering systemd is distributed in the hope that it will be useful, but
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Lesser General Public License for more details.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering You should have received a copy of the GNU Lesser General Public License
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering***/
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
4871690d9e32608bbd9b18505b5326c2079c9690Allin Cottrell#include <assert.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <string.h>
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include <unistd.h>
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include <errno.h>
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include <stdlib.h>
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include <signal.h>
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include <stdio.h>
13790add4bf648fed816361794d8277a75253410Lennart Poettering#include <fcntl.h>
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include <dirent.h>
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include <sys/statvfs.h>
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering
a09561746f15b84da9471b5c4be74e53d19e4f3fLennart Poettering#include "macro.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "util.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "log.h"
13790add4bf648fed816361794d8277a75253410Lennart Poettering#include "strv.h"
afc5dbf37fd2399d37976388d9dd9ab470ecf446Lennart Poettering#include "path-util.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "missing.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekbool path_is_absolute(const char *p) {
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering return p[0] == '/';
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poetteringbool is_path(const char *p) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return !!strchr(p, '/');
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering}
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering
15a5e95075a7f6007dd97b2a165c8ed16fe683dfLennart Poetteringint path_get_parent(const char *path, char **_r) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering const char *e, *a = NULL, *b = NULL, *p;
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering char *r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering bool slash = false;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(path);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(_r);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!*path)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -EINVAL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering for (e = path; *e; e++) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!slash && *e == '/') {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering a = b;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering b = e;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering slash = true;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering } else if (slash && *e != '/')
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering slash = false;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (*(e-1) == '/')
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering p = a;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering else
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek p = b;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!p)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -EINVAL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (p == path)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = strdup("/");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering else
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = strndup(path, p-path);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (!r)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return -ENOMEM;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering *_r = r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering}
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringchar **path_split_and_make_absolute(const char *p) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering char **l;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(p);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering l = strv_split(p, ":");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!l)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!path_strv_make_absolute_cwd(l)) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering strv_free(l);
13790add4bf648fed816361794d8277a75253410Lennart Poettering return NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return l;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering}
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringchar *path_make_absolute(const char *p, const char *prefix) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(p);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Makes every item in the list an absolute path by prepending
13790add4bf648fed816361794d8277a75253410Lennart Poettering * the prefix, if specified and necessary */
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (path_is_absolute(p) || !prefix)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return strdup(p);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek return strjoin(prefix, "/", p, NULL);
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringchar *path_make_absolute_cwd(const char *p) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_free_ char *cwd = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(p);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Similar to path_make_absolute(), but prefixes with the
13790add4bf648fed816361794d8277a75253410Lennart Poettering * current working directory. */
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (path_is_absolute(p))
13790add4bf648fed816361794d8277a75253410Lennart Poettering return strdup(p);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering cwd = get_current_dir_name();
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (!cwd)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return path_make_absolute(p, cwd);
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringchar **path_strv_make_absolute_cwd(char **l) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering char **s;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Goes through every item in the string list and makes it
13790add4bf648fed816361794d8277a75253410Lennart Poettering * absolute. This works in place and won't rollback any
13790add4bf648fed816361794d8277a75253410Lennart Poettering * changes on failure. */
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering STRV_FOREACH(s, l) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering char *t;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering t = path_make_absolute_cwd(*s);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!t)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering free(*s);
13790add4bf648fed816361794d8277a75253410Lennart Poettering *s = t;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return l;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringchar **path_strv_canonicalize_absolute(char **l, const char *prefix) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering char **s;
13790add4bf648fed816361794d8277a75253410Lennart Poettering unsigned k = 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering bool enomem = false;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (strv_isempty(l))
13790add4bf648fed816361794d8277a75253410Lennart Poettering return l;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Goes through every item in the string list and canonicalize
13790add4bf648fed816361794d8277a75253410Lennart Poettering * the path. This works in place and won't rollback any
13790add4bf648fed816361794d8277a75253410Lennart Poettering * changes on failure. */
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering STRV_FOREACH(s, l) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering char *t, *u;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!path_is_absolute(*s))
13790add4bf648fed816361794d8277a75253410Lennart Poettering continue;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (prefix) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering t = strappend(prefix, *s);
13790add4bf648fed816361794d8277a75253410Lennart Poettering free(*s);
13790add4bf648fed816361794d8277a75253410Lennart Poettering *s = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!t) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering enomem = true;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering continue;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering } else {
13790add4bf648fed816361794d8277a75253410Lennart Poettering t = *s;
13790add4bf648fed816361794d8277a75253410Lennart Poettering *s = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering errno = 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering u = canonicalize_file_name(t);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!u) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (errno == ENOENT)
13790add4bf648fed816361794d8277a75253410Lennart Poettering u = t;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering else {
13790add4bf648fed816361794d8277a75253410Lennart Poettering free(t);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (errno == ENOMEM || errno == 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering enomem = true;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering continue;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering } else
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering free(t);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering l[k++] = u;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering l[k] = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (enomem)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return NULL;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return l;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering}
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringchar **path_strv_canonicalize_absolute_uniq(char **l, const char *prefix) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (strv_isempty(l))
13790add4bf648fed816361794d8277a75253410Lennart Poettering return l;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering if (!path_strv_canonicalize_absolute(l, prefix))
13790add4bf648fed816361794d8277a75253410Lennart Poettering return NULL;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering return strv_uniq(l);
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering}
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poetteringchar *path_kill_slashes(char *path) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering char *f, *t;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering bool slash = false;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Removes redundant inner and trailing slashes. Modifies the
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * passed string in-place.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering *
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * ///foo///bar/ becomes /foo/bar
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek */
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek for (f = path, t = path; *f; f++) {
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek if (*f == '/') {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering slash = true;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering continue;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (slash) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering slash = false;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering *(t++) = '/';
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering *(t++) = *f;
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* Special rule, if we are talking of the root directory, a
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering trailing slash is good */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (t == path && slash)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering *(t++) = '/';
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering *t = 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return path;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensenchar* path_startswith(const char *path, const char *prefix) {
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen assert(path);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(prefix);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek if ((path[0] == '/') != (prefix[0] == '/'))
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek return NULL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek for (;;) {
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek size_t a, b;
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek path += strspn(path, "/");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering prefix += strspn(prefix, "/");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (*prefix == 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return (char*) path;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (*path == 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return NULL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering a = strcspn(path, "/");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering b = strcspn(prefix, "/");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek if (a != b)
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek return NULL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (memcmp(path, prefix, a) != 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return NULL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering path += a;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering prefix += b;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringbool path_equal(const char *a, const char *b) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(a);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(b);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if ((a[0] == '/') != (b[0] == '/'))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return false;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering for (;;) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering size_t j, k;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering a += strspn(a, "/");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering b += strspn(b, "/");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (*a == 0 && *b == 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return true;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (*a == 0 || *b == 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return false;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering j = strcspn(a, "/");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering k = strcspn(b, "/");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (j != k)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return false;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (memcmp(a, b, j) != 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return false;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering a += j;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering b += k;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
41891700e02daf0cab9e86908c76ac6f411bbd57Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringint path_is_mount_point(const char *t, bool allow_symlink) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering char *parent;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering struct file_handle *h;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int mount_id, mount_id_parent;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering struct stat a, b;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* We are not actually interested in the file handles, but
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * name_to_handle_at() also passes us the mount ID, hence use
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * it but throw the handle away */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (path_equal(t, "/"))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 1;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering h = alloca(MAX_HANDLE_SZ);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering h->handle_bytes = MAX_HANDLE_SZ;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = name_to_handle_at(AT_FDCWD, t, h, &mount_id, allow_symlink ? AT_SYMLINK_FOLLOW : 0);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (errno == ENOSYS || errno == ENOTSUP)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* This kernel or file system does not support
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * name_to_handle_at(), hence fallback to the
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * traditional stat() logic */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering goto fallback;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (errno == ENOENT)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -errno;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = path_get_parent(t, &parent);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering h->handle_bytes = MAX_HANDLE_SZ;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = name_to_handle_at(AT_FDCWD, parent, h, &mount_id_parent, 0);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering free(parent);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* The parent can't do name_to_handle_at() but the
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * directory we are interested in can? If so, it must
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * be a mount point */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (errno == ENOTSUP)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 1;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -errno;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return mount_id != mount_id_parent;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringfallback:
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (allow_symlink)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = stat(t, &a);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering else
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = lstat(t, &a);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (errno == ENOENT)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -errno;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = path_get_parent(t, &parent);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = lstat(parent, &b);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering free(parent);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -errno;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return a.st_dev != b.st_dev;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringint path_is_read_only_fs(const char *path) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering struct statvfs st;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(path);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (statvfs(path, &st) < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -errno;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return !!(st.f_flag & ST_RDONLY);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringint path_is_os_tree(const char *path) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering char *p;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* We use /etc/os-release as flag file if something is an OS */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering p = strappenda(path, "/etc/os-release");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = access(p, F_OK);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return r < 0 ? 0 : 1;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringint find_binary(const char *name, char **filename) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(name);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(filename);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (strchr(name, '/')) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering char *p;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (path_is_absolute(name))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering p = strdup(name);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering else
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering p = path_make_absolute_cwd(name);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (!p)
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return -ENOMEM;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering *filename = p;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering } else {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering const char *path;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering char *state, *w;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering size_t l;
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering /**
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering * Plain getenv, not secure_getenv, because we want
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * to actually allow the user to pick the binary.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering path = getenv("PATH");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!path)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering path = DEFAULT_PATH;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt FOREACH_WORD_SEPARATOR(w, l, path, ":", state) {
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering char *p;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (asprintf(&p, "%.*s/%s", (int) l, w, name) < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -ENOMEM;
7b77ed8cf36e8eca6017791626044b61ae2d68e7Lennart Poettering
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering if (access(p, X_OK) < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering free(p);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering continue;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering path_kill_slashes(p);
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering *filename = p;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return -ENOENT;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringbool paths_check_timestamp(const char* const* paths, usec_t *timestamp, bool update) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering bool changed = false;
13790add4bf648fed816361794d8277a75253410Lennart Poettering const char* const* i;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(timestamp);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (paths == NULL)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return false;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering STRV_FOREACH(i, paths) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering struct stat stats;
13790add4bf648fed816361794d8277a75253410Lennart Poettering usec_t u;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (stat(*i, &stats) < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering continue;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering u = timespec_load(&stats.st_mtim);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* first check */
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek if (*timestamp >= u)
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek continue;
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_debug("timestamp of '%s' changed", *i);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* update timestamp */
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (update) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering *timestamp = u;
13790add4bf648fed816361794d8277a75253410Lennart Poettering changed = true;
13790add4bf648fed816361794d8277a75253410Lennart Poettering } else
13790add4bf648fed816361794d8277a75253410Lennart Poettering return true;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return changed;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering