diff options
author | Richard Jones <rjones@trick.home.annexia.org> | 2009-05-19 12:05:33 +0100 |
---|---|---|
committer | Richard Jones <rjones@trick.home.annexia.org> | 2009-05-19 12:05:33 +0100 |
commit | d1df2f342489bbbba086cae2bb95971c8e404cad (patch) | |
tree | c1608bc9f0028f79856a51ee6038ef92ff558d0f /daemon | |
parent | 8b4819058243957c8fbbc92ef4fbbc0b46655380 (diff) | |
download | libguestfs-d1df2f342489bbbba086cae2bb95971c8e404cad.tar.gz libguestfs-d1df2f342489bbbba086cae2bb95971c8e404cad.tar.xz libguestfs-d1df2f342489bbbba086cae2bb95971c8e404cad.zip |
Added 'find' command.
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/Makefile.am | 1 | ||||
-rw-r--r-- | daemon/find.c | 129 |
2 files changed, 130 insertions, 0 deletions
diff --git a/daemon/Makefile.am b/daemon/Makefile.am index ac1f8c58..e0da08cc 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -34,6 +34,7 @@ guestfsd_SOURCES = \ dropcaches.c \ ext2.c \ file.c \ + find.c \ fsck.c \ grub.c \ guestfsd.c \ diff --git a/daemon/find.c b/daemon/find.c new file mode 100644 index 00000000..6a7e3e8a --- /dev/null +++ b/daemon/find.c @@ -0,0 +1,129 @@ +/* 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 <fcntl.h> +#include <sys/stat.h> + +#include "../src/guestfs_protocol.h" +#include "daemon.h" +#include "actions.h" + +static int +input_to_nul (FILE *fp, char *buf, int maxlen) +{ + int i = 0, c; + + while (i < maxlen) { + c = fgetc (fp); + if (c == EOF) + return 0; + buf[i++] = c; + if (c == '\0') + return i; + } + + reply_with_error ("input_to_nul: input string too long"); + return -1; +} + +char ** +do_find (const char *dir) +{ + struct stat statbuf; + int r, len, sysrootdirlen; + char *cmd; + FILE *fp; + char **res = NULL; + int size = 0, alloc = 0; + char sysrootdir[PATH_MAX]; + char str[PATH_MAX]; + + NEED_ROOT (NULL); + ABS_PATH (dir, NULL); + + snprintf (sysrootdir, sizeof sysrootdir, "/sysroot%s", dir); + + r = stat (sysrootdir, &statbuf); + if (r == -1) { + reply_with_perror ("%s", dir); + return NULL; + } + if (!S_ISDIR (statbuf.st_mode)) { + reply_with_error ("%s: not a directory", dir); + return NULL; + } + + sysrootdirlen = strlen (sysrootdir); + + /* Assemble the external find command. */ + len = 2 * sysrootdirlen + 32; + cmd = malloc (len); + if (!cmd) { + reply_with_perror ("malloc"); + return NULL; + } + + strcpy (cmd, "find "); + shell_quote (cmd+5, len-5, sysrootdir); + strcat (cmd, " -print0"); + + if (verbose) + printf ("%s\n", cmd); + + fp = popen (cmd, "r"); + if (fp == NULL) { + reply_with_perror ("%s", cmd); + free (cmd); + return NULL; + } + free (cmd); + + while ((r = input_to_nul (fp, str, PATH_MAX)) > 0) { + if (verbose) + printf ("find string: %s\n", str); + + len = strlen (str); + if (len <= sysrootdirlen) + continue; + + /* Remove the directory part of the path when adding it. */ + if (add_string (&res, &size, &alloc, str + sysrootdirlen) == -1) { + pclose (fp); + return NULL; + } + } + pclose (fp); + + if (r == -1) { + free_stringslen (res, size); + return NULL; + } + + if (add_string (&res, &size, &alloc, NULL) == -1) + return NULL; + + sort_strings (res, size-1); + + return res; /* caller frees */ +} |