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"
45 reply_with_perror ("rmdir: %s", path);
52 /* This implementation is quick and dirty, and allows people to try
53 * to remove parts of the initramfs (eg. "rm -r /..") but if people
54 * do stupid stuff, who are we to try to stop them?
65 if (strcmp (path, "/") == 0) {
66 reply_with_error ("rm -rf: cannot remove root directory");
70 len = strlen (path) + 9;
73 reply_with_perror ("malloc");
77 snprintf (buf, len, "/sysroot%s", path);
79 r = command (NULL, &err, "rm", "-rf", buf, NULL);
82 /* rm -rf is never supposed to fail. I/O errors perhaps? */
84 reply_with_error ("rm -rf: %s: %s", path, err);
103 r = mkdir (path, 0777);
107 reply_with_perror ("mkdir: %s", path);
115 recursive_mkdir (const char *path)
123 r = mkdir (path, 0777);
125 if (errno == EEXIST) { /* Something exists here, might not be a dir. */
126 r = lstat (path, &buf);
127 if (r == -1) return -1;
128 if (!S_ISDIR (buf.st_mode)) {
132 return 0; /* OK - directory exists here already. */
135 if (!loop && errno == ENOENT) {
136 loop = 1; /* Stops it looping forever. */
138 /* If we're at the root, and we failed, just give up. */
139 if (path[0] == '/' && path[1] == '\0') return -1;
141 /* Try to make the parent directory first. */
142 ppath = strdup (path);
143 if (ppath == NULL) return -1;
145 p = strrchr (ppath, '/');
148 r = recursive_mkdir (ppath);
151 if (r == -1) return -1;
154 } else /* Failed for some other reason, so return error. */
161 do_mkdir_p (char *path)
169 r = recursive_mkdir (path);
173 reply_with_perror ("mkdir -p: %s", path);
181 do_is_dir (char *path)
190 r = lstat (path, &buf);
194 if (errno != ENOENT && errno != ENOTDIR) {
195 reply_with_perror ("stat: %s", path);
199 return 0; /* Not a directory. */
202 return S_ISDIR (buf.st_mode);
206 do_mkdtemp (char *template)
211 ABS_PATH (template, NULL);
214 r = mkdtemp (template);
218 reply_with_perror ("mkdtemp: %s", template);
222 /* The caller will free template AND try to free the return value,
223 * so we must make a copy here.
226 r = strdup (template);
228 reply_with_perror ("strdup");