I wrote:
Running with this code on a Linux box, with a modification to force staysymlink true, I get a lot of symlinks that seem to be misdirected. For example the toplevel Cuba link looks like
lrwxrwxrwx. 1 postgres postgres 17 Nov 3 20:39 Cuba -> ../America/Havana
when it should be just America/Havana.
It looks to me like this is already broken in 2016h. I think it's a thinko in relname(): should not the number of dotdots added depend on the number of additional directory levels in the *target* name, not the *source* name? This seems to fix it for me: *** a/zic.c --- b/zic.c *************** relname(char const *from, char const *to *** 804,812 **** for (i = 0; f[i] && f[i] == to[i]; i++) if (f[i] == '/') dir_len = i + 1; ! for (; f[i]; i++) ! dotdots += f[i] == '/' && f[i - 1] != '/'; ! taillen = i - dir_len; dotdotetcsize = 3 * dotdots + taillen + 1; if (dotdotetcsize <= linksize) { if (!result) --- 804,812 ---- for (i = 0; f[i] && f[i] == to[i]; i++) if (f[i] == '/') dir_len = i + 1; ! for (; to[i]; i++) ! dotdots += to[i] == '/' && to[i - 1] != '/'; ! taillen = strlen(f + dir_len); dotdotetcsize = 3 * dotdots + taillen + 1; if (dotdotetcsize <= linksize) { if (!result) With that, all the symlinks seem to point somewhere valid. regards, tom lane