diff --git a/contrib/pg_standby/pg_standby.c b/contrib/pg_standby/pg_standby.c
index d7fa2a8..279728d 100644
--- a/contrib/pg_standby/pg_standby.c
+++ b/contrib/pg_standby/pg_standby.c
@@ -33,9 +33,12 @@
 #include "pg_getopt.h"
 
 #include "access/xlog_internal.h"
+#include "access/xlogreader.h"
 
 const char *progname;
 
+uint32		XLogSegSize;
+
 /* Options and defaults */
 int			sleeptime = 5;		/* amount of time to sleep between file checks */
 int			waittime = -1;		/* how long we have been waiting, -1 no wait
@@ -100,6 +103,72 @@ int			nextWALFileType;
 
 struct stat stat_buf;
 
+static bool SetWALFileNameForCleanup(void);
+
+/* Set XLogSegSize from the WAL file specified by WALFilePath */
+static bool
+RetrieveXLogSegSize()
+{
+	bool		ret_val = false;
+	int			fd;
+	char	   *buf = (char *) malloc(XLOG_BLCKSZ);
+
+	/* Already set a valid XLogSegSize? */
+	if (IsValidXLogSegSize(XLogSegSize))
+		return true;
+
+	if ((fd = open(WALFilePath, O_RDWR, 0)) < 0)
+	{
+		fprintf(stderr, "%s: couldn't open WAL file \"%s\"\n",
+				progname, WALFilePath);
+		return false;
+	}
+	if (read(fd, buf, XLOG_BLCKSZ) == XLOG_BLCKSZ)
+	{
+		XLogPageHeader hdr = (XLogPageHeader) buf;
+		XLogLongPageHeader longhdr = (XLogLongPageHeader) hdr;
+
+		XLogSegSize = longhdr->xlp_seg_size;
+
+		if (IsValidXLogSegSize(XLogSegSize))
+		{
+			/* successfully retrieved WAL segment size */
+			ret_val = true;
+
+			/* check if clean up is necessary */
+			need_cleanup = SetWALFileNameForCleanup();
+			if (debug)
+			{
+				fprintf(stderr,
+						_("WAL segment size:     %d \n"), XLogSegSize);
+				fprintf(stderr, "Keep archive history: ");
+
+				if (need_cleanup)
+					fprintf(stderr, "%s and later\n",
+							exclusiveCleanupFileName);
+				else
+					fprintf(stderr, "no cleanup required\n");
+			}
+		}
+		else
+			fprintf(stderr,
+					"%s: WAL segment size must be a power of two between 1MB and 1GB, but the WAL file header specifies %d bytes\n",
+					progname, XLogSegSize);
+		close(fd);
+	}
+	else
+	{
+		if (errno != 0)
+			fprintf(stderr, "could not read file \"%s\": %s",
+				WALFilePath, strerror(errno));
+		else
+			fprintf(stderr, "not enough data in file \"%s\"", WALFilePath);
+	}
+
+	fflush(stderr);
+	return ret_val;
+}
+
 /* =====================================================================
  *
  *		  Customizable section
@@ -184,7 +253,9 @@ CustomizableNextWALFileReady(void)
 			nextWALFileType = XLOG_BACKUP_LABEL;
 			return true;
 		}
-		else if (stat_buf.st_size == XLOG_SEG_SIZE)
+		else if (!RetrieveXLogSegSize())
+			return false;
+		else if (stat_buf.st_size == XLogSegSize)
 		{
 #ifdef WIN32
 
@@ -204,7 +275,7 @@ CustomizableNextWALFileReady(void)
 		/*
 		 * If still too small, wait until it is the correct size
 		 */
