From 25395e3fa0b01a898b6e6ae456c8eef3c66849f1 Mon Sep 17 00:00:00 2001
From: Jonathan Schleifer <js@webkeks.org>
Date: Thu, 20 Mar 2014 14:52:58 +0100
Subject: Patches from tar-1.26


diff --git a/src/common.h b/src/common.h
index 42fd539..633ca19 100644
--- a/src/common.h
+++ b/src/common.h
@@ -192,6 +192,8 @@ GLOBAL enum old_files old_files_option;
 
 GLOBAL bool keep_directory_symlink_option;
 
+GLOBAL bool simulate_hardlinks_option;
+
 /* Specified file name for incremental list.  */
 GLOBAL const char *listed_incremental_option;
 /* Incremental dump level */
diff --git a/src/extract.c b/src/extract.c
index 9b6b7f9..26b027f 100644
--- a/src/extract.c
+++ b/src/extract.c
@@ -33,6 +33,8 @@ static bool we_are_root;	/* true if our effective uid == 0 */
 static mode_t newdir_umask;	/* umask when creating new directories */
 static mode_t current_umask;	/* current umask (which is set to 0 if -p) */
 
+static int extract_symlink (char *, int);
+
 #define ALL_MODE_BITS ((mode_t) ~ (mode_t) 0)
 
 #if ! HAVE_FCHMOD && ! defined fchmod
@@ -1268,6 +1270,38 @@ extract_link (char *file_name, int typeflag)
   char const *link_name;
   int rc;
 
+  if (simulate_hardlinks_option)
+  {
+	/* symlinks have to be normalized */
+	const char* f = file_name;
+	const char* l = current_stat_info.link_name;
+	int sep_pos = 0;
+	int p_count = 0;
+	char *link_name = (char*) xmalloc(strlen(current_stat_info.link_name) * 2);
+
+   for (; *f && *l; f++, l++)
+	{
+	  if (*f != *l)
+		  break;
+	  if (*f == DIRECTORY_SEPARATOR)
+		  sep_pos = f - file_name;
+	}
+
+	for (p_count = 0; *f; f++)
+	  if (*f == DIRECTORY_SEPARATOR)
+	    p_count++;
+
+	link_name[0] = '\0';
+	while (p_count--)
+	  strcat(link_name, "../");
+
+	strcat(link_name, &current_stat_info.link_name[sep_pos + 1]);
+	free(current_stat_info.link_name);
+	current_stat_info.link_name = link_name;
+
+	return extract_symlink(file_name, typeflag);
+  }
+
   link_name = current_stat_info.link_name;
 
   if (! absolute_names_option && contains_dot_dot (link_name))
@@ -1357,6 +1391,13 @@ extract_symlink (char *file_name, int typeflag)
 #else
   static int warned_once;
 
+  /* recursion is not welcomed here */
+  if (simulate_hardlinks_option && typeflag == LINKTYPE)
+  {
+	link_error (current_stat_info.link_name, file_name);
+	return -1;
+  }
+
   if (!warned_once)
     {
       warned_once = 1;
diff --git a/src/tar.c b/src/tar.c
index 4f5017d..2dd5200 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -457,6 +457,8 @@ static struct argp_option options[] = {
   {"check-device", CHECK_DEVICE_OPTION, NULL, 0,
    N_("check device numbers when creating incremental archives (default)"),
    GRID+1 },
+  {"replace-hardlinks", 'Q', 0, 0,
+   N_("replace hardlinks with corresponding symlink when extracting"), GRID+1 },
 #undef GRID
 
 #define GRID 30
@@ -1756,6 +1758,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
       set_archive_format (arg);
       break;
 
+    case 'Q':
+      simulate_hardlinks_option = true;
+      break;
+
     case INDEX_FILE_OPTION:
       index_file_name = arg;
       break;
@@ -2253,6 +2259,7 @@ decode_options (int argc, char **argv)
   unquote_option = true;
   tar_sparse_major = 1;
   tar_sparse_minor = 0;
+  simulate_hardlinks_option = false;
 
   owner_option = -1; owner_name_option = NULL;
   group_option = -1; group_name_option = NULL;
-- 
1.8.3.4


From 6f729d50ba6ca87c6cd33d87462884d90d4504c0 Mon Sep 17 00:00:00 2001
From: Adrien Destugues <pulkomandy@pulkomandy.tk>
Date: Fri, 28 Mar 2014 21:44:58 +0100
Subject: gcc2 build fix.


diff --git a/lib/wordsplit.h b/lib/wordsplit.h
index b48e3cd..d286ffb 100644
--- a/lib/wordsplit.h
+++ b/lib/wordsplit.h
@@ -33,10 +33,8 @@ struct wordsplit
   const char *ws_comment;
   const char *ws_escape;
   void (*ws_alloc_die) (struct wordsplit * wsp);
-  void (*ws_error) (const char *, ...)
-                   __attribute__ ((__format__ (__printf__, 1, 2)));
-  void (*ws_debug) (const char *, ...)
-                   __attribute__ ((__format__ (__printf__, 1, 2)));
+  void (*ws_error) (const char *, ...);
+  void (*ws_debug) (const char *, ...);
 
   const char **ws_env;
   const char *(*ws_getvar) (const char *, size_t, void *);
-- 
1.8.3.4

