Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
timezone.3251
timezone-2016g-absolute-TZDEFAULT.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File timezone-2016g-absolute-TZDEFAULT.patch of Package timezone.3251
From df9991a2186d4236ba1e97e6638fa53b578bc6d7 Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Thu, 6 Oct 2016 11:47:17 -0700 Subject: [PATCH] Do not assume TZDEFAULT is relative. Problem reported by Andreas Stieger in: http://mm.icann.org/pipermail/tz/2016-October/024280.html * NEWS: Document this. * zic.c (relname): New function. (dolink): Use it. --- zic.c | 65 ++++++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 21 deletions(-) --- Fixes: https://bugzilla.suse.com/show_bug.cgi?id=1003324 diff --git a/zic.c b/zic.c index 2505c11..eba223c 100644 --- a/zic.c +++ b/zic.c @@ -764,6 +764,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) { @@ -800,30 +838,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"), -- 2.10.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor