chiark / gitweb /
honor SELinux labels, when creating and writing config files
authorHarald Hoyer <harald@redhat.com>
Thu, 14 Feb 2013 11:26:13 +0000 (12:26 +0100)
committerHarald Hoyer <harald@redhat.com>
Thu, 14 Feb 2013 15:19:38 +0000 (16:19 +0100)
Also split out some fileio functions to fileio.c and provide a SELinux
aware pendant in fileio-label.c

see https://bugzilla.redhat.com/show_bug.cgi?id=881577

57 files changed:
Makefile.am
src/analyze/systemd-analyze.c
src/binfmt/binfmt.c
src/bootchart/bootchart.c
src/cgtop/cgtop.c
src/core/cgroup-attr.c
src/core/condition.c
src/core/dbus-execute.c
src/core/dbus-unit.c
src/core/execute.c
src/core/hostname-setup.c
src/core/locale-setup.c
src/core/machine-id-setup.c
src/core/main.c
src/core/service.c
src/core/unit.c
src/fsck/fsck.c
src/fstab-generator/fstab-generator.c
src/getty-generator/getty-generator.c
src/hostname/hostnamectl.c
src/hostname/hostnamed.c
src/journal/journald-server.c
src/locale/localed.c
src/login/logind-dbus.c
src/login/logind-inhibit.c
src/login/logind-session.c
src/login/logind-user.c
src/login/pam-module.c
src/login/sd-login.c
src/login/user-sessions.c
src/modules-load/modules-load.c
src/nspawn/nspawn.c
src/quotacheck/quotacheck.c
src/readahead/readahead-common.c
src/shared/audit.c
src/shared/capability.c
src/shared/cgroup-util.c
src/shared/fileio-label.c [new file with mode: 0644]
src/shared/fileio-label.h [new file with mode: 0644]
src/shared/fileio.c [new file with mode: 0644]
src/shared/fileio.h [new file with mode: 0644]
src/shared/hwclock.c
src/shared/label.c
src/shared/label.h
src/shared/socket-util.c
src/shared/util.c
src/shared/util.h
src/shared/virt.c
src/shutdownd/shutdownd.c
src/sleep/sleep.c
src/sysctl/sysctl.c
src/systemctl/systemctl.c
src/test/test-unit-file.c
src/timedate/timedated.c
src/udev/udev-builtin-net_id.c
src/udev/udevd.c
src/vconsole/vconsole-setup.c

index 403439b..10934eb 100644 (file)
@@ -623,6 +623,8 @@ libsystemd_shared_la_SOURCES = \
        src/shared/time-dst.h \
        src/shared/calendarspec.c \
        src/shared/calendarspec.h \
+       src/shared/fileio.c \
+       src/shared/fileio.h \
        src/shared/output-mode.h
 
 #-------------------------------------------------------------------------------
@@ -675,6 +677,8 @@ libsystemd_label_la_SOURCES = \
        src/shared/mkdir.h \
        src/shared/ask-password-api.c \
        src/shared/ask-password-api.h \
+       src/shared/fileio-label.c \
+       src/shared/fileio-label.h \
        src/shared/dev-setup.c \
        src/shared/dev-setup.h
 
@@ -2898,6 +2902,7 @@ systemd_hostnamed_CFLAGS = \
        $(DBUS_CFLAGS)
 
 systemd_hostnamed_LDADD = \
+       libsystemd-label.la \
        libsystemd-shared.la \
        libsystemd-daemon.la \
        libsystemd-dbus.la
@@ -3034,6 +3039,7 @@ systemd_timedated_CFLAGS = \
        $(DBUS_CFLAGS)
 
 systemd_timedated_LDADD = \
+       libsystemd-label.la \
        libsystemd-shared.la \
        libsystemd-daemon.la \
        libsystemd-dbus.la
index 88fb406..b7e1670 100644 (file)
@@ -31,6 +31,7 @@
 #include "build.h"
 #include "util.h"
 #include "strxcpyx.h"
+#include "fileio.h"
 
 #define compare(a, b) (((a) > (b))? 1 : (((b) > (a))? -1 : 0))
 #define svg(...) printf(__VA_ARGS__)
index f8c97b5..909eef7 100644 (file)
@@ -33,6 +33,7 @@
 #include "strv.h"
 #include "util.h"
 #include "conf-files.h"
+#include "fileio.h"
 
 static const char conf_file_dirs[] =
         "/etc/binfmt.d\0"
index fb95c6b..adfaba5 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "bootchart.h"
 #include "util.h"
+#include "fileio.h"
 
 double graph_start;
 double log_start;
index f2e6276..f80d51e 100644 (file)
@@ -31,6 +31,7 @@
 #include "hashmap.h"
 #include "cgroup-util.h"
 #include "build.h"
