File jpilot-Backup-0.51-symlinkfix.diff of Package jpilot-Backup
Index: src/plugin.c
===================================================================
--- src/plugin.c.orig
+++ src/plugin.c
@@ -32,6 +32,7 @@
#include <dirent.h>
#include <errno.h>
#include <glib.h>
+#include <fcntl.h>
#include <pi-dlp.h>
#include <pi-file.h>
@@ -46,6 +47,7 @@ static const char RCSID[] = "$Id: plugin
/* Local static functions */
static void filename_make_legal(char *s);
+static int copy_file (const char *src_path, const char *dst_path);
static void purge_db(GDBM_FILE dbf, GHashTable *hashtable);
static gboolean rm_func(gpointer key, gpointer value, gpointer user_data);
@@ -287,8 +289,8 @@ int plugin_sync (int sd) {
if (info.modifyDate == mtime) {
jp_logf (JP_LOG_GUI, "Backup: %s is up to date, fetch skipped.\n", db_copy_name);
get_archive_file_name (last_arch, db_copy_name, temp_str, 255);
- if (link (temp_str, full_name)) {
- jp_logf (JP_LOG_WARN, "Backup: Unable to link file %s, will fetch.\n", temp_str);
+ if (link (temp_str, full_name) && copy_file (temp_str, full_name)) {
+ jp_logf (JP_LOG_WARN, "Backup: Unable to link or copy file %s, will fetch.\n", temp_str);
}
else {
/* update the file manifest */
@@ -462,3 +464,82 @@ static void filename_make_legal (char *s
}
}
+static int copy_file (const char *src_path, const char *dst_path) {
+ int source_desc;
+ int dest_desc;
+ int buf_size = 512;
+ off_t n_read_total = 0;
+ char buf [513];
+ struct stat src_sb;
+
+ if (stat (src_path, &src_sb))
+ return -1;
+
+ /* if (chmod(src_path, src_sb . st_mode | S_IRUSR))
+ return -1;
+ */
+
+ source_desc = open (src_path, O_RDONLY);
+ if (source_desc < 0)
+ return -1;
+
+ dest_desc = open (dst_path, O_WRONLY | O_CREAT, src_sb . st_mode);
+ if (dest_desc < 0) {
+ close (source_desc);
+ return -1;
+ }
+
+ for (;;) {
+ ssize_t n_read = read (source_desc, buf, buf_size);
+ if (n_read < 0) {
+#ifdef EINTR
+ if (errno == EINTR)
+ continue;
+#endif
+ close (dest_desc);
+ close (source_desc);
+ return -1;
+ }
+ if (n_read == 0)
+ break;
+
+ n_read_total += n_read;
+
+ size_t count = n_read;
+ size_t total = 0;
+ char *ptr = buf;
+ size_t n_rw;
+
+ while (count > 0)
+ {
+
+#ifdef EINTR
+# define IS_EINTR(x) ((x) == EINTR)
+#else
+# define IS_EINTR(x) 0
+#endif
+
+ do {
+ n_rw = write (dest_desc, ptr, count);
+ } while (n_rw < 0 && IS_EINTR (errno));
+
+ if (n_rw == (size_t) -1)
+ break;
+ if (n_rw == 0)
+ break;
+ total += n_rw;
+ ptr += n_rw;
+ count -= n_rw;
+ }
+
+ if (total != n_read) {
+ close (dest_desc);
+ close (source_desc);
+ return -1;
+ }
+ }
+
+ close (dest_desc);
+ close (source_desc);
+ return 0;
+}