1 /* libguestfs - the guestfsd daemon
2 * Copyright (C) 2009 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 do_readlink (const char *path)
39 r = readlink (path, link, sizeof link);
42 reply_with_perror ("readlink");
46 ret = strndup (link, r);
48 reply_with_perror ("strndup");
52 return ret; /* caller frees */
56 do_readlinklist (const char *path, char *const *names)
64 int size = 0, alloc = 0;
67 fd_cwd = open (path, O_RDONLY | O_DIRECTORY);
71 reply_with_perror ("open: %s", path);
75 for (i = 0; names[i] != NULL; ++i) {
76 r = readlinkat (fd_cwd, names[i], link, sizeof link);
78 reply_with_perror ("readlinkat: returned link is too long");
82 /* Because of the way this function is intended to be used,
83 * we actually expect to see errors here, and they are not fatal.
90 if (add_string (&ret, &size, &alloc, str) == -1) {
98 if (add_string (&ret, &size, &alloc, NULL) == -1)
105 _link (const char *flag, int symbolic, const char *target, const char *linkname)
112 /* Prefix linkname with sysroot. */
113 buf_linkname = sysroot_path (linkname);
115 reply_with_perror ("malloc");
119 /* Only prefix target if it's _not_ a symbolic link, and if
120 * the target is absolute. Note that the resulting link will
121 * always be "broken" from the p.o.v. of the appliance, ie:
122 * /a -> /b but the path as seen here is /sysroot/b
125 if (!symbolic && target[0] == '/') {
126 buf_target = sysroot_path (target);
128 reply_with_perror ("malloc");
135 r = command (NULL, &err,
136 "ln", flag, "--", /* target could begin with '-' */
137 buf_target ? : target, buf_linkname, NULL);
139 r = command (NULL, &err,
141 buf_target ? : target, buf_linkname, NULL);
145 reply_with_error ("ln%s%s: %s: %s: %s",
148 target, linkname, err);
159 do_ln (const char *target, const char *linkname)
161 return _link (NULL, 0, target, linkname);
165 do_ln_f (const char *target, const char *linkname)
167 return _link ("-f", 0, target, linkname);
171 do_ln_s (const char *target, const char *linkname)
173 return _link ("-s", 1, target, linkname);
177 do_ln_sf (const char *target, const char *linkname)
179 return _link ("-sf", 1, target, linkname);