+#include "fileio.h"
 
 typedef struct Group {
         char *path;
index aed4e99..1373684 100644 (file)
@@ -22,6 +22,7 @@
 #include "cgroup-attr.h"
 #include "cgroup-util.h"
 #include "list.h"
+#include "fileio.h"
 
 int cgroup_attribute_apply(CGroupAttribute *a, CGroupBonding *b) {
         int r;
index b318492..30199c1 100644 (file)
@@ -36,6 +36,7 @@
 #include "condition.h"
 #include "virt.h"
 #include "path-util.h"
+#include "fileio.h"
 
 Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) {
         Condition *c;
index e815cb5..53394c2 100644 (file)
@@ -29,6 +29,7 @@
 #include "strv.h"
 #include "dbus-common.h"
 #include "syscall-list.h"
+#include "fileio.h"
 
 DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_input, exec_input, ExecInput);
 DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_output, exec_output, ExecOutput);
index d1de46a..4f968c2 100644 (file)
@@ -30,6 +30,7 @@
 #include "cgroup-util.h"
 #include "strv.h"
 #include "path-util.h"
+#include "fileio.h"
 
 const char bus_unit_interface[] _introspect_("Unit") = BUS_UNIT_INTERFACE;
 
index aa58bc4..3376adc 100644 (file)
@@ -65,6 +65,7 @@
 #include "path-util.h"
 #include "syscall-list.h"
 #include "env-util.h"
+#include "fileio.h"
 
 #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
 
index 7894f8a..ac508af 100644 (file)
@@ -29,6 +29,7 @@
 #include "macro.h"
 #include "util.h"
 #include "log.h"