-		if (stat_buf.st_size > XLOG_SEG_SIZE)
+		if (stat_buf.st_size > XLogSegSize)
 		{
 			if (debug)
 			{
@@ -218,8 +289,6 @@ CustomizableNextWALFileReady(void)
 	return false;
 }
 
-#define MaxSegmentsPerLogFile ( 0xFFFFFFFF / XLOG_SEG_SIZE )
-
 static void
 CustomizableCleanupPriorWALFiles(void)
 {
@@ -315,6 +384,7 @@ SetWALFileNameForCleanup(void)
 	uint32		log_diff = 0,
 				seg_diff = 0;
 	bool		cleanup = false;
+	int			MaxSegmentsPerLogFile = (0xFFFFFFFF / XLogSegSize);
 
 	if (restartWALFileName)
 	{
@@ -708,8 +778,6 @@ main(int argc, char **argv)
 
 	CustomizableInitialize();
 
-	need_cleanup = SetWALFileNameForCleanup();
-
 	if (debug)
 	{
 		fprintf(stderr, "Trigger file:         %s\n", triggerPath ? triggerPath : "<not set>");
@@ -721,11 +789,6 @@ main(int argc, char **argv)
 		fprintf(stderr, "Max wait interval:    %d %s\n",
 				maxwaittime, (maxwaittime > 0 ? "seconds" : "forever"));
 		fprintf(stderr, "Command for restore:  %s\n", restoreCommand);
-		fprintf(stderr, "Keep archive history: ");
-		if (need_cleanup)
-			fprintf(stderr, "%s and later\n", exclusiveCleanupFileName);
-		else
-			fprintf(stderr, "no cleanup required\n");
 		fflush(stderr);
 	}
 
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index ef0ec72..a13e836 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -110,6 +110,8 @@ int			wal_retrieve_retry_interval = 5000;
 bool		XLOG_DEBUG = false;
 #endif
 
+uint32		XLogSegSize = XLOG_SEG_SIZE;
+
 /*
  * Number of WAL insertion locks to use. A higher value allows more insertions
  * to happen concurrently, but adds some CPU overhead to flushing the WAL,
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index be754a5..a7920bc 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -2394,6 +2394,10 @@ main(int argc, char **argv)
 		exit(1);
 	}
 
+	/* determine remote server's xlog segment size */
+	if (!RetrieveXLogSegSize(conn))
+		disconnect_and_exit(1);
+
 	/* Create pg_wal symlink, if required */
 	if (strcmp(xlog_dir, "") != 0)
 	{
diff --git a/src/bin/pg_basebackup/pg_receivewal.c b/src/bin/pg_basebackup/pg_receivewal.c
index 144823d..0e713c8 100644
--- a/src/bin/pg_basebackup/pg_receivewal.c
+++ b/src/bin/pg_basebackup/pg_receivewal.c
@@ -254,7 +254,7 @@ FindStreamingStart(uint32 *tli)
 				disconnect_and_exit(1);
 			}
 
-			if (statbuf.st_size != XLOG_SEG_SIZE)
+			if (statbuf.st_size != XLogSegSize)
 			{
 				fprintf(stderr,
 						_("%s: segment file \"%s\" has incorrect size %d, skipping\n"),
@@ -295,7 +295,7 @@ FindStreamingStart(uint32 *tli)
 			bytes_out = (buf[3] << 24) | (buf[2] << 16) |
 				(buf[1] << 8) | buf[0];
 
-			if (bytes_out != XLOG_SEG_SIZE)
+			if (bytes_out != XLogSegSize)
 			{
 				fprintf(stderr,
 						_("%s: compressed segment file \"%s\" has incorrect uncompressed size %d, skipping\n"),
@@ -664,6 +664,10 @@ main(int argc, char **argv)
 	if (!RunIdentifySystem(conn, NULL, NULL, NULL, &db_name))
 		disconnect_and_exit(1);
 
+	/* determine remote server's xlog segment size */
+	if (!RetrieveXLogSegSize(conn))
+		disconnect_and_exit(1);
+
 	/*
 	 * Check that there is a database associated with connection, none should
 	 * be defined in this context.
diff --git a/src/bin/pg_basebackup/receivelog.c b/src/bin/pg_basebackup/receivelog.c
index 7b842a5..1bf234f 100644
--- a/src/bin/pg_basebackup/receivelog.c
+++ b/src/bin/pg_basebackup/receivelog.c
@@ -201,7 +201,7 @@ close_walfile(StreamCtl *stream, XLogRecPtr pos)
 
 	if (stream->partial_suffix)
 	{
-		if (currpos == XLOG_SEG_SIZE)
+		if (currpos == XLogSegSize)
 			r = stream->walmethod->close(walfile, CLOSE_NORMAL);
 		else
 		{
@@ -229,7 +229,7 @@ close_walfile(StreamCtl *stream, XLogRecPtr pos)
 	 * new node. This is in line with walreceiver.c always doing a
 	 * XLogArchiveForceDone() after a complete segment.
 	 */
-	if (currpos == XLOG_SEG_SIZE && stream->mark_done)
+	if (currpos == XLogSegSize && stream->mark_done)
 	{
 		/* writes error message if failed */
 		if (!mark_file_as_archived(stream, current_walfile_name))
@@ -1147,10 +1147,10 @@ ProcessXLogDataMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len,
 
 		/*
 		 * If crossing a WAL boundary, only write up until we reach
-		 * XLOG_SEG_SIZE.
+		 * XLogSegSize.
 		 */
-		if (xlogoff + bytes_left > XLOG_SEG_SIZE)
-			bytes_to_write = XLOG_SEG_SIZE - xlogoff;
+		if (xlogoff + bytes_left > XLogSegSize)
+			bytes_to_write = XLogSegSize - xlogoff;
 		else
 			bytes_to_write = bytes_left;
 
diff --git a/src/bin/pg_basebackup/streamutil.c b/src/bin/pg_basebackup/streamutil.c
index d7ba7e2..85213ee 100644
--- a/src/bin/pg_basebackup/streamutil.c
+++ b/src/bin/pg_basebackup/streamutil.c
@@ -24,12 +24,18 @@
 #include "receivelog.h"
 #include "streamutil.h"
 
+#include "access/xlog_internal.h"
 #include "pqexpbuffer.h"
 #include "common/fe_memutils.h"
 #include "datatype/timestamp.h"
 
 #define ERRCODE_DUPLICATE_OBJECT  "42710"
 
+uint32		XLogSegSize;
+
+/* SHOW command for replication connection was introduced in version 10 */
+#define MINIMUM_VERSION_FOR_SHOW_CMD 100000
+
 const char *progname;
 char	   *connection_string = NULL;
 char	   *dbhost = NULL;
@@ -231,6 +237,80 @@ GetConnection(void)
 }
 
 /*
+ * From version 10, explicitly set XLogSegSize using SHOW wal_segment_size
+ * since ControlFile is not accessible here.
+ */
+bool
+RetrieveXLogSegSize(PGconn *conn)
+{
+	PGresult   *res;
+	char	   *tmp_result;
+	char		xlog_unit[3];
+	int			xlog_val,
+				multiplier = 1;
+
+	/* check connection existence */
+	Assert(conn != NULL);
+
+	/* for previous versions set the default xlog seg size */
+	if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_SHOW_CMD)
+	{
+		XLogSegSize = XLOG_SEG_SIZE;
+		return true;
+	}
+
+	res = PQexec(conn, "SHOW wal_segment_size");
+	if (PQresultStatus(res) != PGRES_TUPLES_OK)
+	{
+		fprintf(stderr, _("%s: could not send replication command \"%s\": %s\n"),
+				progname, "SHOW wal_segment_size", PQerrorMessage(conn));
+
+		PQclear(res);
+		return false;
+	}
+	if (PQntuples(res) != 1 || PQnfields(res) < 1)
+	{
+		fprintf(stderr,
+		 _("%s: could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields\n"),
+				progname, PQntuples(res), PQnfields(res), 1, 1);
+
+		PQclear(res);
+		return false;
+	}
+
+	/* wal_segment_size ranges from 1MB to 1GB */
+	tmp_result = pg_strdup(PQgetvalue(res, 0, 0));
+
+	/* fetch xlog value and unit from the result */
+	if (sscanf(tmp_result, "%d%s", &xlog_val, xlog_unit) != 2)
+	{
+		fprintf(stderr, _("%s: WAL segment size could not be parsed\n"),
+				progname);
+		return false;
+	}
+
+	/* set the multiplier based on unit to convert XLogSegSize to bytes */
+	if (strcmp(xlog_unit, "MB") == 0)
+		multiplier = 1024 * 1024;
+	else if (strcmp(xlog_unit, "GB") == 0)
+		multiplier = 1024 * 1024 * 1024;
+
+	/* convert and set XLogSegSize */
+	XLogSegSize = xlog_val * multiplier;
+
+	if (!IsValidXLogSegSize(XLogSegSize))
+	{
+		fprintf(stderr,
+				_("%s: WAL segment size must be a power of two between 1MB and 1GB, but the remote server reported a value of %d bytes\n"),
+				progname, XLogSegSize);
+		return false;
+	}
+
+	PQclear(res);
+	return true;
+}
+
+/*
  * Run IDENTIFY_SYSTEM through a given connection and give back to caller
  * some result information if requested:
  * - System identifier
diff --git a/src/bin/pg_basebackup/streamutil.h b/src/bin/pg_basebackup/streamutil.h
index 6f68786..6fb85ba 100644
--- a/src/bin/pg_basebackup/streamutil.h
+++ b/src/bin/pg_basebackup/streamutil.h
@@ -39,6 +39,7 @@ extern bool RunIdentifySystem(PGconn *conn, char **sysid,
 				  TimeLineID *starttli,
 				  XLogRecPtr *startpos,
 				  char **db_name);
+extern bool RetrieveXLogSegSize(PGconn *conn);
 extern TimestampTz feGetCurrentTimestamp(void);
 extern void feTimestampDifference(TimestampTz start_time, TimestampTz stop_time,
 					  long *secs, int *microsecs);
diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c
index 2ea8931..288860a 100644
--- a/src/bin/pg_controldata/pg_controldata.c
+++ b/src/bin/pg_controldata/pg_controldata.c
@@ -26,6 +26,7 @@
 #include "common/controldata_utils.h"
 #include "pg_getopt.h"
 
+uint32		XLogSegSize;
 
 static void
 usage(const char *progname)
@@ -164,6 +165,14 @@ main(int argc, char *argv[])
 				 "Either the file is corrupt, or it has a different layout than this program\n"
 				 "is expecting.  The results below are untrustworthy.\n\n"));
 
+	/* set XLogSegSize */
+	XLogSegSize = ControlFile->xlog_seg_size;
+
+	if (!IsValidXLogSegSize(XLogSegSize))
+		fprintf(stderr,
+		 _("WARNING: WAL segment size specified, %d bytes, is not a power of two between 1MB and 1GB. The file is corrupt and the results below are untrustworthy."),
+				XLogSegSize);
+
 	/*
 	 * This slightly-chintzy coding will work as long as the control file
 	 * timestamps are within the range of time_t; that should be the case in
diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c
index d4dd1d4..28be212 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -56,6 +56,7 @@
 #include "storage/large_object.h"
 #include "pg_getopt.h"
 
+uint32 XLogSegSize;
 
 static ControlFileData ControlFile; /* pg_control values */
 static XLogSegNo newXlogSegNo;	/* new XLOG segment # */
@@ -94,6 +95,7 @@ main(int argc, char *argv[])
 	char	   *endptr;
 	char	   *endptr2;
 	char	   *DataDir = NULL;
+	char	   *log_fname = NULL;
 	int			fd;
 
 	set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_resetwal"));
@@ -265,7 +267,12 @@ main(int argc, char *argv[])
 					fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
 					exit(1);
 				}
-				XLogFromFileName(optarg, &minXlogTli, &minXlogSegNo);
+
+				/*
+				 * XLogFromFileName requires XLogSegSize which is not yet
+				 * set. Hence XLog details are set later on.
+				 */
+				log_fname = pg_strdup(optarg);
 				break;
 
 			default:
@@ -350,6 +357,9 @@ main(int argc, char *argv[])
 	if (!ReadControlFile())
 		GuessControlValues();
 
+	if (log_fname != NULL)
+		XLogFromFileName(log_fname, &minXlogTli, &minXlogSegNo);
+
 	/*
 	 * Also look at existing segment files to set up newXlogSegNo
 	 */
@@ -573,18 +583,26 @@ ReadControlFile(void)
 					offsetof(ControlFileData, crc));
 		FIN_CRC32C(crc);
 
-		if (EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc))
+		if (!EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc))
 		{
-			/* Valid data... */
-			memcpy(&ControlFile, buffer, sizeof(ControlFile));
-			return true;
+			/* We will use the data but treat it as guessed. */
+			fprintf(stderr, _("%s: pg_control exists but has invalid CRC; proceed with caution\n"),
+					progname);
+			guessed = true;
 		}
 
-		fprintf(stderr, _("%s: pg_control exists but has invalid CRC; proceed with caution\n"),
-				progname);
-		/* We will use the data anyway, but treat it as guessed. */
 		memcpy(&ControlFile, buffer, sizeof(ControlFile));
-		guessed = true;
+		XLogSegSize = ControlFile.xlog_seg_size;
+
+		/* return false if XLogSegSize is not valid */
+		if (!IsValidXLogSegSize(XLogSegSize))
+		{
+			fprintf(stderr,
+					_("%s: WAL segment size must be a power of two between 1MB and 1GB; ignoring control file specifying %d bytes\n"),
+					progname, XLogSegSize);
+			return false;
+		}
+
 		return true;
 	}
 
diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c
index 6c75b56..a1b2107 100644
--- a/src/bin/pg_rewind/pg_rewind.c
+++ b/src/bin/pg_rewind/pg_rewind.c
@@ -44,6 +44,7 @@ static ControlFileData ControlFile_target;
 static ControlFileData ControlFile_source;
 
 const char *progname;
+uint32		XLogSegSize;
 
 /* Configuration options */
 char	   *datadir_target = NULL;
@@ -631,6 +632,12 @@ digestControlFile(ControlFileData *ControlFile, char *src, size_t size)
 
 	memcpy(ControlFile, src, sizeof(ControlFileData));
 
+	/* set and validate XLogSegSize */
+	XLogSegSize = ControlFile->xlog_seg_size;
+
+	if (!IsValidXLogSegSize(XLogSegSize))
+		pg_fatal("WAL segment size must be a power of two between 1MB and 1GB, but the control file specifies %d bytes\n", XLogSegSize);
+
 	/* Additional checks on control file */
 	checkControlFile(ControlFile);
 }
diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index ed73ffe..36db1f6 100644
--- a/src/bin/pg_waldump/pg_waldump.c
+++ b/src/bin/pg_waldump/pg_waldump.c
@@ -22,10 +22,13 @@
 #include "common/fe_memutils.h"
 #include "getopt_long.h"
 #include "rmgrdesc.h"
+#include "sys/stat.h"
 
 
 static const char *progname;
 
+uint32		XLogSegSize;
+
 typedef struct XLogDumpPrivate
 {
 	TimeLineID	timeline;
@@ -144,77 +147,167 @@ split_path(const char *path, char **dir, char **fname)
 }
 
 /*
- * Try to find the file in several places:
- * if directory == NULL:
- *	 fname
- *	 XLOGDIR / fname
- *	 $PGDATA / XLOGDIR / fname
- * else
- *	 directory / fname
- *	 directory / XLOGDIR / fname
+ * Open the file in the valid target directory.
  *
  * return a read only fd
  */
 static int
-fuzzy_open_file(const char *directory, const char *fname)
+open_file_in_directory(const char *directory, const char *fname)
 {
 	int			fd = -1;
 	char		fpath[MAXPGPATH];
 
-	if (directory == NULL)
+	Assert(directory != NULL);
+
+	snprintf(fpath, MAXPGPATH, "%s/%s", directory, fname);
+	fd = open(fpath, O_RDONLY | PG_BINARY, 0);
+
+	if (fd < 0 && errno != ENOENT)
+		fatal_error("could not open file \"%s\": %s",
+					fname, strerror(errno));
+	return fd;
+}
+
+/*
+ * Try to find fname in the given directory. Returns true if it is found,
+ * false otherwise. If fname is NULL, search the complete directory for any
+ * file with a valid WAL file name.
+ */
+static bool
+search_directory(char *directory, char *fname)
+{
+	int			fd = -1;
+	DIR		   *xldir;
+
+	/* open file if valid filename is provided */
+	if (fname != NULL)
+		fd = open_file_in_directory(directory, fname);
+
+	/*
+	 * A valid file name is not passed so search the complete directory.  If
+	 * we find any file whose name is like a valid WAL file name then try to
+	 * open it.  If we can not open it then bail out.
+	 */
+	else if ((xldir = opendir(directory)) != NULL)
+	{
+		struct dirent *xlde;
+
+		while ((xlde = readdir(xldir)) != NULL)
+		{
+			if (IsXLogFileName(xlde->d_name))
+			{
+				fd = open_file_in_directory(directory, xlde->d_name);
+				fname = xlde->d_name;
+				break;
+			}
+		}
+
+		closedir(xldir);
+	}
+
+	/* set XLogSegSize if file is successfully opened */
+	if (fd >= 0)
+	{
+		char	   *buf = (char *) malloc(XLOG_BLCKSZ);
+
+		if (read(fd, buf, XLOG_BLCKSZ) == XLOG_BLCKSZ)
+		{
+			XLogPageHeader hdr = (XLogPageHeader) buf;
+			XLogLongPageHeader longhdr = (XLogLongPageHeader) hdr;
+
+			XLogSegSize = longhdr->xlp_seg_size;
+
+			if (!IsValidXLogSegSize(XLogSegSize))
+				fatal_error("WAL segment size must be a power of two between 1MB and 1GB, but the WAL file \"%s\" header specifies %d bytes",
+							fname, XLogSegSize);
+		}
+		else
+		{
+			if (errno != 0)
+				fatal_error("could not read file \"%s\": %s",
+					fname, strerror(errno));
+			else
+				fatal_error("not enough data in file \"%s\"", fname);
+		}
+		free(buf);
+		close(fd);
+		return true;
+	}
+
+	return false;
+}
+
+/*
+ * Identify the target directory and set XLogSegSize.
+ *
+ * Try to find the file in several places:
+ * if directory != NULL:
+ *	 directory /
+ *	 directory / XLOGDIR /
+ * else
+ *	 .
+ *	 XLOGDIR /
+ *	 $PGDATA / XLOGDIR /
+ *
+ * Set the valid target directory in private->inpath.
+ */
+static void
+identify_target_directory(XLogDumpPrivate *private, char *directory,
+						  char *fname)
+{
+	char		fpath[MAXPGPATH];
+
+	if (directory != NULL)
+	{
+		if (search_directory(directory, fname))
+		{
+			private->inpath = strdup(directory);
+			return;
+		}
+
+		/* directory / XLOGDIR */
+		snprintf(fpath, MAXPGPATH, "%s/%s", directory, XLOGDIR);
+		if (search_directory(fpath, fname))
+		{
+			private->inpath = strdup(fpath);
+			return;
+		}
+	}
+	else
 	{
 		const char *datadir;
 
-		/* fname */
-		fd = open(fname, O_RDONLY | PG_BINARY, 0);
-		if (fd < 0 && errno != ENOENT)
-			return -1;
-		else if (fd >= 0)
-			return fd;
-
-		/* XLOGDIR / fname */
-		snprintf(fpath, MAXPGPATH, "%s/%s",
-				 XLOGDIR, fname);
-		fd = open(fpath, O_RDONLY | PG_BINARY, 0);
-		if (fd < 0 && errno != ENOENT)
-			return -1;
-		else if (fd >= 0)
-			return fd;
+		/* current directory */
+		if (search_directory(".", fname))
+		{
+			private->inpath = strdup(".");
+			return;
+		}
+		/* XLOGDIR */
+		if (search_directory(XLOGDIR, fname))
+		{
+			private->inpath = strdup(XLOGDIR);
+			return;
+		}
 
 		datadir = getenv("PGDATA");
-		/* $PGDATA / XLOGDIR / fname */
+		/* $PGDATA / XLOGDIR */
 		if (datadir != NULL)
 		{
-			snprintf(fpath, MAXPGPATH, "%s/%s/%s",
-					 datadir, XLOGDIR, fname);
-			fd = open(fpath, O_RDONLY | PG_BINARY, 0);
-			if (fd < 0 && errno != ENOENT)
-				return -1;
-			else if (fd >= 0)
-				return fd;
+			snprintf(fpath, MAXPGPATH, "%s/%s", datadir, XLOGDIR);
+			if (search_directory(fpath, fname))
+			{
+				private->inpath = strdup(fpath);
+				return;
+			}
 		}
 	}
+
+	/* could not locate WAL file */
+	if (fname)
+		fatal_error("could not locate WAL file \"%s\"", fname);
 	else
-	{
-		/* directory / fname */
-		snprintf(fpath, MAXPGPATH, "%s/%s",
-				 directory, fname);
-		fd = open(fpath, O_RDONLY | PG_BINARY, 0);
-		if (fd < 0 && errno != ENOENT)
-			return -1;
-		else if (fd >= 0)
-			return fd;
-
-		/* directory / XLOGDIR / fname */
-		snprintf(fpath, MAXPGPATH, "%s/%s/%s",
-				 directory, XLOGDIR, fname);
-		fd = open(fpath, O_RDONLY | PG_BINARY, 0);
-		if (fd < 0 && errno != ENOENT)
-			return -1;
-		else if (fd >= 0)
-			return fd;
-	}
-	return -1;
+		fatal_error("could not find any WAL file");
 }
 
 /*
@@ -267,7 +360,7 @@ XLogDumpXLogRead(const char *directory, TimeLineID timeline_id,
 			 */
 			for (tries = 0; tries < 10; tries++)
 			{
-				sendFile = fuzzy_open_file(directory, fname);
+				sendFile = open_file_in_directory(directory, fname);
 				if (sendFile >= 0)
 					break;
 				if (errno == ENOENT)
@@ -935,7 +1028,8 @@ main(int argc, char **argv)
 							private.inpath, strerror(errno));
 		}
 
