path-util.c revision 112cfb181453e38d3ef4a74fba23abbb53392002
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering This file is part of systemd.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Copyright 2010-2012 Lennart 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 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 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/>.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekbool path_is_absolute(const char *p) {
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering return p[0] == '/';
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poetteringbool is_path(const char *p) {
15a5e95075a7f6007dd97b2a165c8ed16fe683dfLennart Poetteringint path_get_parent(const char *path, char **_r) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering for (e = path; *e; e++) {
13790add4bf648fed816361794d8277a75253410Lennart Poetteringchar **path_split_and_make_absolute(const char *p) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringchar *path_make_absolute(const char *p, const char *prefix) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Makes every item in the list an absolute path by prepending
13790add4bf648fed816361794d8277a75253410Lennart Poettering * the prefix, if specified and necessary */
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek return strjoin(prefix, "/", p, NULL);
13790add4bf648fed816361794d8277a75253410Lennart Poetteringchar *path_make_absolute_cwd(const char *p) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Similar to path_make_absolute(), but prefixes with the
13790add4bf648fed816361794d8277a75253410Lennart Poettering * current working directory. */
13790add4bf648fed816361794d8277a75253410Lennart Poetteringchar **path_strv_make_absolute_cwd(char **l) {
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 Poetteringchar **path_strv_canonicalize_absolute(char **l, const char *prefix) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering unsigned k = 0;
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. */
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringchar **path_strv_canonicalize_absolute_uniq(char **l, const char *prefix) {
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering if (!path_strv_canonicalize_absolute(l, prefix))
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Removes redundant inner and trailing slashes. Modifies the
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * passed string in-place.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * ///foo///bar/ becomes /foo/bar
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek for (f = path, t = path; *f; f++) {
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek if (*f == '/') {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* Special rule, if we are talking of the root directory, a
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering trailing slash is good */
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensenchar* path_startswith(const char *path, const char *prefix) {
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek if ((path[0] == '/') != (prefix[0] == '/'))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return (char*) path;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringbool path_equal(const char *a, const char *b) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (*a == 0 && *b == 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (*a == 0 || *b == 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (memcmp(a, b, j) != 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringint path_is_mount_point(const char *t, bool allow_symlink) {
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 r = name_to_handle_at(AT_FDCWD, t, h, &mount_id, allow_symlink ? AT_SYMLINK_FOLLOW : 0);
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 r = name_to_handle_at(AT_FDCWD, parent, h, &mount_id_parent, 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 Poetteringint path_is_read_only_fs(const char *path) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering /* We use /etc/os-release as flag file if something is an OS */
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return r < 0 ? 0 : 1;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringint find_binary(const char *name, char **filename) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering * Plain getenv, not secure_getenv, because we want
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering * to actually allow the user to pick the binary.
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt FOREACH_WORD_SEPARATOR(w, l, path, ":", state) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (asprintf(&p, "%.*s/%s", (int) l, w, name) < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poetteringbool paths_check_timestamp(const char* const* paths, usec_t *timestamp, bool update) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering const char* const* i;
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* first check */
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_debug("timestamp of '%s' changed", *i);
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* update timestamp */