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;
+}
openSUSE Build Service is sponsored by