diff options
author | Richard Jones <rjones@redhat.com> | 2009-04-10 12:52:49 +0100 |
---|---|---|
committer | Richard Jones <rjones@redhat.com> | 2009-04-10 12:55:04 +0100 |
commit | 44da812b424f5e10e268d47149d012d49edf858b (patch) | |
tree | 14e5e11712c46bcd57d5cb1130be507d96ab11c6 /daemon | |
parent | dd0432e2efc2e22ddbc9fb0a2746ee1c6a9c582f (diff) | |
download | libguestfs-44da812b424f5e10e268d47149d012d49edf858b.tar.gz libguestfs-44da812b424f5e10e268d47149d012d49edf858b.tar.xz libguestfs-44da812b424f5e10e268d47149d012d49edf858b.zip |
New commands: rm rmdir rm-rf mkdir mkdir-p chmod chown
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/Makefile.am | 1 | ||||
-rw-r--r-- | daemon/dir.c | 167 | ||||
-rw-r--r-- | daemon/file.c | 60 |
3 files changed, 228 insertions, 0 deletions
diff --git a/daemon/Makefile.am b/daemon/Makefile.am index c5ae1efc..400f1641 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -23,6 +23,7 @@ guestfsd_SOURCES = \ augeas.c \ daemon.h \ devsparts.c \ + dir.c \ file.c \ guestfsd.c \ ls.c \ diff --git a/daemon/dir.c b/daemon/dir.c new file mode 100644 index 00000000..7892682f --- /dev/null +++ b/daemon/dir.c @@ -0,0 +1,167 @@ +/* libguestfs - the guestfsd daemon + * Copyright (C) 2009 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include "../src/guestfs_protocol.h" +#include "daemon.h" +#include "actions.h" + +int +do_rmdir (const char *path) +{ + int r; + + NEED_ROOT (-1); + ABS_PATH (path, -1); + + CHROOT_IN; + r = rmdir (path); + CHROOT_OUT; + + if (r == -1) { + reply_with_perror ("rmdir: %s", path); + return -1; + } + + return 0; +} + +/* This implementation is quick and dirty, and allows people to try + * to remove parts of the initramfs (eg. "rm -r /..") but if people + * do stupid stuff, who are we to try to stop them? + */ +int +do_rm_rf (const char *path) +{ + int r, len; + char *buf, *err; + + NEED_ROOT (-1); + ABS_PATH (path, -1); + + if (strcmp (path, "/") == 0) { + reply_with_error ("rm -rf: cannot remove root directory"); + return -1; + } + + len = strlen (path) + 9; + buf = malloc (len); + if (buf == NULL) { + reply_with_perror ("malloc"); + return -1; + } + + snprintf (buf, len, "/sysroot%s", path); + + r = command (NULL, &err, "rm", "-rf", buf); + free (buf); + + /* rm -rf is never supposed to fail. I/O errors perhaps? */ + if (r == -1) { + reply_with_error ("rm -rf: %s: %s", path, err); + free (err); + return -1; + } + + free (err); + + return 0; +} + +int +do_mkdir (const char *path) +{ + int r; + + NEED_ROOT (-1); + ABS_PATH (path, -1); + + CHROOT_IN; + r = mkdir (path, 0777); + CHROOT_OUT; + + if (r == -1) { + reply_with_perror ("mkdir: %s", path); + return -1; + } + + return 0; +} + +static int +recursive_mkdir (const char *path) +{ + int loop = 0; + int r; + char *ppath, *p; + + again: + r = mkdir (path, 0777); + if (r == -1) { + if (!loop && errno == ENOENT) { + loop = 1; /* Stops it looping forever. */ + + /* If we're at the root, and we failed, just give up. */ + if (path[0] == '/' && path[1] == '\0') return -1; + + /* Try to make the parent directory first. */ + ppath = strdup (path); + if (ppath == NULL) return -1; + + p = strrchr (ppath, '/'); + if (p) *p = '\0'; + + r = recursive_mkdir (ppath); + free (ppath); + + if (r == -1) return -1; + + goto again; + } else /* Failed for some other reason, so return error. */ + return -1; + } + return 0; +} + +int +do_mkdir_p (const char *path) +{ + int r; + + NEED_ROOT (-1); + ABS_PATH (path, -1); + + CHROOT_IN; + r = recursive_mkdir (path); + CHROOT_OUT; + + if (r == -1) { + reply_with_perror ("mkdir -p: %s", path); + return -1; + } + + return 0; +} diff --git a/daemon/file.c b/daemon/file.c index ce449672..43c875cc 100644 --- a/daemon/file.c +++ b/daemon/file.c @@ -180,3 +180,63 @@ do_read_lines (const char *path) return r; } + +int +do_rm (const char *path) +{ + int r; + + NEED_ROOT (-1); + ABS_PATH (path, -1); + + CHROOT_IN; + r = unlink (path); + CHROOT_OUT; + + if (r == -1) { + reply_with_perror ("unlink: %s", path); + return -1; + } + + return 0; +} + +int +do_chmod (int mode, const char *path) +{ + int r; + + NEED_ROOT (-1); + ABS_PATH (path, -1); + + CHROOT_IN; + r = chmod (path, mode); + CHROOT_OUT; + + if (r == -1) { + reply_with_perror ("chmod: %s: 0%o", path, mode); + return -1; + } + + return 0; +} + +int +do_chown (int owner, int group, const char *path) +{ + int r; + + NEED_ROOT (-1); + ABS_PATH (path, -1); + + CHROOT_IN; + r = chown (path, owner, group); + CHROOT_OUT; + + if (r == -1) { + reply_with_perror ("chown: %s: %d.%d", path, owner, group); + return -1; + } + + return 0; +} |