8000 Sync our copy of the timezone library with IANA release tzcode2016h. · skyline2012/postgres@37ecf07 · GitHub
[go: up one dir, main page]

Skip to content

Commit 37ecf07

Browse files
committed
Sync our copy of the timezone library with IANA release tzcode2016h.
This absorbs a fix for a symlink-manipulation bug in zic that was introduced in 2016g. It probably isn't interesting for our use-case, but I'm not quite sure, so let's update while we're at it.
1 parent 9345bf0 commit 37ecf07

File tree

1 file changed

+56
-20
lines changed

1 file changed

+56
-20
lines changed

src/timezone/zic.c

Lines changed: 56 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,56 @@ namecheck(const char *name)
801801
return componentcheck(name, component, cp);
802802
}
803803

804+
/*
805+
* Create symlink contents suitable for symlinking FROM to TO, as a
806+
* freshly allocated string. FROM should be a relative file name, and
807+
* is relative to the global variable DIRECTORY. TO can be either
808+
* relative or absolute.
809+
*/
810+
#ifdef HAVE_SYMLINK
811+
static char *
812+
relname(char const * from, char const * to)
813+
{
814+
size_t i,
815+
taillen,
816+
dotdotetcsize;
817+
size_t dir_len = 0,
818+
dotdots = 0,
819+
linksize = SIZE_MAX;
820+
char const *f = from;
821+
char *result = NULL;
822+
823+
if (*to == '/')
824+
{
825+
/* Make F absolute too. */
826+
size_t len = strlen(directory);
827+
bool needslash = len && directory[len - 1] != '/';
828+
829+
linksize = len + needslash + strlen(from) + 1;
830+
f = result = emalloc(linksize);
831+
strcpy(result, directory);
832+
result[len] = '/';
833+
strcpy(result + len + needslash, from);
834+
}
835+
for (i = 0; f[i] && f[i] == to[i]; i++)
836+
if (f[i] == '/')
837+
dir_len = i + 1;
838+
for (; f[i]; i++)
839+
dotdots += f[i] == '/' && f[i - 1] != '/';
840+
taillen = i - dir_len;
841+
dotdotetcsize = 3 * dotdots + taillen + 1;
842+
if (dotdotetcsize <= linksize)
843+
{
844+
if (!result)
845+
result = emalloc(dotdotetcsize);
846+
for (i = 0; i < dotdots; i++)
847+
memcpy(result + 3 * i, "../", 3);
848+
memmove(result + 3 * dotdots, f + dir_len, taillen + 1);
849+
}
850+
return result;
851+
}
852+
#endif /* HAVE_SYMLINK */
853+
804854
static void
805855
dolink(char const * fromfield, char const * tofield, bool staysymlink)
806856
{
@@ -844,31 +894,17 @@ dolink(char const * fromfield, char const * tofield, bool staysymlink)
844894
if (link_errno != 0)
845895
{
846896
#ifdef HAVE_SYMLINK
847-
const char *s = fromfield;
848-
const char *t;
849-
char *p;
850-
size_t dotdots = 0;
851-
char *symlinkcontents;
852-
int symlink_errno;
897+
bool absolute = *fromfield == '/';
898+
char *linkalloc = absolute ? NULL : relname(fromfield, tofield);
899+
char const *contents = absolute ? fromfield : linkalloc;
900+
int symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
853901

854-
do
855-
t = s;
856-
while ((s = strchr(s, '/'))
857-
&& strncmp(fromfield, tofield, ++s - fromfield) == 0);
858-
859-
for (s = tofield + (t - fromfield); *s; s++)
860-
dotdots += *s == '/';
861-
symlinkcontents = emalloc(3 * dotdots + strlen(t) + 1);
862-
for (p = symlinkcontents; dotdots-- != 0; p += 3)
863-
memcpy(p, "../", 3);
864-
strcpy(p, t);
865-
symlink_errno = symlink(symlinkcontents, tofield) == 0 ? 0 : errno;
866902
if (symlink_errno == ENOENT && !todirs_made)
867903
{
868904
mkdirs(tofield, true);
869-
symlink_errno = symlink(symlinkcontents, tofield) == 0 ? 0 : errno;
905+
symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
870906
}
871-
free(symlinkcontents);
907+
free(linkalloc);
872908
if (symlink_errno == 0)
873909
{
874910
if (link_errno != ENOTSUP)

0 commit comments

Comments
 (0)
0