chiark / gitweb /
parse_boolean: require exact matches
[elogind.git] / src / shared / util.c
index bef87304e6ce20958297cc91391b1dc4ef65cf11..49c17eff85fdfa4137cf75551f250cb4068bd537 100644 (file)
@@ -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;
+}