diff options
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/cgroup-util.c | 1 | ||||
-rw-r--r-- | src/shared/mkdir.c | 99 | ||||
-rw-r--r-- | src/shared/mkdir.h | 28 | ||||
-rw-r--r-- | src/shared/socket-util.c | 1 | ||||
-rw-r--r-- | src/shared/util.c | 68 | ||||
-rw-r--r-- | src/shared/util.h | 3 |
6 files changed, 129 insertions, 71 deletions
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 904d300952..5647624e8d 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -34,6 +34,7 @@ #include "set.h" #include "macro.h" #include "util.h" +#include "mkdir.h" int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) { char *fs; diff --git a/src/shared/mkdir.c b/src/shared/mkdir.c new file mode 100644 index 0000000000..e668cc2558 --- /dev/null +++ b/src/shared/mkdir.c @@ -0,0 +1,99 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <assert.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> + +#include "mkdir.h" +#include "label.h" +#include "util.h" +#include "log.h" + +int safe_mkdir(const char *path, mode_t mode, uid_t uid, gid_t gid) { + struct stat st; + + if (label_mkdir(path, mode) >= 0) + if (chmod_and_chown(path, mode, uid, gid) < 0) + return -errno; + + if (lstat(path, &st) < 0) + return -errno; + + if ((st.st_mode & 0777) != mode || + st.st_uid != uid || + st.st_gid != gid || + !S_ISDIR(st.st_mode)) { + errno = EEXIST; + return -errno; + } + + return 0; +} + +int mkdir_parents(const char *path, mode_t mode) { + const char *p, *e; + + assert(path); + + /* Creates every parent directory in the path except the last + * component. */ + + p = path + strspn(path, "/"); + for (;;) { + int r; + char *t; + + e = p + strcspn(p, "/"); + p = e + strspn(e, "/"); + + /* Is this the last component? If so, then we're + * done */ + if (*p == 0) + return 0; + + if (!(t = strndup(path, e - path))) + return -ENOMEM; + + r = label_mkdir(t, mode); + free(t); + + if (r < 0 && errno != EEXIST) + return -errno; + } +} + +int mkdir_p(const char *path, mode_t mode) { + int r; + + /* Like mkdir -p */ + + if ((r = mkdir_parents(path, mode)) < 0) + return r; + + if (label_mkdir(path, mode) < 0 && errno != EEXIST) + return -errno; + + return 0; +} diff --git a/src/shared/mkdir.h b/src/shared/mkdir.h new file mode 100644 index 0000000000..c006e7ccdb --- /dev/null +++ b/src/shared/mkdir.h @@ -0,0 +1,28 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foomkdirhfoo +#define foomkdirhfoo + +/*** + 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 General Public License as published by + the Free Software Foundation; either version 2 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 + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +int safe_mkdir(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); +#endif diff --git a/src/shared/socket-util.c b/src/shared/socket-util.c index acc4d33372..554f8ac965 100644 --- a/src/shared/socket-util.c +++ b/src/shared/socket-util.c @@ -34,6 +34,7 @@ #include "macro.h" #include "util.h" +#include "mkdir.h" #include "socket-util.h" #include "missing.h" #include "label.h" diff --git a/src/shared/util.c b/src/shared/util.c index 563853fad6..fef58d5f30 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -1591,74 +1591,6 @@ char *file_in_same_dir(const char *path, const char *filename) { return r; } -int safe_mkdir(const char *path, mode_t mode, uid_t uid, gid_t gid) { - struct stat st; - - if (label_mkdir(path, mode) >= 0) - if (chmod_and_chown(path, mode, uid, gid) < 0) - return -errno; - - if (lstat(path, &st) < 0) - return -errno; - - if ((st.st_mode & 0777) != mode || - st.st_uid != uid || - st.st_gid != gid || - !S_ISDIR(st.st_mode)) { - errno = EEXIST; - return -errno; - } - - return 0; -} - - -int mkdir_parents(const char *path, mode_t mode) { - const char *p, *e; - - assert(path); - - /* Creates every parent directory in the path except the last - * component. */ - - p = path + strspn(path, "/"); - for (;;) { - int r; - char *t; - - e = p + strcspn(p, "/"); - p = e + strspn(e, "/"); - - /* Is this the last component? If so, then we're - * done */ - if (*p == 0) - return 0; - - if (!(t = strndup(path, e - path))) - return -ENOMEM; - - r = label_mkdir(t, mode); - free(t); - - if (r < 0 && errno != EEXIST) - return -errno; - } -} - -int mkdir_p(const char *path, mode_t mode) { - int r; - - /* Like mkdir -p */ - - if ((r = mkdir_parents(path, mode)) < 0) - return r; - - if (label_mkdir(path, mode) < 0 && errno != EEXIST) - return -errno; - - return 0; -} - int rmdir_parents(const char *path, const char *stop) { size_t l; int r = 0; diff --git a/src/shared/util.h b/src/shared/util.h index e96d56dd2a..a45f54d661 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -242,9 +242,6 @@ char *delete_chars(char *s, const char *bad); char *truncate_nl(char *s); char *file_in_same_dir(const char *path, const char *filename); -int safe_mkdir(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); int parent_of_path(const char *path, char **parent); |