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 "guestfs_protocol.h"
33 do_rmdir (const char *path)
42 reply_with_perror ("%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 (STREQ (path, "/")) {
60 reply_with_error ("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 ("%s: %s", path, err);
86 do_mkdir (const char *path)
91 r = mkdir (path, 0777);
95 reply_with_perror ("%s", path);
103 do_mkdir_mode (const char *path, int mode)
108 reply_with_error ("%s: mode is negative", path);
113 r = mkdir (path, mode);
117 reply_with_perror ("%s", path);
125 * 0 if everything was OK,
126 * -1 for a general error (sets errno),
127 * -2 if an existing path element was not a directory.
130 recursive_mkdir (const char *path)
138 r = mkdir (path, 0777);
140 if (errno == EEXIST) { /* Something exists here, might not be a dir. */
141 r = lstat (path, &buf);
142 if (r == -1) return -1;
143 if (!S_ISDIR (buf.st_mode)) return -2;
144 return 0; /* OK - directory exists here already. */
147 if (!loop && errno == ENOENT) {
148 loop = 1; /* Stops it looping forever. */
150 /* If we're at the root, and we failed, just give up. */
151 if (path[0] == '/' && path[1] == '\0') return -1;
153 /* Try to make the parent directory first. */
154 ppath = strdup (path);
155 if (ppath == NULL) return -1;
157 p = strrchr (ppath, '/');
160 r = recursive_mkdir (ppath);
163 if (r != 0) return r;
166 } else /* Failed for some other reason, so return error. */
173 do_mkdir_p (const char *path)
178 r = recursive_mkdir (path);
182 reply_with_perror ("%s", path);
186 reply_with_error ("%s: a path element was not a directory", path);
194 do_mkdtemp (const char *template)
196 char *writable = strdup (template);
197 if (writable == NULL) {
198 reply_with_perror ("strdup");
203 char *r = mkdtemp (writable);
207 reply_with_perror ("%s", template);