#include <glib/gi18n-lib.h>
#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
#include <pwd.h>
#include <grp.h>
#include <mntent.h>
return dest;
}
+/* ---------------------------------------------------------------------------------------------------- */
+
+/* TODO: maybe move to GLib */
+static gboolean
+_g_file_set_contents_full (const gchar *filename,
+ const gchar *contents,
+ gssize contents_len,
+ gint mode_for_new_file,
+ GError **error)
+{
+ gboolean ret;
+ struct stat statbuf;
+ gint mode;
+ gchar *tmpl;
+ gint fd;
+ FILE *f;
+
+ ret = FALSE;
+ tmpl = NULL;
+
+ if (stat (filename, &statbuf) != 0)
+ {
+ if (errno == ENOENT)
+ {
+ mode = mode_for_new_file;
+ }
+ else
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "Error stat(2)'ing %s: %m",
+ filename);
+ goto out;
+ }
+ }
+ else
+ {
+ mode = statbuf.st_mode;
+ }
+
+ tmpl = g_strdup_printf ("%s.XXXXXX", filename);
+ fd = g_mkstemp_full (tmpl, O_RDWR, mode);
+ if (fd == -1)
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "Error creating temporary file: %m");
+ goto out;
+ }
+
+ f = fdopen (fd, "w");
+ if (f == NULL)
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "Error calling fdopen: %m");
+ g_unlink (tmpl);
+ goto out;
+ }
+
+ if (contents_len < 0 )
+ contents_len = strlen (contents);
+ if (fwrite (contents, 1, contents_len, f) != contents_len)
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "Error calling fwrite on temp file: %m");
+ fclose (f);
+ g_unlink (tmpl);
+ goto out;
+ }
+
+ if (fsync (fileno (f)) != 0)
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "Error calling fsync on temp file: %m");
+ fclose (f);
+ g_unlink (tmpl);
+ goto out;
+ }
+ fclose (f);
+
+ if (rename (tmpl, filename) != 0)
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "Error renaming temp file to final file: %m");
+ g_unlink (tmpl);
+ goto out;
+ }
+
+ ret = TRUE;
+
+ out:
+ g_free (tmpl);
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static gboolean
add_remove_fstab_entry (GVariant *remove,
GVariant *add,
g_free (escaped_opts);
}
- if (!g_file_set_contents ("/etc/fstab",
- str->str,
- -1,
- error) != 0)
+ if (!_g_file_set_contents_full ("/etc/fstab",
+ str->str,
+ -1,
+ 0644, /* mode to use if non-existant */
+ error) != 0)
goto out;
ret = TRUE;
goto out;
}
- /* TODO: XXX: would like to use mode 0600 here - umask(3) at start-up? */
- if (!g_file_set_contents (filename,
- add_passphrase_contents,
- -1,
- error))
+ if (!_g_file_set_contents_full (filename,
+ add_passphrase_contents,
+ -1,
+ 0600, /* mode to use if non-existant */
+ error))
{
g_free (filename);
goto out;
add_options);
}
- /* TODO: XXX: ugh, the mode is wrong.. umask(3) at start-up? */
- if (!g_file_set_contents ("/etc/crypttab",
- str->str,
- -1,
- error) != 0)
+ if (!_g_file_set_contents_full ("/etc/crypttab",
+ str->str,
+ -1,
+ 0600, /* mode to use if non-existant */
+ error) != 0)
goto out;
ret = TRUE;