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");
83 /* Because of the way this function is intended to be used,
84 * we actually expect to see errors here, and they are not fatal.
91 if (add_string (&ret, &size, &alloc, str) == -1) {
99 if (add_string (&ret, &size, &alloc, NULL) == -1)
106 _link (const char *flag, int symbolic, const char *target, const char *linkname)
113 /* Prefix linkname with sysroot. */
114 buf_linkname = sysroot_path (linkname);
116 reply_with_perror ("malloc");
120 /* Only prefix target if it's _not_ a symbolic link, and if
121 * the target is absolute. Note that the resulting link will
122 * always be "broken" from the p.o.v. of the appliance, ie:
123 * /a -> /b but the path as seen here is /sysroot/b
126 if (!symbolic && target[0] == '/') {
127 buf_target = sysroot_path (target);
129 reply_with_perror ("malloc");
136 r = command (NULL, &err,
137 "ln", flag, "--", /* target could begin with '-' */
138 buf_target ? : target, buf_linkname, NULL);
140 r = command (NULL, &err,
142 buf_target ? : target, buf_linkname, NULL);
146 reply_with_error ("ln%s%s: %s: %s: %s",
149 target, linkname, err);
160 do_ln (const char *target, const char *linkname)
162 return _link (NULL, 0, target, linkname);
166 do_ln_f (const char *target, const char *linkname)
168 return _link ("-f", 0, target, linkname);
172 do_ln_s (const char *target, const char *linkname)
174 return _link ("-s", 1, target, linkname);
178 do_ln_sf (const char *target, const char *linkname)
180 return _link ("-sf", 1, target, linkname);