>From ce33dd5c708feed330127e7964b73a14c6b0b913 Mon Sep 17 00:00:00 2001
From: Petr Jelinek <pjmodos@pjmodos.net>
Date: Sat, 13 Jun 2015 21:48:31 +0200
Subject: [PATCH 3/4] Set sysid via pg_resetxlog

---
 src/bin/pg_resetxlog/pg_resetxlog.c | 44 +++++++++++++++++++++++++++++++++++--
 src/include/c.h                     | 18 +++++++++++++++
 2 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/src/bin/pg_resetxlog/pg_resetxlog.c b/src/bin/pg_resetxlog/pg_resetxlog.c
index 2c061fa..f0f3658 100644
--- a/src/bin/pg_resetxlog/pg_resetxlog.c
+++ b/src/bin/pg_resetxlog/pg_resetxlog.c
@@ -61,6 +61,7 @@ static TransactionId set_newest_commit_ts = 0;
 static Oid	set_oid = 0;
 static MultiXactId set_mxid = 0;
 static MultiXactOffset set_mxoff = (MultiXactOffset) -1;
+static uint64 set_sysid = 0;
 static uint32 minXlogTli = 0;
 static XLogSegNo minXlogSegNo = 0;
 
@@ -99,7 +100,7 @@ main(int argc, char *argv[])
 	}
 
 
-	while ((c = getopt(argc, argv, "c:D:e:fl:m:no:O:x:")) != -1)
+	while ((c = getopt(argc, argv, "c:D:e:fl:m:no:O:s:x:")) != -1)
 	{
 		switch (c)
 		{
@@ -252,6 +253,25 @@ main(int argc, char *argv[])
 				XLogFromFileName(optarg, &minXlogTli, &minXlogSegNo);
 				break;
 
+			case 's':
+
+				set_sysid = pg_strtouint64(optarg, &endptr, 10);
+
+				/*
+				 * Validate input, we use strspn because some underlying
+				 * implementations of pg_strtouint64 accept negative numbers
+				 * and silently converts them to unsigned.
+				 */
+				if (set_sysid == 0 || errno != 0 ||
+					endptr == optarg || *endptr != '\0' ||
+					strspn(optarg, " 0123456789") != strlen(optarg))
+				{
+					fprintf(stderr, _("%s: invalid argument \"%s\" for option -s\n"), progname, optarg);
+					fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+					exit(1);
+				}
+				break;
+
 			default:
 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
 				exit(1);
@@ -388,6 +408,9 @@ main(int argc, char *argv[])
 	if (set_mxoff != -1)
 		ControlFile.checkPointCopy.nextMultiOffset = set_mxoff;
 
+	if (set_sysid != 0)
+		ControlFile.system_identifier = set_sysid;
+
 	if (minXlogTli > ControlFile.checkPointCopy.ThisTimeLineID)
 	{
 		ControlFile.checkPointCopy.ThisTimeLineID = minXlogTli;
@@ -443,7 +466,7 @@ main(int argc, char *argv[])
  * Print the values to be changed.
  */
 static void
-PrintNewControlValues()
+PrintNewControlValues(void)
 {
 	char		fname[MAXFNAMELEN];
 
@@ -501,6 +524,22 @@ PrintNewControlValues()
 		printf(_("newestCommitTs:                       %u\n"),
 			   ControlFile.checkPointCopy.newestCommitTs);
 	}
+
+	if (set_sysid != 0)
+	{
+		char            sysident_str[32];
+
+		/*
+		 * Format system_identifier separately to keep platform-dependent
+		 * format code out of the translatable message string.
+		 */
+		snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
+				 ControlFile.system_identifier);
+
+		printf(_("Database system identifier:           %s\n"),
+			   sysident_str);
+	}
+
 }
 
 
@@ -519,6 +558,7 @@ usage(void)
 	printf(_("  -n               no update, just show what would be done (for testing)\n"));
 	printf(_("  -o OID           set next OID\n"));
 	printf(_("  -O OFFSET        set next multitransaction offset\n"));
+	printf(_("  -s SYSID         set system identifier\n"));
 	printf(_("  -V, --version    output version information, then exit\n"));
 	printf(_("  -x XID           set next transaction ID\n"));
 	printf(_("  -?, --help       show this help, then exit\n"));
diff --git a/src/include/c.h b/src/include/c.h
index 92c5202..537b4d0 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -1095,6 +1095,24 @@ extern int	fdatasync(int fildes);
 #define HAVE_STRTOULL 1
 #endif
 
+/* Define portable pg_strtoint64() */
+#if defined(HAVE_LONG_INT_64)
+#define pg_strtoint64 strtol
+#elif defined(HAVE_STRTOULL)
+#define pg_strtoint64 strtoll
+#elif defined(WIN32)
+#define pg_strtoint64 _strtoi64
+#endif
+
+/* Define portable pg_strtouint64() */
+#if defined(HAVE_LONG_INT_64)
+#define pg_strtouint64 strtoul
+#elif defined(HAVE_STRTOULL)
+#define pg_strtouint64 strtoull
+#elif defined(WIN32)
+#define pg_strtouint64 _strtoui64
+#endif
+
 /*
  * We assume if we have these two functions, we have their friends too, and
  * can use the wide-character functions.
-- 
1.9.1

