]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/mkdir.c
hashmap, set: remove unused functions
[thirdparty/systemd.git] / src / shared / mkdir.c
CommitLineData
49e942b2
KS
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
49e942b2
KS
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
49e942b2 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
49e942b2
KS
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <assert.h>
23#include <string.h>
24#include <unistd.h>
25#include <errno.h>
26#include <stdlib.h>
27#include <stdio.h>
28
49e942b2
KS
29#include "label.h"
30#include "util.h"
4ad49000
LP
31#include "path-util.h"
32#include "mkdir.h"
49e942b2 33
39bdfa31 34int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkdir_func_t _mkdir) {
49e942b2
KS
35 struct stat st;
36
39bdfa31 37 if (_mkdir(path, mode) >= 0)
49e942b2
KS
38 if (chmod_and_chown(path, mode, uid, gid) < 0)
39 return -errno;
40
41 if (lstat(path, &st) < 0)
42 return -errno;
43
0cb9fbcd
LP
44 if ((st.st_mode & 0007) > (mode & 0007) ||
45 (st.st_mode & 0070) > (mode & 0070) ||
46 (st.st_mode & 0700) > (mode & 0700) ||
e66cf1a3
LP
47 (uid != (uid_t) -1 && st.st_uid != uid) ||
48 (gid != (gid_t) -1 && st.st_gid != gid) ||
49e942b2
KS
49 !S_ISDIR(st.st_mode)) {
50 errno = EEXIST;
51 return -errno;
52 }
53
54 return 0;
55}
56
c66e7f04 57int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid) {
69c2b6be 58 return mkdir_safe_internal(path, mode, uid, gid, mkdir);
c66e7f04
KS
59}
60
e73a03e0 61int is_dir(const char* path, bool follow) {
9e13dbae 62 struct stat st;
4ad49000 63
e73a03e0
LP
64 if (follow) {
65 if (stat(path, &st) < 0)
66 return -errno;
67 } else {
68 if (lstat(path, &st) < 0)
69 return -errno;
70 }
4ad49000
LP
71
72 return S_ISDIR(st.st_mode);
73}
74
39bdfa31 75int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir) {
49e942b2 76 const char *p, *e;
4ad49000 77 int r;
49e942b2
KS
78
79 assert(path);
80
4ad49000
LP
81 if (prefix && !path_startswith(path, prefix))
82 return -ENOTDIR;
83
9e13dbae
KS
84 /* return immediately if directory exists */
85 e = strrchr(path, '/');
86 if (!e)
87 return -EINVAL;
4ad49000
LP
88
89 if (e == path)
90 return 0;
91
9e13dbae 92 p = strndupa(path, e - path);
e73a03e0 93 r = is_dir(p, true);
4ad49000
LP
94 if (r > 0)
95 return 0;
96 if (r == 0)
97 return -ENOTDIR;
49e942b2 98
9e13dbae 99 /* create every parent directory in the path, except the last component */
49e942b2
KS
100 p = path + strspn(path, "/");
101 for (;;) {
4ad49000 102 char t[strlen(path) + 1];
49e942b2
KS
103
104 e = p + strcspn(p, "/");
105 p = e + strspn(e, "/");
106
107 /* Is this the last component? If so, then we're
108 * done */
109 if (*p == 0)
110 return 0;
111
4ad49000
LP
112 memcpy(t, path, e - path);
113 t[e-path] = 0;
49e942b2 114
4ad49000
LP
115 if (prefix && path_startswith(prefix, t))
116 continue;
49e942b2 117
39bdfa31 118 r = _mkdir(t, mode);
49e942b2
KS
119 if (r < 0 && errno != EEXIST)
120 return -errno;
121 }
122}
123
c66e7f04 124int mkdir_parents(const char *path, mode_t mode) {
39bdfa31 125 return mkdir_parents_internal(NULL, path, mode, mkdir);
5b585b53
ZJS
126}
127
39bdfa31 128int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir) {
49e942b2
KS
129 int r;
130
131 /* Like mkdir -p */
132
39bdfa31 133 r = mkdir_parents_internal(prefix, path, mode, _mkdir);
c66e7f04 134 if (r < 0)
49e942b2
KS
135 return r;
136
39bdfa31 137 r = _mkdir(path, mode);
e73a03e0 138 if (r < 0 && (errno != EEXIST || is_dir(path, true) <= 0))
49e942b2
KS
139 return -errno;
140
141 return 0;
142}
c66e7f04
KS
143
144int mkdir_p(const char *path, mode_t mode) {
39bdfa31 145 return mkdir_p_internal(NULL, path, mode, mkdir);
4ad49000
LP
146}
147
148int mkdir_p_prefix(const char *prefix, const char *path, mode_t mode) {
39bdfa31 149 return mkdir_p_internal(prefix, path, mode, mkdir);
c66e7f04 150}