MCPcopy Create free account
hub / github.com/eggert/tz / relname

Function relname

zic.c:1675–1714  ·  view source on GitHub ↗

Create symlink contents suitable for symlinking TARGET to LINKNAME, as a freshly allocated string. TARGET should be a relative file name, and is relative to the global variable DIRECTORY. LINKNAME can be either relative or absolute. Return a null pointer if the symlink contents was not computed because LINKNAME is absolute but DIRECTORY is not. */

Source from the content-addressed store, hash-verified

1673remove_temp(char const *temp)
1674{
1675 if (remove(temp) < 0)
1676 fprintf(stderr, _("%s: Can't remove temporary file %s%s%s: %s\n"),
1677 progname, diagdir(temp), diagslash(temp), temp, strerror(errno));
1678}
1679
1680/* Create symlink contents suitable for symlinking TARGET to LINKNAME, as a
1681 freshly allocated string. TARGET should be a relative file name, and
1682 is relative to the global variable DIRECTORY. LINKNAME can be either
1683 relative or absolute. Return a null pointer if the symlink contents
1684 was not computed because LINKNAME is absolute but DIRECTORY is not. */
1685static char *
1686relname(char const *target, char const *linkname)
1687{
1688 size_t i, taillen, dir_len = 0, dotdots = 0;
1689 ptrdiff_t dotdotetcsize, linksize = INDEX_MAX;
1690 char const *f = target;
1691 char *result = NULL;
1692 if (*linkname == '/') {
1693 /* Make F absolute too. */
1694 size_t len = strlen(directory);
1695 bool needs_slash = len && directory[len - 1] != '/';
1696 size_t lenslash = len + needs_slash;
1697 size_t targetsize = strlen(target) + 1;
1698 char *cp;
1699 if (*directory != '/')
1700 return NULL;
1701 linksize = size_sum(lenslash, targetsize);
1702 f = cp = result = xmalloc(linksize);
1703 cp = mempcpy(cp, directory, len);
1704 *cp = '/';
1705 memcpy(cp + needs_slash, target, targetsize);
1706 }
1707 for (i = 0; f[i] && f[i] == linkname[i]; i++)
1708 if (f[i] == '/')
1709 dir_len = i + 1;
1710 for (; linkname[i]; i++)
1711 dotdots += linkname[i] == '/' && linkname[i - 1] != '/';
1712 taillen = strlen(f + dir_len);
1713 dotdotetcsize = size_sum(size_product(dotdots, 3), taillen + 1);
1714 if (dotdotetcsize <= linksize) {
1715 char *cp;
1716 if (!result)
1717 result = xmalloc(dotdotetcsize);

Callers 1

dolinkFunction · 0.85

Calls 4

size_sumFunction · 0.85
mempcpyFunction · 0.85
size_productFunction · 0.85
xmallocFunction · 0.70

Tested by

no test coverage detected