X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=49c17eff85fdfa4137cf75551f250cb4068bd537;hp=bef87304e6ce20958297cc91391b1dc4ef65cf11;hb=0f625d0b87139fc18cd565c9b6da05c53a0eb7ab;hpb=418b9be50018303cde79b423d4701b7fd86ddbdc diff --git a/src/shared/util.c b/src/shared/util.c index bef87304e..49c17eff8 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -231,9 +231,9 @@ int unlink_noerrno(const char *path) { int parse_boolean(const char *v) { assert(v); - if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || strcaseeq(v, "on")) + if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on")) return 1; - else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || strcaseeq(v, "off")) + else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off")) return 0; return -EINVAL; @@ -3604,6 +3604,17 @@ int null_or_empty_path(const char *fn) { return null_or_empty(&st); } +int null_or_empty_fd(int fd) { + struct stat st; + + assert(fd >= 0); + + if (fstat(fd, &st) < 0) + return -errno; + + return null_or_empty(&st); +} + DIR *xopendirat(int fd, const char *name, int flags) { int nfd; DIR *d; @@ -3795,7 +3806,7 @@ bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) { return endswith(de->d_name, suffix); } -void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv[], char *env[]) { +void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv[]) { pid_t executor_pid; int r; @@ -3826,14 +3837,6 @@ void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); - if (!strv_isempty(env)) { - char **i; - - STRV_FOREACH(i, env) - putenv(*i); - } - - if (!d) { d = _d = opendir(directory); if (!d) { @@ -5427,7 +5430,7 @@ bool string_has_cc(const char *p, const char *ok) { for (t = p; *t; t++) { if (ok && strchr(ok, *t)) - return false; + continue; if (*t > 0 && *t < ' ') return true; @@ -6823,3 +6826,43 @@ bool is_localhost(const char *hostname) { endswith(hostname, ".localdomain") || endswith(hostname, ".localdomain."); } + +int take_password_lock(const char *root) { + + struct flock flock = { + .l_type = F_WRLCK, + .l_whence = SEEK_SET, + .l_start = 0, + .l_len = 0, + }; + + const char *path; + int fd, r; + + /* This is roughly the same as lckpwdf(), but not as awful. We + * don't want to use alarm() and signals, hence we implement + * our own trivial version of this. + * + * Note that shadow-utils also takes per-database locks in + * addition to lckpwdf(). However, we don't given that they + * are redundant as they they invoke lckpwdf() first and keep + * it during everything they do. The per-database locks are + * awfully racy, and thus we just won't do them. */ + + if (root) + path = strappenda(root, "/etc/.pwd.lock"); + else + path = "/etc/.pwd.lock"; + + fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600); + if (fd < 0) + return -errno; + + r = fcntl(fd, F_SETLKW, &flock); + if (r < 0) { + safe_close(fd); + return -errno; + } + + return fd; +}