File tzcode-symlink.patch of Package timezone.2410

This patch is used on openSUSE 12.2 or newer. Nowadays,
/etc/localtime is by default a symbolic link to a zone
file in /usr/share/zoneinfo.

By default, zic tries the following approaches to create
/etc/localtime:

  1. Hard link
  2. Symbolic link
  3. File copy

This patch changes the logic slightly: keep using symbolic
links if /etc/localtime is already one. If it isn't, use
the default order as listed above.

Index: timezone-2015f/zic.c
===================================================================
--- timezone-2015f.orig/zic.c
+++ timezone-2015f/zic.c
@@ -105,7 +105,7 @@ static int	addtype(zic_t, char const *,
 static void	leapadd(zic_t, bool, int, int);
 static void	adjleap(void);
 static void	associate(void);
-static void	dolink(const char * fromfield, const char * tofield);
+static void	dolink(const char * fromfield, const char * tofield, int defaultsymlink);
 static char **	getfields(char * buf);
 static zic_t	gethms(const char * string, const char * errstring,
 		       bool);
@@ -633,7 +633,7 @@ _("%s: More than one -L option specified
 	*/
 	for (i = 0; i < nlinks; ++i) {
 		eat(links[i].l_filename, links[i].l_linenum);
-		dolink(links[i].l_from, links[i].l_to);
+		dolink(links[i].l_from, links[i].l_to, false);
 		if (noise)
 			for (j = 0; j < nlinks; ++j)
 				if (strcmp(links[i].l_to,
@@ -642,11 +642,11 @@ _("%s: More than one -L option specified
 	}
 	if (lcltime != NULL) {
 		eat(_("command line"), 1);
-		dolink(lcltime, TZDEFAULT);
+		dolink(lcltime, TZDEFAULT, true);
 	}
 	if (psxrules != NULL) {
 		eat(_("command line"), 1);
-		dolink(psxrules, TZDEFRULES);
+		dolink(psxrules, TZDEFRULES, false);
 	}
 	if (warnings && (ferror(stderr) || fclose(stderr) != 0))
 	  return EXIT_FAILURE;
@@ -739,14 +739,17 @@ relname(char const *dir, char const *bas
 }
 
 static void
-dolink(char const *fromfield, char const *tofield)
+dolink(char const *fromfield, char const *tofield, int defaultsymlink)
 {
+	struct stat st;
 	register char *	fromname;
 	register char *	toname;
 	register int fromisdir;
 
 	fromname = relname(directory, fromfield);
 	toname = relname(directory, tofield);
+	if (lstat(fromname, &st) == 0 && S_ISLNK(st.st_mode))
+		defaultsymlink = true;
 	/*
 	** We get to be careful here since
 	** there's a fair chance of root running us.
@@ -760,14 +763,14 @@ dolink(char const *fromfield, char const
 	}
 	if (itsdir(toname) <= 0)
 		remove(toname);
-	if (link(fromname, toname) != 0) {
+	if (defaultsymlink || link(fromname, toname) != 0) {
 		int	result;
 
 		if (! mkdirs(toname))
 			exit(EXIT_FAILURE);
-
-		result = link(fromname, toname);
-		if (result != 0) {
+		if (!defaultsymlink)
+			result = link(fromname, toname);
+		if ((defaultsymlink || (!defaultsymlink && result != 0))) {
 				const char *s = fromname;
 				const char *t;
 				char *p;
openSUSE Build Service is sponsored by