-		fd = fuzzy_open_file(private.inpath, fname);
+		identify_target_directory(&private, private.inpath, fname);
+		fd = open_file_in_directory(private.inpath, fname);
 		if (fd < 0)
 			fatal_error("could not open file \"%s\"", fname);
 		close(fd);
@@ -968,7 +1062,7 @@ main(int argc, char **argv)
 			/* ignore directory, already have that */
 			split_path(argv[optind + 1], &directory, &fname);
 
-			fd = fuzzy_open_file(private.inpath, fname);
+			fd = open_file_in_directory(private.inpath, fname);
 			if (fd < 0)
 				fatal_error("could not open file \"%s\"", fname);
 			close(fd);
@@ -1000,6 +1094,8 @@ main(int argc, char **argv)
 			goto bad_argument;
 		}
 	}
+	else
+		identify_target_directory(&private, private.inpath, NULL);
 
 	/* we don't know what to print */
 	if (XLogRecPtrIsInvalid(private.startptr))
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index 3fee2ee..9c0039c 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -89,11 +89,23 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
  * The XLOG is split into WAL segments (physical files) of the size indicated
  * by XLOG_SEG_SIZE.
  */
-#define XLogSegSize		((uint32) XLOG_SEG_SIZE)
-#define XLogSegmentsPerXLogId	(UINT64CONST(0x100000000) / XLOG_SEG_SIZE)
+
+extern uint32 XLogSegSize;
+
+/* XLogSegSize can range from 1MB to 1GB */
+#define XLogSegMinSize 1024 * 1024
+#define XLogSegMaxSize 1024 * 1024 * 1024
+
+/* check that the given size is a valid XLogSegSize */
+#define IsPowerOf2(x) (((x) & ((x)-1)) == 0)
+#define IsValidXLogSegSize(size) \
+	 (IsPowerOf2(size) && \
+	 (size >= XLogSegMinSize && size <= XLogSegMaxSize))
+
+#define XLogSegmentsPerXLogId	(UINT64CONST(0x100000000) / XLogSegSize)
 
 #define XLogSegNoOffsetToRecPtr(segno, offset, dest) \
-		(dest) = (segno) * XLOG_SEG_SIZE + (offset)
+		(dest) = (segno) * XLogSegSize + (offset)
 
 #define XLogSegmentOffset(xlogptr)	\
 	((xlogptr) & (XLogSegSize - 1))
