Add program to calculate the shortest relative path for symlinks
This commit is contained in:
parent
434f32ca8d
commit
411d83c41e
|
@ -124,13 +124,15 @@ tools_kmod_CFLAGS = $(AM_CFLAGS)
|
||||||
tools_kmod_LDADD = libkmod/libkmod-util.la \
|
tools_kmod_LDADD = libkmod/libkmod-util.la \
|
||||||
libkmod/libkmod.la
|
libkmod/libkmod.la
|
||||||
|
|
||||||
noinst_PROGRAMS = tools/kmod-nolib
|
noinst_PROGRAMS = tools/kmod-nolib scripts/shortest_relpath
|
||||||
tools_kmod_nolib_SOURCES = $(tools_kmod_SOURCES)
|
tools_kmod_nolib_SOURCES = $(tools_kmod_SOURCES)
|
||||||
tools_kmod_nolib_CPPFLAGS = $(tools_kmod_CPPFLAGS)
|
tools_kmod_nolib_CPPFLAGS = $(tools_kmod_CPPFLAGS)
|
||||||
tools_kmod_nolib_CFLAGS = $(tools_kmod_CFLAGS)
|
tools_kmod_nolib_CFLAGS = $(tools_kmod_CFLAGS)
|
||||||
tools_kmod_nolib_LDADD = libkmod/libkmod-util.la \
|
tools_kmod_nolib_LDADD = libkmod/libkmod-util.la \
|
||||||
libkmod/libkmod-private.la
|
libkmod/libkmod-private.la
|
||||||
|
|
||||||
|
scripts_shortest_relpath_SOURCES = scripts/shortest_relpath.c
|
||||||
|
|
||||||
${noinst_SCRIPTS}: tools/kmod-nolib
|
${noinst_SCRIPTS}: tools/kmod-nolib
|
||||||
$(AM_V_GEN) ($(RM) $@; \
|
$(AM_V_GEN) ($(RM) $@; \
|
||||||
$(LN_S) $(notdir $<) $@)
|
$(LN_S) $(notdir $<) $@)
|
||||||
|
|
|
@ -7,3 +7,4 @@ modinfo
|
||||||
depmod
|
depmod
|
||||||
kmod
|
kmod
|
||||||
kmod-nolib
|
kmod-nolib
|
||||||
|
shortest-relpath
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
static void usage(const char *progname)
|
||||||
|
{
|
||||||
|
printf("%s <path> <relative-to-path>\n", progname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* path must be absolute path, as the result of calling realpath()
|
||||||
|
*/
|
||||||
|
static void split_path(const char *path, char d[PATH_MAX], size_t *dlen,
|
||||||
|
char n[NAME_MAX], size_t *nlen)
|
||||||
|
{
|
||||||
|
size_t dirnamelen, namelen;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = strrchr(path, '/'); /* p is never NULL since path is abs */
|
||||||
|
dirnamelen = p - path;
|
||||||
|
if (dirnamelen > 0)
|
||||||
|
memcpy(d, path, dirnamelen);
|
||||||
|
d[dirnamelen] = '\0';
|
||||||
|
|
||||||
|
namelen = strlen(p + 1);
|
||||||
|
if (namelen > 0)
|
||||||
|
memcpy(n, p + 1, namelen + 1);
|
||||||
|
|
||||||
|
if (dlen)
|
||||||
|
*dlen = dirnamelen;
|
||||||
|
if (nlen)
|
||||||
|
*nlen = namelen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
size_t sympathlen, namelen, pathlen, i, j;
|
||||||
|
char name[NAME_MAX], path[PATH_MAX];
|
||||||
|
char sympath[PATH_MAX];
|
||||||
|
char buf[PATH_MAX];
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
usage(basename(argv[0]));
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = realpath(argv[1], buf);
|
||||||
|
if (p == NULL) {
|
||||||
|
fprintf(stderr, "could not get realpath of %s: %m\n", argv[1]);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
split_path(buf, path, &pathlen, name, &namelen);
|
||||||
|
|
||||||
|
p = realpath(argv[2], sympath);
|
||||||
|
if (p == NULL) {
|
||||||
|
fprintf(stderr, "could not get realpath of %s: %m\n", argv[2]);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
sympathlen = strlen(sympath);
|
||||||
|
|
||||||
|
for (i = 1; i < sympathlen && i < pathlen; i++) {
|
||||||
|
if (sympath[i] == path[i])
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < sympathlen) {
|
||||||
|
while (sympath[i - 1] != '/')
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = &path[i];
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
if (i < sympathlen) {
|
||||||
|
memcpy(buf + j, "../", 3);
|
||||||
|
j += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i < sympathlen; i++) {
|
||||||
|
if (sympath[i] != '/')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
memcpy(buf + j, "../", 3);
|
||||||
|
j += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p != path + pathlen) {
|
||||||
|
memcpy(buf + j, p, path + pathlen - p);
|
||||||
|
j += path + pathlen - p;;
|
||||||
|
buf[j++] = '/';
|
||||||
|
}
|
||||||
|
memcpy(buf + j, name, namelen + 1);
|
||||||
|
|
||||||
|
printf("%s\n", buf);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue