chiark / gitweb /
core: introduce ConditionSecurity=audit
[elogind.git] / src / shared / fileio.c
index b0ab780d771b63e076cb8dabc159b95c55582bb6..38028b972ed2ed0e34ac10139e2bd0e8125fb599 100644 (file)
@@ -58,6 +58,28 @@ int write_string_file(const char *fn, const char *line) {
         return write_string_stream(f, line);
 }
 
+int write_string_file_no_create(const char *fn, const char *line) {
+        _cleanup_fclose_ FILE *f = NULL;
+        int fd;
+
+        assert(fn);
+        assert(line);
+
+        /* We manually build our own version of fopen(..., "we") that
+         * without O_CREAT */
+        fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY);
+        if (fd < 0)
+                return -errno;
+
+        f = fdopen(fd, "we");
+        if (!f) {
+                safe_close(fd);
+                return -errno;
+        }
+
+        return write_string_stream(f, line);
+}
+
 int write_string_file_atomic(const char *fn, const char *line) {
         _cleanup_fclose_ FILE *f = NULL;
         _cleanup_free_ char *p = NULL;
@@ -274,8 +296,9 @@ static int parse_env_file_internal(
                 const char *fname,
                 const char *newline,
                 int (*push) (const char *filename, unsigned line,
-                             const char *key, char *value, void *userdata),
-                void *userdata) {
+                             const char *key, char *value, void *userdata, int *n_pushed),
+                void *userdata,
+                int *n_pushed) {
 
         _cleanup_free_ char *contents = NULL, *key = NULL;
         size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_value_whitespace = (size_t) -1, last_key_whitespace = (size_t) -1;
@@ -364,7 +387,7 @@ static int parse_env_file_internal(
                                 if (last_key_whitespace != (size_t) -1)
                                         key[last_key_whitespace] = 0;
 
-                                r = push(fname, line, key, value, userdata);
+                                r = push(fname, line, key, value, userdata, n_pushed);
                                 if (r < 0)
                                         goto fail;
 
@@ -409,7 +432,7 @@ static int parse_env_file_internal(
                                 if (last_key_whitespace != (size_t) -1)
                                         key[last_key_whitespace] = 0;
 
-                                r = push(fname, line, key, value, userdata);
+                                r = push(fname, line, key, value, userdata, n_pushed);
                                 if (r < 0)
                                         goto fail;
 
@@ -544,7 +567,7 @@ static int parse_env_file_internal(
                 if (last_key_whitespace != (size_t) -1)
                         key[last_key_whitespace] = 0;
 
-                r = push(fname, line, key, value, userdata);
+                r = push(fname, line, key, value, userdata, n_pushed);
                 if (r < 0)
                         goto fail;
         }
@@ -559,7 +582,8 @@ fail:
 static int parse_env_file_push(
                 const char *filename, unsigned line,
                 const char *key, char *value,
-                void *userdata) {
+                void *userdata,
+                int *n_pushed) {
 
         const char *k;
         va_list aq, *ap = userdata;
@@ -591,6 +615,10 @@ static int parse_env_file_push(
                         va_end(aq);
                         free(*v);
                         *v = value;
+
+                        if (n_pushed)
+                                (*n_pushed)++;
+
                         return 1;
                 }
         }
@@ -606,22 +634,23 @@ int parse_env_file(
                 const char *newline, ...) {
 
         va_list ap;
-        int r;
+        int r, n_pushed = 0;
 
         if (!newline)
                 newline = NEWLINE;
 
         va_start(ap, newline);
-        r = parse_env_file_internal(NULL, fname, newline, parse_env_file_push, &ap);
+        r = parse_env_file_internal(NULL, fname, newline, parse_env_file_push, &ap, &n_pushed);
         va_end(ap);
 
-        return r;
+        return r < 0 ? r : n_pushed;
 }
 
 static int load_env_file_push(
                 const char *filename, unsigned line,
                 const char *key, char *value,
-                void *userdata) {
+                void *userdata,
+                int *n_pushed) {
         char ***m = userdata;
         char *p;
         int r;
@@ -648,6 +677,9 @@ static int load_env_file_push(
         if (r < 0)
                 return r;
 
+        if (n_pushed)
+                (*n_pushed)++;
+
         free(value);
         return 0;
 }
@@ -659,7 +691,7 @@ int load_env_file(FILE *f, const char *fname, const char *newline, char ***rl) {
         if (!newline)
                 newline = NEWLINE;
 
-        r = parse_env_file_internal(f, fname, newline, load_env_file_push, &m);
+        r = parse_env_file_internal(f, fname, newline, load_env_file_push, &m, NULL);
         if (r < 0) {
                 strv_free(m);
                 return r;
@@ -672,7 +704,8 @@ int load_env_file(FILE *f, const char *fname, const char *newline, char ***rl) {
 static int load_env_file_push_pairs(
                 const char *filename, unsigned line,
                 const char *key, char *value,
-                void *userdata) {
+                void *userdata,
+                int *n_pushed) {
         char ***m = userdata;
         int r;
 
@@ -704,6 +737,9 @@ static int load_env_file_push_pairs(
                         return r;
         }
 
+        if (n_pushed)
+                (*n_pushed)++;
+
         return 0;
 }
 
@@ -714,7 +750,7 @@ int load_env_file_pairs(FILE *f, const char *fname, const char *newline, char **
         if (!newline)
                 newline = NEWLINE;
 
-        r = parse_env_file_internal(f, fname, newline, load_env_file_push_pairs, &m);
+        r = parse_env_file_internal(f, fname, newline, load_env_file_push_pairs, &m, NULL);
         if (r < 0) {
                 strv_free(m);
                 return r;
@@ -738,11 +774,11 @@ static void write_env_var(FILE *f, const char *v) {
         p++;
         fwrite(v, 1, p-v, f);
 
-        if (string_has_cc(p, NULL) || chars_intersect(p, WHITESPACE "\'\"\\`$")) {
+        if (string_has_cc(p, NULL) || chars_intersect(p, WHITESPACE SHELL_NEED_QUOTES)) {
                 fputc('\"', f);
 
                 for (; *p; p++) {
-                        if (strchr("\'\"\\`$", *p))
+                        if (strchr(SHELL_NEED_ESCAPE, *p))
                                 fputc('\\', f);
 
                         fputc(*p, f);