>From 30280d2af2895ad455fcecc7fdf702ff612120b4 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Mon, 12 Jun 2017 11:06:38 -0700
Subject: [PROPOSED] Overcome FILENAME_MAX limit on Solaris
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Problem reported by Kees Dekker in:
http://mm.icann.org/pipermail/tz/2017-June/025116.html
* NEWS: Mention Solaris.
* localtime.c (struct file_analysis): Tag the struct.
(union local_storage): Make ���fullname��� the same size ���u���, as the
union���s bytes are typically wasted otherwise, and this can easily
cause loads by absolute file names to fail on Solaris.
(tzloadbody): Simplify by avoiding the need for a local var
to point to the file name.
---
 NEWS        |  4 ++--
 localtime.c | 17 ++++++++---------
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/NEWS b/NEWS
index aa33eb3..2c86e90 100644
--- a/NEWS
+++ b/NEWS
@@ -82,8 +82,8 @@ Unreleased, experimental changes
     if not defined, the code attempts to guess it from other macros.
 
     Several minor changes have been made to the code to make it a
-    bit easier to port to MS-Windows.  (Thanks to Kees Dekker for
-    reporting the problems.)
+    bit easier to port to MS-Windows and Solaris.  (Thanks to Kees
+    Dekker for reporting the problems.)
 
   Changes to documentation and commentary
 
diff --git a/localtime.c b/localtime.c
index b23fe43..cd4e80e 100644
--- a/localtime.c
+++ b/localtime.c
@@ -358,17 +358,17 @@ union input_buffer {
 
 /* Local storage needed for 'tzloadbody'.  */
 union local_storage {
-  /* The file name to be opened.  */
-  char fullname[FILENAME_MAX + 1];
-
   /* The results of analyzing the file's contents after it is opened.  */
-  struct {
+  struct file_analysis {
     /* The input buffer.  */
     union input_buffer u;
 
     /* A temporary state used for parsing a TZ string in the file.  */
     struct state st;
   } u;
+
+  /* The file name to be opened.  */
+  char fullname[sizeof (struct file_analysis)];
 };
 
 /* Load tz data from the file named NAME into *SP.  Read extended
@@ -383,7 +383,6 @@ tzloadbody(char const *name, struct state *sp, bool doextend,
 	register int			stored;
 	register ssize_t		nread;
 	register bool doaccess;
-	register char *fullname = lsp->fullname;
 	register union input_buffer *up = &lsp->u.u;
 	register int tzheadsize = sizeof (struct tzhead);
 
@@ -404,13 +403,13 @@ tzloadbody(char const *name, struct state *sp, bool doextend,
 		  return EINVAL;
 		if (sizeof lsp->fullname - 1 <= strlen(p) + strlen(name))
 		  return ENAMETOOLONG;
-		strcpy(fullname, p);
-		strcat(fullname, "/");
-		strcat(fullname, name);
+		strcpy(lsp->fullname, p);
+		strcat(lsp->fullname, "/");
+		strcat(lsp->fullname, name);
 		/* Set doaccess if '.' (as in "../") shows up in name.  */
 		if (strchr(name, '.'))
 			doaccess = true;
-		name = fullname;
+		name = lsp->fullname;
 	}
 	if (doaccess && access(name, R_OK) != 0)
 	  return errno;
-- 
2.9.4

