1413c3537b8730940d516af4823e83ac8df001edeRalf Habacker/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2413c3537b8730940d516af4823e83ac8df001edeRalf Habacker/* dbus-file-unix.c unix related file implementation (internal to D-Bus implementation) 3413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * 4413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * Copyright (C) 2002, 2003, 2006 Red Hat, Inc. 5413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * Copyright (C) 2003 CodeFactory AB 6413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * 7413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * Licensed under the Academic Free License version 2.1 8413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * 9413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * This program is free software; you can redistribute it and/or modify 10413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * it under the terms of the GNU General Public License as published by 11413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * the Free Software Foundation; either version 2 of the License, or 12413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * (at your option) any later version. 13413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * 14413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * This program is distributed in the hope that it will be useful, 15413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * but WITHOUT ANY WARRANTY; without even the implied warranty of 16413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * GNU General Public License for more details. 18413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * 19413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * You should have received a copy of the GNU General Public License 20413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * along with this program; if not, write to the Free Software 21413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * 23413c3537b8730940d516af4823e83ac8df001edeRalf Habacker */ 24413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 25413c3537b8730940d516af4823e83ac8df001edeRalf Habacker#include <config.h> 26235eebdb1618ecdd0f752c9bcd92c61d17752e0bColin Walters 27235eebdb1618ecdd0f752c9bcd92c61d17752e0bColin Walters#include "dbus-protocol.h" 28235eebdb1618ecdd0f752c9bcd92c61d17752e0bColin Walters#include "dbus-errors.h" 29413c3537b8730940d516af4823e83ac8df001edeRalf Habacker#include "dbus-file.h" 30235eebdb1618ecdd0f752c9bcd92c61d17752e0bColin Walters#include "dbus-internals.h" 31235eebdb1618ecdd0f752c9bcd92c61d17752e0bColin Walters#include "dbus-sysdeps.h" 32235eebdb1618ecdd0f752c9bcd92c61d17752e0bColin Walters#include "dbus-sysdeps-unix.h" 33235eebdb1618ecdd0f752c9bcd92c61d17752e0bColin Walters 34235eebdb1618ecdd0f752c9bcd92c61d17752e0bColin Walters#include <sys/stat.h> 35235eebdb1618ecdd0f752c9bcd92c61d17752e0bColin Walters#include <stdio.h> 36235eebdb1618ecdd0f752c9bcd92c61d17752e0bColin Walters#include <fcntl.h> 37235eebdb1618ecdd0f752c9bcd92c61d17752e0bColin Walters#include <unistd.h> 38235eebdb1618ecdd0f752c9bcd92c61d17752e0bColin Walters#include <errno.h> 39235eebdb1618ecdd0f752c9bcd92c61d17752e0bColin Walters 40235eebdb1618ecdd0f752c9bcd92c61d17752e0bColin Walters#ifndef O_BINARY 41235eebdb1618ecdd0f752c9bcd92c61d17752e0bColin Walters#define O_BINARY 0 42235eebdb1618ecdd0f752c9bcd92c61d17752e0bColin Walters#endif 43413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 44413c3537b8730940d516af4823e83ac8df001edeRalf Habacker/** 45413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * Appends the contents of the given file to the string, 46413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * returning error code. At the moment, won't open a file 47413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * more than a megabyte in size. 48413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * 49413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @param str the string to append to 50413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @param filename filename to load 51413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @param error place to set an error 52413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @returns #FALSE if error was set 53413c3537b8730940d516af4823e83ac8df001edeRalf Habacker */ 54413c3537b8730940d516af4823e83ac8df001edeRalf Habackerdbus_bool_t 55413c3537b8730940d516af4823e83ac8df001edeRalf Habacker_dbus_file_get_contents (DBusString *str, 56413c3537b8730940d516af4823e83ac8df001edeRalf Habacker const DBusString *filename, 57413c3537b8730940d516af4823e83ac8df001edeRalf Habacker DBusError *error) 58413c3537b8730940d516af4823e83ac8df001edeRalf Habacker{ 59413c3537b8730940d516af4823e83ac8df001edeRalf Habacker int fd; 60413c3537b8730940d516af4823e83ac8df001edeRalf Habacker struct stat sb; 61413c3537b8730940d516af4823e83ac8df001edeRalf Habacker int orig_len; 62413c3537b8730940d516af4823e83ac8df001edeRalf Habacker int total; 63413c3537b8730940d516af4823e83ac8df001edeRalf Habacker const char *filename_c; 64413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 65413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _DBUS_ASSERT_ERROR_IS_CLEAR (error); 66413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 67413c3537b8730940d516af4823e83ac8df001edeRalf Habacker filename_c = _dbus_string_get_const_data (filename); 68413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 69413c3537b8730940d516af4823e83ac8df001edeRalf Habacker /* O_BINARY useful on Cygwin */ 70413c3537b8730940d516af4823e83ac8df001edeRalf Habacker fd = open (filename_c, O_RDONLY | O_BINARY); 71413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (fd < 0) 72413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 73413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, _dbus_error_from_errno (errno), 74413c3537b8730940d516af4823e83ac8df001edeRalf Habacker "Failed to open \"%s\": %s", 75413c3537b8730940d516af4823e83ac8df001edeRalf Habacker filename_c, 76413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_strerror (errno)); 77413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return FALSE; 78413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 79413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 80413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_verbose ("file fd %d opened\n", fd); 81413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 82413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (fstat (fd, &sb) < 0) 83413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 84413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, _dbus_error_from_errno (errno), 85413c3537b8730940d516af4823e83ac8df001edeRalf Habacker "Failed to stat \"%s\": %s", 86413c3537b8730940d516af4823e83ac8df001edeRalf Habacker filename_c, 87413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_strerror (errno)); 88413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 89413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_verbose ("fstat() failed: %s", 90413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_strerror (errno)); 91413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 92413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_close (fd, NULL); 93413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 94413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return FALSE; 95413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 96413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 97413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (sb.st_size > _DBUS_ONE_MEGABYTE) 98413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 99413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, DBUS_ERROR_FAILED, 100413c3537b8730940d516af4823e83ac8df001edeRalf Habacker "File size %lu of \"%s\" is too large.", 101413c3537b8730940d516af4823e83ac8df001edeRalf Habacker (unsigned long) sb.st_size, filename_c); 102413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_close (fd, NULL); 103413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return FALSE; 104413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 105413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 106413c3537b8730940d516af4823e83ac8df001edeRalf Habacker total = 0; 107413c3537b8730940d516af4823e83ac8df001edeRalf Habacker orig_len = _dbus_string_get_length (str); 108413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (sb.st_size > 0 && S_ISREG (sb.st_mode)) 109413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 110413c3537b8730940d516af4823e83ac8df001edeRalf Habacker int bytes_read; 111413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 112413c3537b8730940d516af4823e83ac8df001edeRalf Habacker while (total < (int) sb.st_size) 113413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 114413c3537b8730940d516af4823e83ac8df001edeRalf Habacker bytes_read = _dbus_read (fd, str, 115413c3537b8730940d516af4823e83ac8df001edeRalf Habacker sb.st_size - total); 116413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (bytes_read <= 0) 117413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 118413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, _dbus_error_from_errno (errno), 119413c3537b8730940d516af4823e83ac8df001edeRalf Habacker "Error reading \"%s\": %s", 120413c3537b8730940d516af4823e83ac8df001edeRalf Habacker filename_c, 121413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_strerror (errno)); 122413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 123413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_verbose ("read() failed: %s", 124413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_strerror (errno)); 125413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 126413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_close (fd, NULL); 127413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_string_set_length (str, orig_len); 128413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return FALSE; 129413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 130413c3537b8730940d516af4823e83ac8df001edeRalf Habacker else 131413c3537b8730940d516af4823e83ac8df001edeRalf Habacker total += bytes_read; 132413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 133413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 134413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_close (fd, NULL); 135413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return TRUE; 136413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 137413c3537b8730940d516af4823e83ac8df001edeRalf Habacker else if (sb.st_size != 0) 138413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 139413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_verbose ("Can only open regular files at the moment.\n"); 140413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, DBUS_ERROR_FAILED, 141413c3537b8730940d516af4823e83ac8df001edeRalf Habacker "\"%s\" is not a regular file", 142413c3537b8730940d516af4823e83ac8df001edeRalf Habacker filename_c); 143413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_close (fd, NULL); 144413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return FALSE; 145413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 146413c3537b8730940d516af4823e83ac8df001edeRalf Habacker else 147413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 148413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_close (fd, NULL); 149413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return TRUE; 150413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 151413c3537b8730940d516af4823e83ac8df001edeRalf Habacker} 152413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 153413c3537b8730940d516af4823e83ac8df001edeRalf Habacker/** 154413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * Writes a string out to a file. If the file exists, 155413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * it will be atomically overwritten by the new data. 156413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * 157413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @param str the string to write out 158413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @param filename the file to save string to 15945d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters * @param world_readable If set, ensure the file is world readable 160413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @param error error to be filled in on failure 161413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @returns #FALSE on failure 162413c3537b8730940d516af4823e83ac8df001edeRalf Habacker */ 163413c3537b8730940d516af4823e83ac8df001edeRalf Habackerdbus_bool_t 164413c3537b8730940d516af4823e83ac8df001edeRalf Habacker_dbus_string_save_to_file (const DBusString *str, 165413c3537b8730940d516af4823e83ac8df001edeRalf Habacker const DBusString *filename, 16645d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters dbus_bool_t world_readable, 167413c3537b8730940d516af4823e83ac8df001edeRalf Habacker DBusError *error) 168413c3537b8730940d516af4823e83ac8df001edeRalf Habacker{ 169413c3537b8730940d516af4823e83ac8df001edeRalf Habacker int fd; 170413c3537b8730940d516af4823e83ac8df001edeRalf Habacker int bytes_to_write; 171413c3537b8730940d516af4823e83ac8df001edeRalf Habacker const char *filename_c; 172413c3537b8730940d516af4823e83ac8df001edeRalf Habacker DBusString tmp_filename; 173413c3537b8730940d516af4823e83ac8df001edeRalf Habacker const char *tmp_filename_c; 174413c3537b8730940d516af4823e83ac8df001edeRalf Habacker int total; 175413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_bool_t need_unlink; 176413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_bool_t retval; 177413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 178413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _DBUS_ASSERT_ERROR_IS_CLEAR (error); 179413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 180413c3537b8730940d516af4823e83ac8df001edeRalf Habacker fd = -1; 181413c3537b8730940d516af4823e83ac8df001edeRalf Habacker retval = FALSE; 182413c3537b8730940d516af4823e83ac8df001edeRalf Habacker need_unlink = FALSE; 183413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 184413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (!_dbus_string_init (&tmp_filename)) 185413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 186413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 187413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return FALSE; 188413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 189413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 190413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (!_dbus_string_copy (filename, 0, &tmp_filename, 0)) 191413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 192413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 193413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_string_free (&tmp_filename); 194413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return FALSE; 195413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 196413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 197413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (!_dbus_string_append (&tmp_filename, ".")) 198413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 199413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 200413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_string_free (&tmp_filename); 201413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return FALSE; 202413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 203413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 204413c3537b8730940d516af4823e83ac8df001edeRalf Habacker#define N_TMP_FILENAME_RANDOM_BYTES 8 205413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES)) 206413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 207413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 208413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_string_free (&tmp_filename); 209413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return FALSE; 210413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 211413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 212413c3537b8730940d516af4823e83ac8df001edeRalf Habacker filename_c = _dbus_string_get_const_data (filename); 213413c3537b8730940d516af4823e83ac8df001edeRalf Habacker tmp_filename_c = _dbus_string_get_const_data (&tmp_filename); 214413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 215413c3537b8730940d516af4823e83ac8df001edeRalf Habacker fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT, 21645d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters world_readable ? 0644 : 0600); 217413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (fd < 0) 218413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 219413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, _dbus_error_from_errno (errno), 220413c3537b8730940d516af4823e83ac8df001edeRalf Habacker "Could not create %s: %s", tmp_filename_c, 221413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_strerror (errno)); 222413c3537b8730940d516af4823e83ac8df001edeRalf Habacker goto out; 223413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 22445d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters if (world_readable) 22545d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters { 22645d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters /* Ensure the file is world readable even in the presence of 22745d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters * possibly restrictive umasks; 22845d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters * see http://lists.freedesktop.org/archives/dbus/2010-September/013367.html 22945d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters */ 23045d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters if (fchmod (fd, 0644) < 0) 23145d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters { 23245d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters dbus_set_error (error, _dbus_error_from_errno (errno), 23345d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters "Could not chmod %s: %s", tmp_filename_c, 23445d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters _dbus_strerror (errno)); 23545d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters goto out; 23645d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters } 23745d53565bc13678d6aa5edec1d4efb5bf8a64e0bColin Walters } 238413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 239413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_verbose ("tmp file fd %d opened\n", fd); 240413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 241413c3537b8730940d516af4823e83ac8df001edeRalf Habacker need_unlink = TRUE; 242413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 243413c3537b8730940d516af4823e83ac8df001edeRalf Habacker total = 0; 244413c3537b8730940d516af4823e83ac8df001edeRalf Habacker bytes_to_write = _dbus_string_get_length (str); 245413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 246413c3537b8730940d516af4823e83ac8df001edeRalf Habacker while (total < bytes_to_write) 247413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 248413c3537b8730940d516af4823e83ac8df001edeRalf Habacker int bytes_written; 249413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 250413c3537b8730940d516af4823e83ac8df001edeRalf Habacker bytes_written = _dbus_write (fd, str, total, 251413c3537b8730940d516af4823e83ac8df001edeRalf Habacker bytes_to_write - total); 252413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 253413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (bytes_written <= 0) 254413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 255413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, _dbus_error_from_errno (errno), 256413c3537b8730940d516af4823e83ac8df001edeRalf Habacker "Could not write to %s: %s", tmp_filename_c, 257413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_strerror (errno)); 258413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 259413c3537b8730940d516af4823e83ac8df001edeRalf Habacker goto out; 260413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 261413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 262413c3537b8730940d516af4823e83ac8df001edeRalf Habacker total += bytes_written; 263413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 264413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 265413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (fsync(fd)) 266413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 267413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, _dbus_error_from_errno (errno), 268413c3537b8730940d516af4823e83ac8df001edeRalf Habacker "Could not synchronize file %s: %s", 269413c3537b8730940d516af4823e83ac8df001edeRalf Habacker tmp_filename_c, _dbus_strerror (errno)); 270413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 271413c3537b8730940d516af4823e83ac8df001edeRalf Habacker goto out; 272413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 273413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 274413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (!_dbus_close (fd, NULL)) 275413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 276413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, _dbus_error_from_errno (errno), 277413c3537b8730940d516af4823e83ac8df001edeRalf Habacker "Could not close file %s: %s", 278413c3537b8730940d516af4823e83ac8df001edeRalf Habacker tmp_filename_c, _dbus_strerror (errno)); 279413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 280413c3537b8730940d516af4823e83ac8df001edeRalf Habacker goto out; 281413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 282413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 283413c3537b8730940d516af4823e83ac8df001edeRalf Habacker fd = -1; 284413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 285413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (rename (tmp_filename_c, filename_c) < 0) 286413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 287413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, _dbus_error_from_errno (errno), 288413c3537b8730940d516af4823e83ac8df001edeRalf Habacker "Could not rename %s to %s: %s", 289413c3537b8730940d516af4823e83ac8df001edeRalf Habacker tmp_filename_c, filename_c, 290413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_strerror (errno)); 291413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 292413c3537b8730940d516af4823e83ac8df001edeRalf Habacker goto out; 293413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 294413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 295413c3537b8730940d516af4823e83ac8df001edeRalf Habacker need_unlink = FALSE; 296413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 297413c3537b8730940d516af4823e83ac8df001edeRalf Habacker retval = TRUE; 298413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 299413c3537b8730940d516af4823e83ac8df001edeRalf Habacker out: 300413c3537b8730940d516af4823e83ac8df001edeRalf Habacker /* close first, then unlink, to prevent ".nfs34234235" garbage 301413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * files 302413c3537b8730940d516af4823e83ac8df001edeRalf Habacker */ 303413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 304413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (fd >= 0) 305413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_close (fd, NULL); 306413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 307413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (need_unlink && unlink (tmp_filename_c) < 0) 308413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_verbose ("Failed to unlink temp file %s: %s\n", 309413c3537b8730940d516af4823e83ac8df001edeRalf Habacker tmp_filename_c, _dbus_strerror (errno)); 310413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 311413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_string_free (&tmp_filename); 312413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 313413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (!retval) 314413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _DBUS_ASSERT_ERROR_IS_SET (error); 315413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 316413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return retval; 317413c3537b8730940d516af4823e83ac8df001edeRalf Habacker} 318413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 319413c3537b8730940d516af4823e83ac8df001edeRalf Habacker/** Makes the file readable by every user in the system. 320413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * 321413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @param filename the filename 322413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @param error error location 323413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @returns #TRUE if the file's permissions could be changed. 324413c3537b8730940d516af4823e83ac8df001edeRalf Habacker */ 325413c3537b8730940d516af4823e83ac8df001edeRalf Habackerdbus_bool_t 326413c3537b8730940d516af4823e83ac8df001edeRalf Habacker_dbus_make_file_world_readable(const DBusString *filename, 327413c3537b8730940d516af4823e83ac8df001edeRalf Habacker DBusError *error) 328413c3537b8730940d516af4823e83ac8df001edeRalf Habacker{ 329413c3537b8730940d516af4823e83ac8df001edeRalf Habacker const char *filename_c; 330413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 331413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _DBUS_ASSERT_ERROR_IS_CLEAR (error); 332413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 333413c3537b8730940d516af4823e83ac8df001edeRalf Habacker filename_c = _dbus_string_get_const_data (filename); 334413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (chmod (filename_c, 0644) == -1) 335413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 336413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, 337413c3537b8730940d516af4823e83ac8df001edeRalf Habacker DBUS_ERROR_FAILED, 338413c3537b8730940d516af4823e83ac8df001edeRalf Habacker "Could not change permissions of file %s: %s\n", 339413c3537b8730940d516af4823e83ac8df001edeRalf Habacker filename_c, 340413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_strerror (errno)); 341413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return FALSE; 342413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 343413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return TRUE; 344413c3537b8730940d516af4823e83ac8df001edeRalf Habacker} 345413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 346413c3537b8730940d516af4823e83ac8df001edeRalf Habacker/** Creates the given file, failing if the file already exists. 347413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * 348413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @param filename the filename 349413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @param error error location 350413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @returns #TRUE if we created the file and it didn't exist 351413c3537b8730940d516af4823e83ac8df001edeRalf Habacker */ 352413c3537b8730940d516af4823e83ac8df001edeRalf Habackerdbus_bool_t 353413c3537b8730940d516af4823e83ac8df001edeRalf Habacker_dbus_create_file_exclusively (const DBusString *filename, 354413c3537b8730940d516af4823e83ac8df001edeRalf Habacker DBusError *error) 355413c3537b8730940d516af4823e83ac8df001edeRalf Habacker{ 356413c3537b8730940d516af4823e83ac8df001edeRalf Habacker int fd; 357413c3537b8730940d516af4823e83ac8df001edeRalf Habacker const char *filename_c; 358413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 359413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _DBUS_ASSERT_ERROR_IS_CLEAR (error); 360413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 361413c3537b8730940d516af4823e83ac8df001edeRalf Habacker filename_c = _dbus_string_get_const_data (filename); 362413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 363413c3537b8730940d516af4823e83ac8df001edeRalf Habacker fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT, 364413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 0600); 365413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (fd < 0) 366413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 367413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, 368413c3537b8730940d516af4823e83ac8df001edeRalf Habacker DBUS_ERROR_FAILED, 369413c3537b8730940d516af4823e83ac8df001edeRalf Habacker "Could not create file %s: %s\n", 370413c3537b8730940d516af4823e83ac8df001edeRalf Habacker filename_c, 371413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_strerror (errno)); 372413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return FALSE; 373413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 374413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 375413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_verbose ("exclusive file fd %d opened\n", fd); 376413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 377413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (!_dbus_close (fd, NULL)) 378413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 379413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, 380413c3537b8730940d516af4823e83ac8df001edeRalf Habacker DBUS_ERROR_FAILED, 381413c3537b8730940d516af4823e83ac8df001edeRalf Habacker "Could not close file %s: %s\n", 382413c3537b8730940d516af4823e83ac8df001edeRalf Habacker filename_c, 383413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _dbus_strerror (errno)); 384413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return FALSE; 385413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 386413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 387413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return TRUE; 388413c3537b8730940d516af4823e83ac8df001edeRalf Habacker} 389413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 390413c3537b8730940d516af4823e83ac8df001edeRalf Habacker/** 391413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * Deletes the given file. 392413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * 393413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @param filename the filename 394413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @param error error location 395413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * 396413c3537b8730940d516af4823e83ac8df001edeRalf Habacker * @returns #TRUE if unlink() succeeded 397413c3537b8730940d516af4823e83ac8df001edeRalf Habacker */ 398413c3537b8730940d516af4823e83ac8df001edeRalf Habackerdbus_bool_t 399413c3537b8730940d516af4823e83ac8df001edeRalf Habacker_dbus_delete_file (const DBusString *filename, 400413c3537b8730940d516af4823e83ac8df001edeRalf Habacker DBusError *error) 401413c3537b8730940d516af4823e83ac8df001edeRalf Habacker{ 402413c3537b8730940d516af4823e83ac8df001edeRalf Habacker const char *filename_c; 403413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 404413c3537b8730940d516af4823e83ac8df001edeRalf Habacker _DBUS_ASSERT_ERROR_IS_CLEAR (error); 405413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 406413c3537b8730940d516af4823e83ac8df001edeRalf Habacker filename_c = _dbus_string_get_const_data (filename); 407413c3537b8730940d516af4823e83ac8df001edeRalf Habacker 408413c3537b8730940d516af4823e83ac8df001edeRalf Habacker if (unlink (filename_c) < 0) 409413c3537b8730940d516af4823e83ac8df001edeRalf Habacker { 410413c3537b8730940d516af4823e83ac8df001edeRalf Habacker dbus_set_error (error, DBUS_ERROR_FAILED, 411413c3537b8730940d516af4823e83ac8df001edeRalf Habacker "Failed to delete file %s: %s\n", 412413c3537b8730940d516af4823e83ac8df001edeRalf Habacker filename_c, _dbus_strerror (errno)); 413413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return FALSE; 414413c3537b8730940d516af4823e83ac8df001edeRalf Habacker } 415413c3537b8730940d516af4823e83ac8df001edeRalf Habacker else 416413c3537b8730940d516af4823e83ac8df001edeRalf Habacker return TRUE; 417413c3537b8730940d516af4823e83ac8df001edeRalf Habacker} 418