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.
26 #include <sys/types.h>
28 #include "../src/guestfs_protocol.h"
33 do_rmdir (const char *path)
42 reply_with_perror ("rmdir: %s", path);
49 /* This implementation is quick and dirty, and allows people to try
50 * to remove parts of the initramfs (eg. "rm -r /..") but if people
51 * do stupid stuff, who are we to try to stop them?
54 do_rm_rf (const char *path)
59 if (strcmp (path, "/") == 0) {
60 reply_with_error ("rm -rf: cannot remove root directory");
64 buf = sysroot_path (path);
66 reply_with_perror ("malloc");
70 r = command (NULL, &err, "rm", "-rf", buf, NULL);
73 /* rm -rf is never supposed to fail. I/O errors perhaps? */
75 reply_with_error ("rm -rf: %s: %s", path, err);
86 do_mkdir (const char *path)
91 r = mkdir (path, 0777);
95 reply_with_perror ("mkdir: %s", path);
103 recursive_mkdir (const char *path)
111 r = mkdir (path, 0777);
113 if (errno == EEXIST) { /* Something exists here, might not be a dir. */
114 r = lstat (path, &buf);
115 if (r == -1) return -1;
116 if (!S_ISDIR (buf.st_mode)) {
120 return 0; /* OK - directory exists here already. */
123 if (!loop && errno == ENOENT) {
124 loop = 1; /* Stops it looping forever. */
126 /* If we're at the root, and we failed, just give up. */
127 if (path[0] == '/' && path[1] == '\0') return -1;
129 /* Try to make the parent directory first. */
130 ppath = strdup (path);
131 if (ppath == NULL) return -1;
133 p = strrchr (ppath, '/');
136 r = recursive_mkdir (ppath);
139 if (r == -1) return -1;
142 } else /* Failed for some other reason, so return error. */
149 do_mkdir_p (const char *path)
154 r = recursive_mkdir (path);
158 reply_with_perror ("mkdir -p: %s", path);
166 do_is_dir (const char *path)
172 r = lstat (path, &buf);
176 if (errno != ENOENT && errno != ENOTDIR) {
177 reply_with_perror ("stat: %s", path);
181 return 0; /* Not a directory. */
184 return S_ISDIR (buf.st_mode);
188 do_mkdtemp (char *template)
192 NEED_ROOT (return NULL);
193 ABS_PATH (template, return NULL);
196 r = mkdtemp (template);
200 reply_with_perror ("mkdtemp: %s", template);
204 /* The caller will free template AND try to free the return value,
205 * so we must make a copy here.
208 r = strdup (template);
210 reply_with_perror ("strdup");