Patch 0001 from upstream to tzcode2016g to restore full functionality
of zic -l
This commit is contained in:
parent
3e9c9a9b4c
commit
3a37e001c7
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: zic.c,v 1.63 2016/10/07 15:29:42 christos Exp $ */
|
||||
/* $NetBSD: zic.c,v 1.64 2016/10/07 19:47:16 kre Exp $ */
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 2006-07-17 by Arthur David Olson.
|
||||
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: zic.c,v 1.63 2016/10/07 15:29:42 christos Exp $");
|
||||
__RCSID("$NetBSD: zic.c,v 1.64 2016/10/07 19:47:16 kre Exp $");
|
||||
#endif /* !defined lint */
|
||||
|
||||
#include "private.h"
|
||||
|
@ -776,6 +776,44 @@ namecheck(const char *name)
|
|||
return componentcheck(name, component, cp);
|
||||
}
|
||||
|
||||
/* Create symlink contents suitable for symlinking FROM to TO, as a
|
||||
freshly allocated string. FROM should be a relative file name, and
|
||||
is relative to the global variable DIRECTORY. TO can be either
|
||||
relative or absolute. */
|
||||
static char *
|
||||
relname(char const *from, char const *to)
|
||||
{
|
||||
size_t i, taillen, dotdotetcsize;
|
||||
size_t dir_len = 0, dotdots = 0, linksize = SIZE_MAX;
|
||||
char const *f = from;
|
||||
char *result = NULL;
|
||||
if (*to == '/') {
|
||||
/* Make F absolute too. */
|
||||
size_t len = strlen(directory);
|
||||
bool needslash = len && directory[len - 1] != '/';
|
||||
linksize = len + needslash + strlen(from) + 1;
|
||||
f = result = emalloc(linksize);
|
||||
strcpy(result, directory);
|
||||
result[len] = '/';
|
||||
strcpy(result + len + needslash, from);
|
||||
}
|
||||
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)
|
||||
result = emalloc(dotdotetcsize);
|
||||
for (i = 0; i < dotdots; i++)
|
||||
memcpy(result + 3 * i, "../", 3);
|
||||
memmove(result + 3 * dotdots, f + dir_len, taillen + 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
dolink(char const *fromfield, char const *tofield, bool staysymlink)
|
||||
{
|
||||
|
@ -812,30 +850,15 @@ dolink(char const *fromfield, char const *tofield, bool staysymlink)
|
|||
link_errno = link(fromfield, tofield) == 0 ? 0 : errno;
|
||||
}
|
||||
if (link_errno != 0) {
|
||||
const char *s = fromfield;
|
||||
const char *t;
|
||||
char *p;
|
||||
size_t dotdots = 0;
|
||||
char *symlinkcontents;
|
||||
int symlink_errno;
|
||||
|
||||
do
|
||||
t = s;
|
||||
while ((s = strchr(s, '/'))
|
||||
&& strncmp(fromfield, tofield, ++s - fromfield) == 0);
|
||||
|
||||
for (s = tofield + (t - fromfield); *s; s++)
|
||||
dotdots += *s == '/';
|
||||
symlinkcontents = emalloc(3 * dotdots + strlen(t) + 1);
|
||||
for (p = symlinkcontents; dotdots-- != 0; p += 3)
|
||||
memcpy(p, "../", 3);
|
||||
strcpy(p, t);
|
||||
symlink_errno = symlink(symlinkcontents, tofield) == 0 ? 0 : errno;
|
||||
bool absolute = *fromfield == '/';
|
||||
char *linkalloc = absolute ? NULL : relname(fromfield, tofield);
|
||||
char const *contents = absolute ? fromfield : linkalloc;
|
||||
int symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
|
||||
if (symlink_errno == ENOENT && !todirs_made) {
|
||||
mkdirs(tofield, true);
|
||||
symlink_errno = symlink(symlinkcontents, tofield) == 0 ? 0 : errno;
|
||||
symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
|
||||
}
|
||||
free(symlinkcontents);
|
||||
free(linkalloc);
|
||||
if (symlink_errno == 0) {
|
||||
if (link_errno != ENOTSUP)
|
||||
warning(_("symbolic link used because hard link failed: %s"),
|
||||
|
|
Loading…
Reference in New Issue