mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
New commands: rm rmdir rm-rf mkdir mkdir-p chmod chown
This commit is contained in:
@@ -23,6 +23,7 @@ guestfsd_SOURCES = \
|
||||
augeas.c \
|
||||
daemon.h \
|
||||
devsparts.c \
|
||||
dir.c \
|
||||
file.c \
|
||||
guestfsd.c \
|
||||
ls.c \
|
||||
|
||||
167
daemon/dir.c
Normal file
167
daemon/dir.c
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -64,6 +64,14 @@ and ret =
|
||||
| RVGList of string
|
||||
| RLVList of string
|
||||
and args = argt list (* Function parameters, guestfs handle is implicit. *)
|
||||
|
||||
(* Note in future we should allow a "variable args" parameter as
|
||||
* the final parameter, to allow commands like
|
||||
* chmod mode file [file(s)...]
|
||||
* This is not implemented yet, but many commands (such as chmod)
|
||||
* are currently defined with the argument order keeping this future
|
||||
* possibility in mind.
|
||||
*)
|
||||
and argt =
|
||||
| String of string (* const char *name, cannot be NULL *)
|
||||
| OptString of string (* const char *name, may be NULL *)
|
||||
@@ -483,6 +491,48 @@ details.");
|
||||
This is just a shortcut for listing C<guestfs_aug_match>
|
||||
C<path/*> and sorting the resulting nodes into alphabetical order.");
|
||||
|
||||
("rm", (RErr, [String "path"]), 29, [],
|
||||
"remove a file",
|
||||
"\
|
||||
Remove the single file C<path>.");
|
||||
|
||||
("rmdir", (RErr, [String "path"]), 30, [],
|
||||
"remove a directory",
|
||||
"\
|
||||
Remove the single directory C<path>.");
|
||||
|
||||
("rm_rf", (RErr, [String "path"]), 31, [],
|
||||
"remove a file or directory recursively",
|
||||
"\
|
||||
Remove the file or directory C<path>, recursively removing the
|
||||
contents if its a directory. This is like the C<rm -rf> shell
|
||||
command.");
|
||||
|
||||
("mkdir", (RErr, [String "path"]), 32, [],
|
||||
"create a directory",
|
||||
"\
|
||||
Create a directory named C<path>.");
|
||||
|
||||
("mkdir_p", (RErr, [String "path"]), 33, [],
|
||||
"create a directory and parents",
|
||||
"\
|
||||
Create a directory named C<path>, creating any parent directories
|
||||
as necessary. This is like the C<mkdir -p> shell command.");
|
||||
|
||||
("chmod", (RErr, [Int "mode"; String "path"]), 34, [],
|
||||
"change file mode",
|
||||
"\
|
||||
Change the mode (permissions) of C<path> to C<mode>. Only
|
||||
numeric modes are supported.");
|
||||
|
||||
("chown", (RErr, [Int "owner"; Int "group"; String "path"]), 35, [],
|
||||
"change file owner and group",
|
||||
"\
|
||||
Change the file owner to C<owner> and group to C<group>.
|
||||
|
||||
Only numeric uid and gid are supported. If you want to use
|
||||
names, you will need to locate and parse the password file
|
||||
yourself (Augeas support makes this relatively easy).");
|
||||
]
|
||||
|
||||
let all_functions = non_daemon_functions @ daemon_functions
|
||||
|
||||
Reference in New Issue
Block a user