X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=daemon%2Flink.c;h=3766d8ca164d4e7774958ed771e9bf56ce61d819;hp=57e35384bc5165e232854bf6d057ac52d73db0af;hb=ba39ced8804765705f4c61a92db0fddb8d672c7d;hpb=afaff775c12f32b7912f194e2fcc8e76b8c82572 diff --git a/daemon/link.c b/daemon/link.c index 57e3538..3766d8c 100644 --- a/daemon/link.c +++ b/daemon/link.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -28,15 +29,12 @@ #include "actions.h" char * -do_readlink (char *path) +do_readlink (const char *path) { ssize_t r; char *ret; char link[PATH_MAX]; - NEED_ROOT (NULL); - ABS_PATH (path, NULL); - CHROOT_IN; r = readlink (path, link, sizeof link); CHROOT_OUT; @@ -54,6 +52,56 @@ do_readlink (char *path) return ret; /* caller frees */ } +char ** +do_readlinklist (const char *path, char *const *names) +{ + int fd_cwd; + size_t i; + ssize_t r; + char link[PATH_MAX]; + const char *str; + char **ret = NULL; + int size = 0, alloc = 0; + + CHROOT_IN; + fd_cwd = open (path, O_RDONLY | O_DIRECTORY); + CHROOT_OUT; + + if (fd_cwd == -1) { + reply_with_perror ("open: %s", path); + return NULL; + } + + for (i = 0; names[i] != NULL; ++i) { + r = readlinkat (fd_cwd, names[i], link, sizeof link); + if (r >= PATH_MAX) { + reply_with_perror ("readlinkat: returned link is too long"); + free_strings (ret); + close (fd_cwd); + return NULL; + } + /* Because of the way this function is intended to be used, + * we actually expect to see errors here, and they are not fatal. + */ + if (r >= 0) { + link[r] = '\0'; + str = link; + } else + str = ""; + if (add_string (&ret, &size, &alloc, str) == -1) { + close (fd_cwd); + return NULL; + } + } + + close (fd_cwd); + + if (add_string (&ret, &size, &alloc, NULL) == -1) + return NULL; + + return ret; +} + static int _link (const char *flag, int symbolic, const char *target, const char *linkname) { @@ -62,10 +110,6 @@ _link (const char *flag, int symbolic, const char *target, const char *linkname) char *buf_linkname; char *buf_target; - NEED_ROOT (-1); - ABS_PATH (linkname, -1); - /* but target does not need to be absolute */ - /* Prefix linkname with sysroot. */ buf_linkname = sysroot_path (linkname); if (!buf_linkname) { @@ -90,19 +134,19 @@ _link (const char *flag, int symbolic, const char *target, const char *linkname) if (flag) r = command (NULL, &err, - "ln", flag, "--", /* target could begin with '-' */ - buf_target ? : target, buf_linkname, NULL); + "ln", flag, "--", /* target could begin with '-' */ + buf_target ? : target, buf_linkname, NULL); else r = command (NULL, &err, - "ln", "--", - buf_target ? : target, buf_linkname, NULL); + "ln", "--", + buf_target ? : target, buf_linkname, NULL); free (buf_linkname); free (buf_target); if (r == -1) { reply_with_error ("ln%s%s: %s: %s: %s", - flag ? " " : "", - flag ? : "", - target, linkname, err); + flag ? " " : "", + flag ? : "", + target, linkname, err); free (err); return -1; } @@ -113,25 +157,25 @@ _link (const char *flag, int symbolic, const char *target, const char *linkname) } int -do_ln (char *target, char *linkname) +do_ln (const char *target, const char *linkname) { return _link (NULL, 0, target, linkname); } int -do_ln_f (char *target, char *linkname) +do_ln_f (const char *target, const char *linkname) { return _link ("-f", 0, target, linkname); } int -do_ln_s (char *target, char *linkname) +do_ln_s (const char *target, const char *linkname) { return _link ("-s", 1, target, linkname); } int -do_ln_sf (char *target, char *linkname) +do_ln_sf (const char *target, const char *linkname) { return _link ("-sf", 1, target, linkname); }