summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/basic/mkdir.c2
-rw-r--r--src/basic/stat-util.c217
-rw-r--r--src/basic/stat-util.h32
-rw-r--r--src/basic/time-util.c2
-rw-r--r--src/firstboot/firstboot.c4
-rw-r--r--src/kernel-install/kernel-install.c2
6 files changed, 129 insertions, 130 deletions
diff --git a/src/basic/mkdir.c b/src/basic/mkdir.c
index 5dd56c89a4..7c1ad7dd64 100644
--- a/src/basic/mkdir.c
+++ b/src/basic/mkdir.c
@@ -112,7 +112,7 @@ int mkdirat_parents_internal(int dir_fd, const char *path, mode_t mode, uid_t ui
/* drop the last component */
path = strndupa_safe(path, e - path);
- r = is_dir_full(dir_fd, path, true);
+ r = is_dir_at(dir_fd, path, /* follow = */ true);
if (r > 0)
return 0;
if (r == 0)
diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c
index 6a8ec1ba2a..ec6273c7d0 100644
--- a/src/basic/stat-util.c
+++ b/src/basic/stat-util.c
@@ -25,43 +25,130 @@
#include "stat-util.h"
#include "string-util.h"
-int is_symlink(const char *path) {
- struct stat info;
+static int verify_stat_at(
+ int fd,
+ const char *path,
+ bool follow,
+ int (*verify_func)(const struct stat *st),
+ bool verify) {
- assert(path);
+ struct stat st;
+ int r;
+
+ assert(fd >= 0 || fd == AT_FDCWD);
+ assert(!isempty(path) || !follow);
+ assert(verify_func);
- if (lstat(path, &info) < 0)
+ if (fstatat(fd, strempty(path), &st,
+ (isempty(path) ? AT_EMPTY_PATH : 0) | (follow ? 0 : AT_SYMLINK_NOFOLLOW)) < 0)
return -errno;
- return !!S_ISLNK(info.st_mode);
+ r = verify_func(&st);
+ return verify ? r : r >= 0;
}
-int is_dir_full(int atfd, const char* path, bool follow) {
- struct stat st;
- int r;
+int stat_verify_regular(const struct stat *st) {
+ assert(st);
- assert(atfd >= 0 || atfd == AT_FDCWD);
- assert(atfd >= 0 || path);
+ /* Checks whether the specified stat() structure refers to a regular file. If not returns an
+ * appropriate error code. */
- if (path)
- r = fstatat(atfd, path, &st, follow ? 0 : AT_SYMLINK_NOFOLLOW);
- else
- r = fstat(atfd, &st);
- if (r < 0)
- return -errno;
+ if (S_ISDIR(st->st_mode))
+ return -EISDIR;
+
+ if (S_ISLNK(st->st_mode))
+ return -ELOOP;
+
+ if (!S_ISREG(st->st_mode))
+ return -EBADFD;
- return !!S_ISDIR(st.st_mode);
+ return 0;
}
-int is_device_node(const char *path) {
- struct stat info;
+int verify_regular_at(int fd, const char *path, bool follow) {
+ return verify_stat_at(fd, path, follow, stat_verify_regular, true);
+}
- assert(path);
+int fd_verify_regular(int fd) {
+ assert(fd >= 0);
+ return verify_regular_at(fd, NULL, false);
+}
- if (lstat(path, &info) < 0)
- return -errno;
+int stat_verify_directory(const struct stat *st) {
+ assert(st);
- return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
+ if (S_ISLNK(st->st_mode))
+ return -ELOOP;
+
+ if (!S_ISDIR(st->st_mode))
+ return -ENOTDIR;
+
+ return 0;
+}
+
+int fd_verify_directory(int fd) {
+ assert(fd >= 0);
+ return verify_stat_at(fd, NULL, false, stat_verify_directory, true);
+}
+
+int is_dir_at(int fd, const char *path, bool follow) {
+ return verify_stat_at(fd, path, follow, stat_verify_directory, false);
+}
+
+int is_dir(const char *path, bool follow) {
+ assert(!isempty(path));
+ return is_dir_at(AT_FDCWD, path, follow);
+}
+
+int stat_verify_symlink(const struct stat *st) {
+ assert(st);
+
+ if (S_ISDIR(st->st_mode))
+ return -EISDIR;
+
+ if (!S_ISLNK(st->st_mode))
+ return -ENOLINK;
+
+ return 0;
+}
+
+int is_symlink(const char *path) {
+ assert(!isempty(path));
+ return verify_stat_at(AT_FDCWD, path, false, stat_verify_symlink, false);
+}
+
+int stat_verify_linked(const struct stat *st) {
+ assert(st);
+
+ if (st->st_nlink <= 0)
+ return -EIDRM; /* recognizable error. */
+
+ return 0;
+}
+
+int fd_verify_linked(int fd) {
+ assert(fd >= 0);
+ return verify_stat_at(fd, NULL, false, stat_verify_linked, true);
+}
+
+int stat_verify_device_node(const struct stat *st) {
+ assert(st);
+
+ if (S_ISLNK(st->st_mode))
+ return -ELOOP;
+
+ if (S_ISDIR(st->st_mode))
+ return -EISDIR;
+
+ if (!S_ISBLK(st->st_mode) && !S_ISCHR(st->st_mode))
+ return -ENOTTY;
+
+ return 0;
+}
+
+int is_device_node(const char *path) {
+ assert(!isempty(path));
+ return verify_stat_at(AT_FDCWD, path, false, stat_verify_device_node, false);
}
int dir_is_empty_at(int dir_fd, const char *path, bool ignore_hidden_or_backup) {
@@ -260,90 +347,6 @@ int path_is_network_fs(const char *path) {
return is_network_fs(&s);
}
-int stat_verify_linked(const struct stat *st) {
- assert(st);
-
- if (st->st_nlink <= 0)
- return -EIDRM; /* recognizable error. */
-
- return 0;
-}
-
-int fd_verify_linked(int fd) {
- struct stat st;
-
- assert(fd >= 0);
-
- if (fstat(fd, &st) < 0)
- return -errno;
-
- return stat_verify_linked(&st);
-}
-
-int stat_verify_regular(const struct stat *st) {
- assert(st);
-
- /* Checks whether the specified stat() structure refers to a regular file. If not returns an
- * appropriate error code. */
-
- if (S_ISDIR(st->st_mode))
- return -EISDIR;
-
- if (S_ISLNK(st->st_mode))
- return -ELOOP;
-
- if (!S_ISREG(st->st_mode))
- return -EBADFD;
-
- return 0;
-}
-
-int fd_verify_regular(int fd) {
- struct stat st;
-
- assert(fd >= 0);
-
- if (fstat(fd, &st) < 0)
- return -errno;
-
- return stat_verify_regular(&st);
-}
-
-int verify_regular_at(int dir_fd, const char *path, bool follow) {
- struct stat st;
-
- assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
- assert(path);
-
- if (fstatat(dir_fd, path, &st, (isempty(path) ? AT_EMPTY_PATH : 0) | (follow ? 0 : AT_SYMLINK_NOFOLLOW)) < 0)
- return -errno;
-
- return stat_verify_regular(&st);
-}
-
-int stat_verify_directory(const struct stat *st) {
- assert(st);
-
- if (S_ISLNK(st->st_mode))
- return -ELOOP;
-
- if (!S_ISDIR(st->st_mode))
- return -ENOTDIR;
-
- return 0;
-}
-
-int fd_verify_directory(int fd) {
- struct stat st;
-
- assert(fd >= 0);
-
- if (fstat(fd, &st) < 0)
- return -errno;
-
- return stat_verify_directory(&st);
-}
-
int proc_mounted(void) {
int r;
diff --git a/src/basic/stat-util.h b/src/basic/stat-util.h
index bab5415357..47445d852a 100644
--- a/src/basic/stat-util.h
+++ b/src/basic/stat-util.h
@@ -14,14 +14,22 @@
#include "siphash24.h"
#include "time-util.h"
+int stat_verify_regular(const struct stat *st);
+int verify_regular_at(int fd, const char *path, bool follow);
+int fd_verify_regular(int fd);
+
+int stat_verify_directory(const struct stat *st);
+int fd_verify_directory(int fd);
+int is_dir_at(int fd, const char *path, bool follow);
+int is_dir(const char *path, bool follow);
+
+int stat_verify_symlink(const struct stat *st);
int is_symlink(const char *path);
-int is_dir_full(int atfd, const char *fname, bool follow);
-static inline int is_dir(const char *path, bool follow) {
- return is_dir_full(AT_FDCWD, path, follow);
-}
-static inline int is_dir_fd(int fd) {
- return is_dir_full(fd, NULL, false);
-}
+
+int stat_verify_linked(const struct stat *st);
+int fd_verify_linked(int fd);
+
+int stat_verify_device_node(const struct stat *st);
int is_device_node(const char *path);
int dir_is_empty_at(int dir_fd, const char *path, bool ignore_hidden_or_backup);
@@ -72,16 +80,6 @@ int path_is_network_fs(const char *path);
*/
#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
-int stat_verify_linked(const struct stat *st);
-int fd_verify_linked(int fd);
-
-int stat_verify_regular(const struct stat *st);
-int fd_verify_regular(int fd);
-int verify_regular_at(int dir_fd, const char *path, bool follow);
-
-int stat_verify_directory(const struct stat *st);
-int fd_verify_directory(int fd);
-
int proc_mounted(void);
bool stat_inode_same(const struct stat *a, const struct stat *b);
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
index d1736f0aa3..3601be25fb 100644
--- a/src/basic/time-util.c
+++ b/src/basic/time-util.c
@@ -1573,7 +1573,7 @@ int verify_timezone(const char *name, int log_level) {
r = fd_verify_regular(fd);
if (r < 0)
- return log_full_errno(log_level, r, "Timezone file '%s' is not a regular file: %m", t);
+ return log_full_errno(log_level, r, "Timezone file '%s' is not a regular file: %m", t);
r = loop_read_exact(fd, buf, 4, false);
if (r < 0)
diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
index 7f6c146120..6afabef430 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -1066,10 +1066,8 @@ static int process_root_account(int rfd) {
FOREACH_STRING(s, "passwd", "shadow") {
r = verify_regular_at(pfd, s, /* follow = */ false);
- if (IN_SET(r, -EISDIR, -ELOOP, -EBADFD))
- return log_error_errno(r, "/etc/%s is not a regular file", s);
if (r < 0 && r != -ENOENT)
- return log_error_errno(r, "Failed to check whether /etc/%s is a regular file: %m", s);
+ return log_error_errno(r, "Verification of /etc/%s being regular file failed: %m", s);
r = should_configure(pfd, s);
if (r < 0)
diff --git a/src/kernel-install/kernel-install.c b/src/kernel-install/kernel-install.c
index 273c1d9c47..4df52c8342 100644
--- a/src/kernel-install/kernel-install.c
+++ b/src/kernel-install/kernel-install.c
@@ -801,7 +801,7 @@ static int context_ensure_layout(Context *c) {
if (!entry_token_path)
return log_oom();
- r = is_dir_full(c->rfd, entry_token_path, /* follow = */ false);
+ r = is_dir_at(c->rfd, entry_token_path, /* follow = */ false);
if (r < 0 && r != -ENOENT)
return log_error_errno(r, "Failed to check if '%s' is a directory: %m", entry_token_path);
if (r > 0) {