summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--src/db-artwork-writer.c14
-rw-r--r--src/itdb_itunesdb.c81
-rw-r--r--src/itdb_private.h3
4 files changed, 66 insertions, 41 deletions
diff --git a/ChangeLog b/ChangeLog
index ea9f10c..ae1365a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,13 @@
2007-11-15 Christophe Fergeau <teuf@gnome.org>
+
+ * src/itdb_private.h:
+ * src/itdb_itunesdb.c: add itdb_file_set_contents to workaround a
+ rename issue on sshfs (existing files on the FS can't be
+ atomatically erased during a rename). Use it in wcontents_write
+ * src/db-artwork-writer.c: use itdb_file_set_contents to write the
+ ArtworkDB
+
+2007-11-15 Christophe Fergeau <teuf@gnome.org>
* src/db-artwork-writer.c:
* src/db-parse-context.c:
diff --git a/src/db-artwork-writer.c b/src/db-artwork-writer.c
index 6de0c80..fd19d8a 100644
--- a/src/db-artwork-writer.c
+++ b/src/db-artwork-writer.c
@@ -34,6 +34,8 @@
#include "db-image-parser.h"
#include "itdb_endianness.h"
+#include <glib/gstdio.h>
+
#include <errno.h>
#include <fcntl.h>
#include <string.h>
@@ -65,13 +67,13 @@ typedef struct _iPodBuffer iPodBuffer;
static gboolean
ipod_gstring_flush (struct iPodSharedDataBuffer *shared, GError **error)
{
- gboolean result;
+ gboolean success;
- result = g_file_set_contents (shared->filename,
- shared->data->str, shared->data->len,
- error);
- if (!result) {
- return FALSE;
+ success = itdb_file_set_contents (shared->filename,
+ shared->data->str, shared->data->len,
+ error);
+ if (!success) {
+ return FALSE;
}
g_string_free (shared->data, TRUE);
g_free (shared->filename);
diff --git a/src/itdb_itunesdb.c b/src/itdb_itunesdb.c
index 325e90a..cb1b79e 100644
--- a/src/itdb_itunesdb.c
+++ b/src/itdb_itunesdb.c
@@ -4842,44 +4842,12 @@ static WContents *wcontents_new (const gchar *filename)
* cts->error accordingly. */
static gboolean wcontents_write (WContents *cts)
{
- int fd;
-
g_return_val_if_fail (cts, FALSE);
g_return_val_if_fail (cts->filename, FALSE);
- fd = creat (cts->filename, S_IRWXU|S_IRWXG|S_IRWXO);
-
- if (fd == -1)
- {
- cts->error = g_error_new (G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Opening of '%s' for writing failed (%s)."),
- cts->filename, g_strerror (errno));
- return FALSE;
- }
- if (cts->contents && cts->pos)
- {
- ssize_t written = write (fd, cts->contents, cts->pos);
- if (written == -1)
- {
- cts->error = g_error_new (G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Writing to '%s' failed (%s)."),
- cts->filename, g_strerror (errno));
- close (fd);
- return FALSE;
- }
- }
- fd = close (fd);
- if (fd == -1)
- {
- cts->error = g_error_new (G_FILE_ERROR,
- g_file_error_from_errno (errno),
- _("Writing to '%s' failed (%s)."),
- cts->filename, g_strerror (errno));
- return FALSE;
- }
- return TRUE;
+ cts->error = NULL;
+ return itdb_file_set_contents (cts->filename, cts->contents,
+ cts->pos, &cts->error);
}
@@ -6159,6 +6127,49 @@ gboolean itdb_cp (const gchar *from_file, const gchar *to_file,
}
+G_GNUC_INTERNAL gboolean
+itdb_file_set_contents (const char *filename,
+ const char *data, gssize len,
+ GError **error)
+{
+ gchar *backup;
+ gboolean success;
+
+ /* sshfs (which is used to access iPhones/iTouches) can't successfully
+ * rename a file if the destination file already exist.
+ * We first move away the existing file to workaround that limitation
+ * */
+ if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
+ gint result;
+ backup = g_strdup_printf ("%sXXXXXX", filename);
+ result = g_rename (filename, backup);
+ if (result != 0) {
+ g_free (backup);
+ return FALSE;
+ }
+ } else {
+ backup = NULL;
+ }
+
+ success = g_file_set_contents (filename, data, len, error);
+ if (!success) {
+ if (backup != NULL) {
+ g_rename (backup, filename);
+ g_free (backup);
+ }
+ return FALSE;
+ }
+
+ /* File saving was
+ * ok, clean up our
+ * mess */
+ if (backup != NULL) {
+ g_unlink (backup);
+ g_free (backup);
+ }
+
+ return TRUE;
+}
/**
diff --git a/src/itdb_private.h b/src/itdb_private.h
index 1ce36da..7e9e410 100644
--- a/src/itdb_private.h
+++ b/src/itdb_private.h
@@ -156,4 +156,7 @@ G_GNUC_INTERNAL guint64 device_time_time_t_to_mac (Itdb_Device *device,
time_t timet);
G_GNUC_INTERNAL gint itdb_musicdirs_number_by_mountpoint (const gchar *mountpoint);
G_GNUC_INTERNAL gboolean itdb_device_requires_checksum (Itdb_Device *device);
+G_GNUC_INTERNAL gboolean itdb_file_set_contents (const char *filename,
+ const char *data, gssize len,
+ GError **error);
#endif