- "\"%s\" is not a regular file",
- filename_c);
- _dbus_close (fd, NULL);
- return FALSE;
- }
- else
- {
- _dbus_close (fd, NULL);
- return TRUE;
- }
-}
-
-/**
- * Writes a string out to a file. If the file exists,
- * it will be atomically overwritten by the new data.
- *
- * @param str the string to write out
- * @param filename the file to save string to
- * @param error error to be filled in on failure
- * @returns #FALSE on failure
- */
-dbus_bool_t
-_dbus_string_save_to_file (const DBusString *str,
- const DBusString *filename,
- DBusError *error)
-{
- int fd;
- int bytes_to_write;
- const char *filename_c;
- DBusString tmp_filename;
- const char *tmp_filename_c;
- int total;
- dbus_bool_t need_unlink;
- dbus_bool_t retval;
-
- _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
- fd = -1;
- retval = FALSE;
- need_unlink = FALSE;
-
- if (!_dbus_string_init (&tmp_filename))
- {
- dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- return FALSE;
- }
-
- if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
- {
- dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- _dbus_string_free (&tmp_filename);
- return FALSE;
- }
-
- if (!_dbus_string_append (&tmp_filename, "."))
- {
- dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- _dbus_string_free (&tmp_filename);
- return FALSE;
- }
-
-#define N_TMP_FILENAME_RANDOM_BYTES 8
- if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
- {
- dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- _dbus_string_free (&tmp_filename);
- return FALSE;
- }
-
- filename_c = _dbus_string_get_const_data (filename);
- tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
-
- fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
- 0600);
- if (fd < 0)
- {
- dbus_set_error (error, _dbus_error_from_errno (errno),
- "Could not create %s: %s", tmp_filename_c,
- _dbus_strerror (errno));
- goto out;
- }
-
- _dbus_verbose ("tmp file fd %d opened\n", fd);
-
- need_unlink = TRUE;
-
- total = 0;
- bytes_to_write = _dbus_string_get_length (str);
-
- while (total < bytes_to_write)
- {
- int bytes_written;
-
- bytes_written = _dbus_write (fd, str, total,
- bytes_to_write - total);
-
- if (bytes_written <= 0)
- {
- dbus_set_error (error, _dbus_error_from_errno (errno),
- "Could not write to %s: %s", tmp_filename_c,
- _dbus_strerror (errno));
-
- goto out;
- }
-
- total += bytes_written;
- }
-
- if (fsync(fd))
- {
- dbus_set_error (error, _dbus_error_from_errno (errno),
- "Could not synchronize file %s: %s",
- tmp_filename_c, _dbus_strerror (errno));
-
- goto out;
- }
-
- if (!_dbus_close (fd, NULL))
- {
- dbus_set_error (error, _dbus_error_from_errno (errno),
- "Could not close file %s: %s",
- tmp_filename_c, _dbus_strerror (errno));
-
- goto out;
- }
-
- fd = -1;
-
- if (rename (tmp_filename_c, filename_c) < 0)
- {
- dbus_set_error (error, _dbus_error_from_errno (errno),
- "Could not rename %s to %s: %s",
- tmp_filename_c, filename_c,
- _dbus_strerror (errno));
-
- goto out;
- }
-
- need_unlink = FALSE;
-
- retval = TRUE;
-
- out:
- /* close first, then unlink, to prevent ".nfs34234235" garbage
- * files
- */
-
- if (fd >= 0)
- _dbus_close (fd, NULL);
-
- if (need_unlink && unlink (tmp_filename_c) < 0)
- _dbus_verbose ("Failed to unlink temp file %s: %s\n",
- tmp_filename_c, _dbus_strerror (errno));
-
- _dbus_string_free (&tmp_filename);
-
- if (!retval)
- _DBUS_ASSERT_ERROR_IS_SET (error);
-
- return retval;
-}
-
-/** Makes the file readable by every user in the system.
- *
- * @param filename the filename
- * @param error error location
- * @returns #TRUE if the file's permissions could be changed.
- */
-dbus_bool_t
-_dbus_make_file_world_readable(const DBusString *filename,
- DBusError *error)
-{
- const char *filename_c;
-
- _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
- filename_c = _dbus_string_get_const_data (filename);
- if (chmod (filename_c, 0644) == -1)
- {
- dbus_set_error (error,
- DBUS_ERROR_FAILED,
- "Could not change permissions of file %s: %s\n",
- filename_c,
- _dbus_strerror (errno));
- return FALSE;
- }
- return TRUE;
-}
-
-/** Creates the given file, failing if the file already exists.
- *
- * @param filename the filename
- * @param error error location
- * @returns #TRUE if we created the file and it didn't exist
- */
-dbus_bool_t
-_dbus_create_file_exclusively (const DBusString *filename,
- DBusError *error)
-{
- int fd;
- const char *filename_c;
-
- _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
- filename_c = _dbus_string_get_const_data (filename);
-
- fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
- 0600);
- if (fd < 0)
- {
- dbus_set_error (error,
- DBUS_ERROR_FAILED,
- "Could not create file %s: %s\n",
- filename_c,
- _dbus_strerror (errno));
- return FALSE;
- }
-
- _dbus_verbose ("exclusive file fd %d opened\n", fd);
-
- if (!_dbus_close (fd, NULL))
- {
- dbus_set_error (error,
- DBUS_ERROR_FAILED,
- "Could not close file %s: %s\n",
- filename_c,
- _dbus_strerror (errno));
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * Deletes the given file.
- *
- * @param filename the filename
- * @param error error location
- *
- * @returns #TRUE if unlink() succeeded
- */
-dbus_bool_t
-_dbus_delete_file (const DBusString *filename,
- DBusError *error)
-{
- const char *filename_c;
-
- _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
- filename_c = _dbus_string_get_const_data (filename);
-
- if (unlink (filename_c) < 0)
- {
- dbus_set_error (error, DBUS_ERROR_FAILED,
- "Failed to delete file %s: %s\n",
- filename_c, _dbus_strerror (errno));
- return FALSE;
- }
- else
- return TRUE;
-}
-
-/**
- * Creates a directory; succeeds if the directory
- * is created or already existed.
- *
- * @param filename directory filename
- * @param error initialized error object
- * @returns #TRUE on success
- */
-dbus_bool_t
-_dbus_create_directory (const DBusString *filename,
- DBusError *error)
-{
- const char *filename_c;
-
- _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
- filename_c = _dbus_string_get_const_data (filename);
-
- if (mkdir (filename_c, 0700) < 0)
- {
- if (errno == EEXIST)
- return TRUE;
-
- dbus_set_error (error, DBUS_ERROR_FAILED,
- "Failed to create directory %s: %s\n",
- filename_c, _dbus_strerror (errno));