Below find a proposed rewrite of the "symbolic link" section of zic.c; I hope this deals with the problems circulated recently on the time zone mailing list. --ado #if (HAVE_SYMLINK - 0) /* ** If hard link fails but from file exists, try a symbolic link. ** We want as relative a link as possible to maximize chances ** of correct behavior when the link is part of an ** exported directory. */ if (result != 0 && access(fromname, F_OK) == 0 && !itsdir(fromname)) { register char * t = toname; register char * f = fromname; register char * s; register int n; while ((s = strchr(t, '/')) != NULL && strncmp(t, f, (n = (s - t) + 1)) == 0) { t += n; f += n; } /* ** f t desired symlink value ** /a/b/c /d/e/f eliminated just above ** a/b/c d/e/f ../../a/b/c ** a/b d/e/f ../../a/b ** a/b/c d/e ../a/b/c ** /a/b/c d/e/f /a/b/c ** a/b/c /d/e/f hard to handle well */ if (*f == '/') s = ecpyalloc(f); else { s = NULL; if (*t != '/') { while (*t != '\0') if (*t++ == '/') s = ecatalloc(s, "../"); s = ecatalloc(s, f); } } if (s != NULL) { result = symlink(s, toname); ifree(s); if (result == 0) warning(_("hard link failed, symbolic link used")); } } #endif
Unfortunately that code won't work if toname is of the form FOO/BAR, where FOO is a symbolic link to some other place in the filesystem. The simplest fix is to remove the HAVE_SYMLINK code entirely, and to fail if the hard-link call fails. It's one less thing to configure in Makefile and in private.h. But if you want to support situations where hard links don't work, I think it would be simpler and more portable to make a copy instead of a link.
participants (2)
-
Olson, Arthur David (NCI) -
Paul Eggert