+#include "fileio.h"
 
 static int read_and_strip_hostname(const char *path, char **hn) {
         char *s;
index 48b59bf..eefb256 100644 (file)
@@ -27,6 +27,7 @@
 #include "util.h"
 #include "macro.h"
 #include "virt.h"
+#include "fileio.h"
 
 enum {
         /* We don't list LC_ALL here on purpose. People should be
index 7f4c23b..ca16397 100644 (file)
@@ -35,6 +35,7 @@
 #include "mkdir.h"
 #include "log.h"
 #include "virt.h"
+#include "fileio.h"
 
 static int shorten_uuid(char destination[36], const char *source) {
         unsigned i, j;
index a2b0a39..71e0a6c 100644 (file)
@@ -66,6 +66,7 @@
 #include "locale-setup.h"
 #include "selinux-setup.h"
 #include "ima-setup.h"
+#include "fileio.h"
 
 static enum {
         ACTION_RUN,
index 9c4bc41..c510736 100644 (file)
@@ -43,6 +43,7 @@
 #include "util.h"
 #include "utf8.h"
 #include "env-util.h"
+#include "fileio.h"
 
 #ifdef HAVE_SYSV_COMPAT
 
index f7d00b6..86aaa15 100644 (file)
@@ -46,6 +46,8 @@
 #include "missing.h"
 #include "cgroup-attr.h"
 #include "mkdir.h"
+#include "label.h"
+#include "fileio-label.h"
 
 const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
         [UNIT_SERVICE] = &service_vtable,
@@ -2778,7 +2780,7 @@ int unit_write_drop_in(Unit *u, bool runtime, const char *name, const char *data
                 return -ENOMEM;
 
         mkdir_p(p, 0755);
-        return write_one_line_file_atomic(q, data);
+        return write_one_line_file_atomic_label(q, data);
 }
 
 int unit_remove_drop_in(Unit *u, bool runtime, const char *name) {
index f5d38ad..f692b3a 100644 (file)
@@ -35,6 +35,7 @@
 #include "special.h"
 #include "bus-errors.h"
 #include "virt.h"
+#include "fileio.h"
 
 static bool arg_skip = false;
 static bool arg_force = false;
index 2b67bb6..ad26acb 100644 (file)
@@ -33,6 +33,7 @@
 #include "special.h"
 #include "mkdir.h"
 #include "virt.h"
+#include "fileio.h"
 
 static const char *arg_dest = "/tmp";
 static bool arg_enabled = true;
index cb38f21..e811830 100644 (file)
@@ -28,6 +28,7 @@
 #include "mkdir.h"
 #include "unit-name.h"
 #include "virt.h"
+#include "fileio.h"
 
 static const char *arg_dest = "/tmp";
 
index ff1f091..7945c86 100644 (file)
@@ -36,6 +36,7 @@
 #include "strv.h"
 #include "sd-id128.h"
 #include "virt.h"
+#include "fileio.h"
 
 static enum transport {
         TRANSPORT_NORMAL,
index c5a8b6f..7ea891c 100644 (file)
@@ -33,6 +33,8 @@
 #include "def.h"
 #include "virt.h"
 #include "env-util.h"
+#include "fileio-label.h"
+#include "label.h"
 
 #define INTERFACE \
         " <interface name=\"org.freedesktop.hostname1\">\n"             \
@@ -287,8 +289,7 @@ static int write_data_static_hostname(void) {
 
                 return 0;
         }
-
-        return write_one_line_file_atomic("/etc/hostname", data[PROP_STATIC_HOSTNAME]);
+        return write_one_line_file_atomic_label("/etc/hostname", data[PROP_STATIC_HOSTNAME]);
 }
 
 static int write_data_other(void) {
@@ -338,7 +339,7 @@ static int write_data_other(void) {
                 return 0;
         }
 
-        r = write_env_file("/etc/machine-info", l);
+        r = write_env_file_label("/etc/machine-info", l);
         strv_free(l);
 
         return r;
@@ -683,6 +684,7 @@ int main(int argc, char *argv[]) {
         log_open();
 
         umask(0022);
+        label_init("/etc");
 
         if (argc == 2 && streq(argv[1], "--introspect")) {
                 fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
index 1375d7a..818bd08 100644 (file)
@@ -34,6 +34,7 @@
 #include <systemd/sd-login.h>
 #endif
 
+#include "fileio.h"
 #include "mkdir.h"
 #include "hashmap.h"
 #include "journal-file.h"
index fedcdfb..4f85b8b 100644 (file)
@@ -32,6 +32,9 @@
 #include "polkit.h"
 #include "def.h"
 #include "env-util.h"
+#include "fileio.h"
+#include "fileio-label.h"
+#include "label.h"
 
 #define INTERFACE                                                       \
         " <interface name=\"org.freedesktop.locale1\">\n"               \
@@ -390,7 +393,7 @@ static int write_data_locale(void) {
                 return 0;
         }
 
-        r = write_env_file("/etc/locale.conf", l);
+        r = write_env_file_label("/etc/locale.conf", l);
         strv_free(l);
 
         return r;
@@ -546,7 +549,7 @@ static int write_data_vconsole(void) {
                 return 0;
         }
 
-        r = write_env_file("/etc/vconsole.conf", l);
+        r = write_env_file_label("/etc/vconsole.conf", l);
         strv_free(l);
 
         return r;
@@ -1364,7 +1367,7 @@ int main(int argc, char *argv[]) {
         log_set_target(LOG_TARGET_AUTO);
         log_parse_environment();
         log_open();
-
+        label_init("/etc");
         umask(0022);
 
         if (argc == 2 && streq(argv[1], "--introspect")) {
index f351859..d235474 100644 (file)
@@ -33,6 +33,8 @@
 #include "special.h"
 #include "systemd/sd-id128.h"
 #include "systemd/sd-messages.h"
+#include "fileio-label.h"
+#include "label.h"
 
 #define BUS_MANAGER_INTERFACE                                           \
         " <interface name=\"org.freedesktop.login1.Manager\">\n"        \
@@ -937,7 +939,8 @@ static int attach_device(Manager *m, const char *seat, const char *sysfs) {
         }
 
         mkdir_p_label("/etc/udev/rules.d", 0755);
-        r = write_one_line_file_atomic(file, rule);
+        label_init("/etc");
+        r = write_one_line_file_atomic_label(file, rule);
         if (r < 0)
                 goto finish;
 
index 2c1a412..9994084 100644 (file)
@@ -30,6 +30,7 @@
 #include "mkdir.h"
 #include "path-util.h"
 #include "logind-inhibit.h"
+#include "fileio.h"
 
 Inhibitor* inhibitor_new(Manager *m, const char* id) {
         Inhibitor *i;
index b981e14..71c7912 100644 (file)
@@ -33,6 +33,7 @@
 #include "path-util.h"
 #include "cgroup-util.h"
 #include "logind-session.h"
+#include "fileio.h"
 
 Session* session_new(Manager *m, User *u, const char *id) {
         Session *s;
index b692b53..411215a 100644 (file)
@@ -29,6 +29,7 @@
 #include "cgroup-util.h"
 #include "hashmap.h"
 #include "strv.h"
+#include "fileio.h"
 
 User* user_new(Manager *m, uid_t uid, gid_t gid, const char *name) {
         User *u;
index 88b0ef9..702095e 100644 (file)
@@ -41,6 +41,7 @@
 #include "dbus-common.h"
 #include "def.h"
 #include "socket-util.h"
+#include "fileio.h"
 
 static int parse_argv(pam_handle_t *handle,
                       int argc, const char **argv,
index b81dddf..8867e8c 100644 (file)
@@ -29,6 +29,7 @@
 #include "macro.h"
 #include "sd-login.h"
 #include "strv.h"
+#include "fileio.h"
 
 _public_ int sd_pid_get_session(pid_t pid, char **session) {
         int r;
index 91531e8..c6f8fa7 100644 (file)
@@ -26,6 +26,7 @@
 #include "log.h"
 #include "util.h"
 #include "cgroup-util.h"
+#include "fileio.h"
 
 int main(int argc, char*argv[]) {
         int ret = EXIT_FAILURE;
index 88b1261..28b53ec 100644 (file)
@@ -34,6 +34,7 @@
 #include "strv.h"
 #include "conf-files.h"
 #include "virt.h"
+#include "fileio.h"
 
 static char **arg_proc_cmdline_modules = NULL;
 
index 4c87371..1d602a5 100644 (file)
@@ -57,6 +57,7 @@
 #include "dev-setup.h"
 #include "fdset.h"
 #include "build.h"
+#include "fileio.h"
 
 typedef enum LinkJournal {
         LINK_NO,
index e7a4405..32f3ff9 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "util.h"
 #include "virt.h"
+#include "fileio.h"
 
 static bool arg_skip = false;
 static bool arg_force = false;
index 41aaff0..81bb16c 100644 (file)
@@ -33,6 +33,7 @@
 #include "readahead-common.h"
 #include "util.h"
 #include "missing.h"
+#include "fileio.h"
 
 int file_verify(int fd, const char *fn, off_t file_size_max, struct stat *st) {
         assert(fd >= 0);
index e5c483a..138ca1d 100644 (file)
@@ -33,6 +33,7 @@
 #include "audit.h"
 #include "util.h"
 #include "log.h"
+#include "fileio.h"
 
 int audit_session_from_pid(pid_t pid, uint32_t *id) {
         char *s;
index 9b743e8..cad718d 100644 (file)
@@ -34,6 +34,7 @@
 #include "capability.h"
 #include "util.h"
 #include "log.h"
+#include "fileio.h"
 
 int have_effective_cap(int value) {
         cap_t cap;
index 7efbc2e..be00b40 100644 (file)
@@ -37,6 +37,7 @@
 #include "path-util.h"
 #include "strv.h"
 #include "unit-name.h"
+#include "fileio.h"
 
 int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) {
         char *fs;
diff --git a/src/shared/fileio-label.c b/src/shared/fileio-label.c
new file mode 100644 (file)
index 0000000..5bf127b
--- /dev/null
@@ -0,0 +1,55 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+  Copyright 2010 Harald Hoyer
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "fileio-label.h"
+#include "label.h"
+
+int write_one_line_file_atomic_label(const char *fn, const char *line) {
+        int r;
+
+        r = label_context_set(fn, S_IFREG);
+        if (r  < 0)
+                return r;
+
+        write_one_line_file_atomic(fn, line);
+
+        label_context_clear();
+
+        return r;
+}
+
+int write_env_file_label(const char *fname, char **l) {
+        int r;
+
+        r = label_context_set(fname, S_IFREG);
+        if (r  < 0)
+                return r;
+
+        write_env_file(fname, l);
+
+        label_context_clear();
+
+        return r;
+}
diff --git a/src/shared/fileio-label.h b/src/shared/fileio-label.h
new file mode 100644 (file)
index 0000000..cc5ce34
--- /dev/null
@@ -0,0 +1,29 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+  Copyright 2010 Harald Hoyer
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include "fileio.h"
+
+int write_one_line_file_atomic_label(const char *fn, const char *line);
+int write_env_file_label(const char *fname, char **l);
diff --git a/src/shared/fileio.c b/src/shared/fileio.c
new file mode 100644 (file)
index 0000000..4e6ff16
--- /dev/null
@@ -0,0 +1,383 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include "fileio.h"
+#include "util.h"
+#include "strv.h"
+
+int write_one_line_file(const char *fn, const char *line) {
+        _cleanup_fclose_ FILE *f = NULL;
+
+        assert(fn);
+        assert(line);
+
+        f = fopen(fn, "we");
+        if (!f)
+                return -errno;
+
+        errno = 0;
+        if (fputs(line, f) < 0)
+                return errno ? -errno : -EIO;
+
+        if (!endswith(line, "\n"))
+                fputc('\n', f);
+
+        fflush(f);
+
+        if (ferror(f))
+                return errno ? -errno : -EIO;
+
+        return 0;
+}
+
+int write_one_line_file_atomic(const char *fn, const char *line) {
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_free_ char *p = NULL;
+        int r;
+
+        assert(fn);
+        assert(line);
+
+        r = fopen_temporary(fn, &f, &p);
+        if (r < 0)
+                return r;
+
+        fchmod_umask(fileno(f), 0644);
+
+        errno = 0;
+        if (fputs(line, f) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        if (!endswith(line, "\n"))
+                fputc('\n', f);
+
+        fflush(f);
+
+        if (ferror(f))
+                r = errno ? -errno : -EIO;
+        else {
+                if (rename(p, fn) < 0)
+                        r = -errno;
+                else
+                        r = 0;
+        }
+
+finish:
+        if (r < 0)
+                unlink(p);
+
+        return r;
+}
+
+int read_one_line_file(const char *fn, char **line) {
+        _cleanup_fclose_ FILE *f = NULL;
+        char t[LINE_MAX], *c;
+
+        assert(fn);
+        assert(line);
+
+        f = fopen(fn, "re");
+        if (!f)
+                return -errno;
+
+        if (!fgets(t, sizeof(t), f)) {
+
+                if (ferror(f))
+                        return errno ? -errno : -EIO;
+
+                t[0] = 0;
+        }
+
+        c = strdup(t);
+        if (!c)
+                return -ENOMEM;
+        truncate_nl(c);
+
+        *line = c;
+        return 0;
+}
+
+int read_full_file(const char *fn, char **contents, size_t *size) {
+        _cleanup_fclose_ FILE *f = NULL;
+        size_t n, l;
+        _cleanup_free_ char *buf = NULL;
+        struct stat st;
+
+        assert(fn);
+        assert(contents);
+
+        f = fopen(fn, "re");
+        if (!f)
+                return -errno;
+
+        if (fstat(fileno(f), &st) < 0)
+                return -errno;
+
+        /* Safety check */
+        if (st.st_size > 4*1024*1024)
+                return -E2BIG;
+
+        n = st.st_size > 0 ? st.st_size : LINE_MAX;
+        l = 0;
+
+        for (;;) {
+                char *t;
+                size_t k;
+
+                t = realloc(buf, n+1);
+                if (!t)
+                        return -ENOMEM;
+
+                buf = t;
+                k = fread(buf + l, 1, n - l, f);
+
+                if (k <= 0) {
+                        if (ferror(f))
+                                return -errno;
+
+                        break;
+                }
+
+                l += k;
+                n *= 2;
+
+                /* Safety check */
+                if (n > 4*1024*1024)
+                        return -E2BIG;
+        }
+
+        buf[l] = 0;
+        *contents = buf;
+        buf = NULL;
+
+        if (size)
+                *size = l;
+
+        return 0;
+}
+
+int parse_env_file(
+                const char *fname,
+                const char *separator, ...) {
+
+        int r = 0;
+        char *contents = NULL, *p;
+
+        assert(fname);
+        assert(separator);
+
+        if ((r = read_full_file(fname, &contents, NULL)) < 0)
+                return r;
+
+        p = contents;
+        for (;;) {
+                const char *key = NULL;
+
+                p += strspn(p, separator);
+                p += strspn(p, WHITESPACE);
+
+                if (!*p)
+                        break;
+
+                if (!strchr(COMMENTS, *p)) {
+                        va_list ap;
+                        char **value;
+
+                        va_start(ap, separator);
+                        while ((key = va_arg(ap, char *))) {
+                                size_t n;
+                                char *v;
+
+                                value = va_arg(ap, char **);
+
+                                n = strlen(key);
+                                if (!strneq(p, key, n) ||
+                                    p[n] != '=')
+                                        continue;
+
+                                p += n + 1;
+                                n = strcspn(p, separator);
+
+                                if (n >= 2 &&
+                                    strchr(QUOTES, p[0]) &&
+                                    p[n-1] == p[0])
+                                        v = strndup(p+1, n-2);
+                                else
+                                        v = strndup(p, n);
+
+                                if (!v) {
+                                        r = -ENOMEM;
+                                        va_end(ap);
+                                        goto fail;
+                                }
+
+                                if (v[0] == '\0') {
+                                        /* return empty value strings as NULL */
+                                        free(v);
+                                        v = NULL;
+                                }
+
+                                free(*value);
+                                *value = v;
+
+                                p += n;
+
+                                r ++;
+                                break;
+                        }
+                        va_end(ap);
+                }
+
+                if (!key)
+                        p += strcspn(p, separator);
+        }
+
+fail:
+        free(contents);
+        return r;
+}
+
+int load_env_file(const char *fname, char ***rl) {
+
+        _cleanup_fclose_ FILE *f;
+        _cleanup_strv_free_ char **m = NULL;
+        _cleanup_free_ char *c = NULL;
+
+        assert(fname);
+        assert(rl);
+
+        /* This reads an environment file, but will not complain about
+         * any invalid assignments, that needs to be done by the
+         * caller */
+
+        f = fopen(fname, "re");
+        if (!f)
+                return -errno;
+
+        while (!feof(f)) {
+                char l[LINE_MAX], *p, *cs, *b;
+
+                if (!fgets(l, sizeof(l), f)) {
+                        if (ferror(f))
+                                return -errno;
+
+                        /* The previous line was a continuation line?
+                         * Let's process it now, before we leave the
+                         * loop */
+                        if (c)
+                                goto process;
+
+                        break;
+                }
+
+                /* Is this a continuation line? If so, just append
+                 * this to c, and go to next line right-away */
+                cs = endswith(l, "\\\n");
+                if (cs) {
+                        *cs = '\0';
+                        b = strappend(c, l);
+                        if (!b)
+                                return -ENOMEM;
+
+                        free(c);
+                        c = b;
+                        continue;
+                }
+
+                /* If the previous line was a continuation line,
+                 * append the current line to it */
+                if (c) {
+                        b = strappend(c, l);
+                        if (!b)
+                                return -ENOMEM;
+
+                        free(c);
+                        c = b;
+                }
+
+        process:
+                p = strstrip(c ? c : l);
+
+                if (*p && !strchr(COMMENTS, *p)) {
+                        _cleanup_free_ char *u;
+                        int k;
+
+                        u = normalize_env_assignment(p);
+                        if (!u)
+                                return -ENOMEM;
+
+                        k = strv_extend(&m, u);
+                        if (k < 0)
+                                return -ENOMEM;
+                }
+
+                free(c);
+                c = NULL;
+        }
+
+        *rl = m;
+        m = NULL;
+
+        return 0;
+}
+
+int write_env_file(const char *fname, char **l) {
+        char **i, *p;
+        FILE *f;
+        int r;
+
+        r = fopen_temporary(fname, &f, &p);
+        if (r < 0)
+                return r;
+
+        fchmod_umask(fileno(f), 0644);
+
+        errno = 0;
+        STRV_FOREACH(i, l) {
+                fputs(*i, f);
+                fputc('\n', f);
+        }
+
+        fflush(f);
+
+        if (ferror(f)) {
+                if (errno != 0)
+                        r = -errno;
+                else
+                        r = -EIO;
+        } else {
+                if (rename(p, fname) < 0)
+                        r = -errno;
+                else
+                        r = 0;
+        }
+
+        if (r < 0)
+                unlink(p);
+
+        fclose(f);
+        free(p);
+
+        return r;
+}
diff --git a/src/shared/fileio.h b/src/shared/fileio.h
new file mode 100644 (file)
index 0000000..0023204
--- /dev/null
@@ -0,0 +1,33 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+#include <stddef.h>
+#include "macro.h"
+
+int write_one_line_file(const char *fn, const char *line);
+int write_one_line_file_atomic(const char *fn, const char *line);
+int read_one_line_file(const char *fn, char **line);
+int read_full_file(const char *fn, char **contents, size_t *size);
+
+int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
+int load_env_file(const char *fname, char ***l);
+int write_env_file(const char *fname, char **l);
index f9adf03..488c30e 100644 (file)
@@ -41,6 +41,7 @@
 #include "log.h"
 #include "strv.h"
 #include "hwclock.h"
+#include "fileio.h"
 
 static int rtc_open(int flags) {
         int fd;
index d353da5..a8bf6bd 100644 (file)
 #include <malloc.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 
 #include "label.h"
+#include "strv.h"
 #include "util.h"
 #include "path-util.h"
 
index 1220b18..dda4d1c 100644 (file)
@@ -45,3 +45,7 @@ int label_mkdir(const char *path, mode_t mode, bool apply);
 void label_retest_selinux(void);
 
 int label_bind(int fd, const struct sockaddr *addr, socklen_t addrlen);
+
+int label_write_one_line_file_atomic(const char *fn, const char *line);
+int label_write_env_file(const char *fname, char **l);
+int label_fopen_temporary(const char *path, FILE **_f, char **_temp_path);
index 39b6142..6c94d69 100644 (file)
@@ -38,6 +38,7 @@
 #include "path-util.h"
 #include "socket-util.h"
 #include "missing.h"
+#include "fileio.h"
 
 int socket_address_parse(SocketAddress *a, const char *s) {
         int r;
index 4f0b652..1527249 100644 (file)
@@ -71,6 +71,7 @@
 #include "exit-status.h"
 #include "hashmap.h"
 #include "env-util.h"
+#include "fileio.h"
 
 int saved_argc = 0;
 char **saved_argv = NULL;
@@ -528,31 +529,6 @@ int get_starttime_of_pid(pid_t pid, unsigned long long *st) {
         return 0;
 }
 
-int write_one_line_file(const char *fn, const char *line) {
-        _cleanup_fclose_ FILE *f = NULL;
-
-        assert(fn);
-        assert(line);
-
-        f = fopen(fn, "we");
-        if (!f)
-                return -errno;
-
-        errno = 0;
-        if (fputs(line, f) < 0)
-                return errno ? -errno : -EIO;
-
-        if (!endswith(line, "\n"))
-                fputc('\n', f);
-
-        fflush(f);
-
-        if (ferror(f))
-                return errno ? -errno : -EIO;
-
-        return 0;
-}
-
 int fchmod_umask(int fd, mode_t m) {
         mode_t u;
         int r;
@@ -564,339 +540,6 @@ int fchmod_umask(int fd, mode_t m) {
         return r;
 }
 
-int write_one_line_file_atomic(const char *fn, const char *line) {
-        _cleanup_fclose_ FILE *f = NULL;
-        _cleanup_free_ char *p = NULL;
-        int r;
-
-        assert(fn);
-        assert(line);
-
-        r = fopen_temporary(fn, &f, &p);
-        if (r < 0)
-                return r;
-
-        fchmod_umask(fileno(f), 0644);
-
-        errno = 0;
-        if (fputs(line, f) < 0) {
-                r = -errno;
-                goto finish;
-        }
-
-        if (!endswith(line, "\n"))
-                fputc('\n', f);
-
-        fflush(f);
-
-        if (ferror(f))
-                r = errno ? -errno : -EIO;
-        else {
-                if (rename(p, fn) < 0)
-                        r = -errno;
-                else
-                        r = 0;
-        }
-
-finish:
-        if (r < 0)
-                unlink(p);
-
-        return r;
-}
-
-int read_one_line_file(const char *fn, char **line) {
-        _cleanup_fclose_ FILE *f = NULL;
-        char t[LINE_MAX], *c;
-
-        assert(fn);
-        assert(line);
-
-        f = fopen(fn, "re");
-        if (!f)
-                return -errno;
-
-        if (!fgets(t, sizeof(t), f)) {
-
-                if (ferror(f))
-                        return errno ? -errno : -EIO;
-
-                t[0] = 0;
-        }
-
-        c = strdup(t);
-        if (!c)
-                return -ENOMEM;
-        truncate_nl(c);
-
-        *line = c;
-        return 0;
-}
-
-int read_full_file(const char *fn, char **contents, size_t *size) {
-        _cleanup_fclose_ FILE *f = NULL;
-        size_t n, l;
-        _cleanup_free_ char *buf = NULL;
-        struct stat st;
-
-        assert(fn);
-        assert(contents);
-
-        f = fopen(fn, "re");
-        if (!f)
-                return -errno;
-
-        if (fstat(fileno(f), &st) < 0)
-                return -errno;
-
-        /* Safety check */
-        if (st.st_size > 4*1024*1024)
-                return -E2BIG;
-
-        n = st.st_size > 0 ? st.st_size : LINE_MAX;
-        l = 0;
-
-        for (;;) {
-                char *t;
-                size_t k;
-
-                t = realloc(buf, n+1);
-                if (!t)
-                        return -ENOMEM;
-
-                buf = t;
-                k = fread(buf + l, 1, n - l, f);
-
-                if (k <= 0) {
-                        if (ferror(f))
-                                return -errno;
-
-                        break;
-                }
-
-                l += k;
-                n *= 2;
-
-                /* Safety check */
-                if (n > 4*1024*1024)
-                        return -E2BIG;
-        }
-
-        buf[l] = 0;
-        *contents = buf;
-        buf = NULL;
-
-        if (size)
-                *size = l;
-
-        return 0;
-}
-
-int parse_env_file(
-                const char *fname,
-                const char *separator, ...) {
-
-        int r = 0;
-        char *contents = NULL, *p;
-
-        assert(fname);
-        assert(separator);
-
-        if ((r = read_full_file(fname, &contents, NULL)) < 0)
-                return r;
-
-        p = contents;
-        for (;;) {
-                const char *key = NULL;
-
-                p += strspn(p, separator);
-                p += strspn(p, WHITESPACE);
-
-                if (!*p)
-                        break;
-
-                if (!strchr(COMMENTS, *p)) {
-                        va_list ap;
-                        char **value;
-
-                        va_start(ap, separator);
-                        while ((key = va_arg(ap, char *))) {
-                                size_t n;
-                                char *v;
-
-                                value = va_arg(ap, char **);
-
-                                n = strlen(key);
-                                if (!strneq(p, key, n) ||
-                                    p[n] != '=')
-                                        continue;
-
-                                p += n + 1;
-                                n = strcspn(p, separator);
-
-                                if (n >= 2 &&
-                                    strchr(QUOTES, p[0]) &&
-                                    p[n-1] == p[0])
-                                        v = strndup(p+1, n-2);
-                                else
-                                        v = strndup(p, n);
-
-                                if (!v) {
-                                        r = -ENOMEM;
-                                        va_end(ap);
-                                        goto fail;
-                                }
-
-                                if (v[0] == '\0') {
-                                        /* return empty value strings as NULL */
-                                        free(v);
-                                        v = NULL;
-                                }
-
-                                free(*value);
-                                *value = v;
-
-                                p += n;
-
-                                r ++;
-                                break;
-                        }
-                        va_end(ap);
-                }
-
-                if (!key)
-                        p += strcspn(p, separator);
-        }
-
-fail:
-        free(contents);
-        return r;
-}
-
-int load_env_file(const char *fname, char ***rl) {
-
-        _cleanup_fclose_ FILE *f;
-        _cleanup_strv_free_ char **m = NULL;
-        _cleanup_free_ char *c = NULL;
-
-        assert(fname);
-        assert(rl);
-
-        /* This reads an environment file, but will not complain about
-         * any invalid assignments, that needs to be done by the
-         * caller */
-
-        f = fopen(fname, "re");
-        if (!f)
-                return -errno;
-
-        while (!feof(f)) {
-                char l[LINE_MAX], *p, *cs, *b;
-
-                if (!fgets(l, sizeof(l), f)) {
-                        if (ferror(f))
-                                return -errno;
-
-                        /* The previous line was a continuation line?
-                         * Let's process it now, before we leave the
-                         * loop */
-                        if (c)
-                                goto process;
-
-                        break;
-                }
-
-                /* Is this a continuation line? If so, just append
-                 * this to c, and go to next line right-away */
-                cs = endswith(l, "\\\n");
-                if (cs) {
-                        *cs = '\0';
-                        b = strappend(c, l);
-                        if (!b)
-                                return -ENOMEM;
-
-                        free(c);
-                        c = b;
-                        continue;
-                }
-
-                /* If the previous line was a continuation line,
-                 * append the current line to it */
-                if (c) {
-                        b = strappend(c, l);
-                        if (!b)
-                                return -ENOMEM;
-
-                        free(c);
-                        c = b;
-                }
-
-        process:
-                p = strstrip(c ? c : l);
-
-                if (*p && !strchr(COMMENTS, *p)) {
-                        _cleanup_free_ char *u;
-                        int k;
-
-                        u = normalize_env_assignment(p);
-                        if (!u)
-                                return -ENOMEM;
-
-                        k = strv_extend(&m, u);
-                        if (k < 0)
-                                return -ENOMEM;
-                }
-
-                free(c);
-                c = NULL;
-        }
-
-        *rl = m;
-        m = NULL;
-
-        return 0;
-}
-
-int write_env_file(const char *fname, char **l) {
-        char **i, *p;
-        FILE *f;
-        int r;
-
-        r = fopen_temporary(fname, &f, &p);
-        if (r < 0)
-                return r;
-
-        fchmod_umask(fileno(f), 0644);
-
-        errno = 0;
-        STRV_FOREACH(i, l) {
-                fputs(*i, f);
-                fputc('\n', f);
-        }
-
-        fflush(f);
-
-        if (ferror(f)) {
-                if (errno != 0)
-                        r = -errno;
-                else
-                        r = -EIO;
-        } else {
-                if (rename(p, fname) < 0)
-                        r = -errno;
-                else
-                        r = 0;
-        }
-
-        if (r < 0)
-                unlink(p);
-
-        fclose(f);
-        free(p);
-
-        return r;
-}
-
 char *truncate_nl(char *s) {
         assert(s);
 
index fcb0d9a..88ef2f9 100644 (file)
@@ -177,15 +177,6 @@ char *split_quoted(const char *c, size_t *l, char **state);
 pid_t get_parent_of_pid(pid_t pid, pid_t *ppid);
 int get_starttime_of_pid(pid_t pid, unsigned long long *st);
 
-int write_one_line_file(const char *fn, const char *line);
-int write_one_line_file_atomic(const char *fn, const char *line);
-int read_one_line_file(const char *fn, char **line);
-int read_full_file(const char *fn, char **contents, size_t *size);
-
-int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
-int load_env_file(const char *fname, char ***l);
-int write_env_file(const char *fname, char **l);
-
 char *strappend(const char *s, const char *suffix);
 char *strnappend(const char *s, const char *suffix, size_t length);
 
index fc62c72..eed3210 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "util.h"
 #include "virt.h"
+#include "fileio.h"
 
 /* Returns a short identifier for the various VM implementations */
 int detect_vm(const char **id) {
index c074741..0464c89 100644 (file)
@@ -38,6 +38,7 @@
 #include "util.h"
 #include "utmp-wtmp.h"
 #include "mkdir.h"
+#include "fileio.h"
 
 union shutdown_buffer {
         struct sd_shutdown_command command;
index 218de3a..0707625 100644 (file)
@@ -27,6 +27,7 @@
 #include "util.h"
 #include "systemd/sd-id128.h"
 #include "systemd/sd-messages.h"
+#include "fileio.h"
 
 int main(int argc, char *argv[]) {
         const char *verb;
index a8cbb5a..2d43660 100644 (file)
@@ -34,6 +34,7 @@
 #include "hashmap.h"
 #include "path-util.h"
 #include "conf-files.h"
+#include "fileio.h"
 
 static char **arg_prefixes = NULL;
 
index 12e343e..df8da96 100644 (file)
@@ -66,6 +66,7 @@
 #include "logs-show.h"
 #include "path-util.h"
 #include "socket-util.h"
+#include "fileio.h"
 
 static const char *arg_type = NULL;
 static const char *arg_load_state = NULL;
index 041daab..8a71ee9 100644 (file)
@@ -34,6 +34,7 @@
 #include "hashmap.h"
 #include "load-fragment.h"
 #include "strv.h"
+#include "fileio.h"
 
 static void test_unit_file_get_set(void) {
         int r;
index b8c6b36..80c24eb 100644 (file)
@@ -35,6 +35,8 @@
 #include "hwclock.h"
 #include "conf-files.h"
 #include "path-util.h"
+#include "fileio-label.h"
+#include "label.h"
 
 #define NULL_ADJTIME_UTC "0.0 0 0\n0\nUTC\n"
 #define NULL_ADJTIME_LOCAL "0.0 0 0\n0\nLOCAL\n"
@@ -269,8 +271,8 @@ static int write_data_local_rtc(void) {
                         return 0;
                 }
         }
-
-        r = write_one_line_file_atomic("/etc/adjtime", w);
+        label_init("/etc");
+        r = write_one_line_file_atomic_label("/etc/adjtime", w);
         free(w);
 
         return r;
index 57674bf..fbacb45 100644 (file)
@@ -91,6 +91,7 @@
 #include <linux/pci_regs.h>
 
 #include "udev.h"
+#include "fileio.h"
 
 enum netname_type{
         NET_UNDEF,
index 088a89f..92911ef 100644 (file)
@@ -48,6 +48,7 @@
 #include "sd-daemon.h"
 #include "cgroup-util.h"
 #include "dev-setup.h"
+#include "fileio.h"
 
 static bool debug;
 
index 1208aeb..c1f662b 100644 (file)
@@ -39,6 +39,7 @@
 #include "log.h"
 #include "macro.h"
 #include "virt.h"
+#include "fileio.h"
 
 static bool is_vconsole(int fd) {
         unsigned char data[1];