return res; /* caller frees */
}
+
+/* The code below assumes each path returned can fit into a protocol
+ * chunk. If this turns out not to be true at some point in the
+ * future then we'll need to modify the code a bit to handle it.
+ */
+#if PATH_MAX > GUESTFS_MAX_CHUNK_SIZE
+#error "PATH_MAX > GUESTFS_MAX_CHUNK_SIZE"
+#endif
+
+/* Has one FileOut parameter. */
+int
+do_find0 (const char *dir)
+{
+ struct stat statbuf;
+ int r;
+ FILE *fp;
+ char *cmd;
+ char *sysrootdir;
+ size_t sysrootdirlen, len;
+ char str[GUESTFS_MAX_CHUNK_SIZE];
+
+ sysrootdir = sysroot_path (dir);
+ if (!sysrootdir) {
+ reply_with_perror ("malloc");
+ return -1;
+ }
+
+ r = stat (sysrootdir, &statbuf);
+ if (r == -1) {
+ reply_with_perror ("%s", dir);
+ free (sysrootdir);
+ return -1;
+ }
+ if (!S_ISDIR (statbuf.st_mode)) {
+ reply_with_error ("%s: not a directory", dir);
+ free (sysrootdir);
+ return -1;
+ }
+
+ sysrootdirlen = strlen (sysrootdir);
+
+ if (asprintf_nowarn (&cmd, "find %Q -print0", sysrootdir) == -1) {
+ reply_with_perror ("asprintf");
+ free (sysrootdir);
+ return -1;
+ }
+ free (sysrootdir);
+
+ if (verbose)
+ fprintf (stderr, "%s\n", cmd);
+
+ fp = popen (cmd, "r");
+ if (fp == NULL) {
+ reply_with_perror ("%s", cmd);
+ free (cmd);
+ return -1;
+ }
+ free (cmd);
+
+ /* Now we must send the reply message, before the file contents. After
+ * this there is no opportunity in the protocol to send any error
+ * message back. Instead we can only cancel the transfer.
+ */
+ reply (NULL, NULL);
+
+ while ((r = input_to_nul (fp, str, GUESTFS_MAX_CHUNK_SIZE)) > 0) {
+ if (verbose)
+ printf ("find0 string: %s\n", str);
+
+ len = strlen (str);
+ if (len <= sysrootdirlen)
+ continue;
+
+ /* Remove the directory part of the path before sending it. */
+ if (send_file_write (str + sysrootdirlen, r - sysrootdirlen) < 0) {
+ pclose (fp);
+ return -1;
+ }
+ }
+
+ if (ferror (fp)) {
+ perror (dir);
+ send_file_end (1); /* Cancel. */
+ pclose (fp);
+ return -1;
+ }
+
+ if (pclose (fp) != 0) {
+ perror (dir);
+ send_file_end (1); /* Cancel. */
+ return -1;
+ }
+
+ if (send_file_end (0)) /* Normal end of file. */
+ return -1;
+
+ return 0;
+}
+
rhbz503169c13.sh \
test-cancellation-download-librarycancels.sh \
test-cancellation-upload-daemoncancels.sh \
+ test-find0.sh \
test-noexec-stack.pl \
test-qemudie-killsub.sh \
test-qemudie-midcommand.sh \
--- /dev/null
+#!/bin/sh -
+# libguestfs
+# 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.
+
+# Test find0 call.
+
+set -e
+
+rm -f test.out
+
+../fish/guestfish <<'EOF'
+add-ro ../images/test.iso
+run
+mount-ro /dev/sda /
+find0 / test.out
+EOF
+
+n=$(tr '\0' '\n' < test.out | grep '^known-[1-5]' | wc -l)
+[ "$n" = 5 ] || {
+ echo find0: Invalid list of files
+ tr '\0' '\n' < test.out
+ exit 1
+}
+
+rm -f test.out
If C<directory> is not a directory, then this command returns
an error.
-The returned list is sorted.");
+The returned list is sorted.
+
+See also C<guestfs_find0>.");
("e2fsck_f", (RErr, [Device "device"]), 108, [],
[], (* lvresize tests this *)
See also C<guestfs_ping_daemon>.");
+ ("find0", (RErr, [Pathname "directory"; FileOut "files"]), 196, [],
+ [], (* There is a regression test for this. *)
+ "find all files and directories, returning NUL-separated list",
+ "\
+This command lists out all files and directories, recursively,
+starting at C<directory>, placing the resulting list in the
+external file called C<files>.
+
+This command works the same way as C<guestfs_find> with the
+following exceptions:
+
+=over 4
+
+=item *
+
+The resulting list is written to an external file.
+
+=item *
+
+Items (filenames) in the result are separated
+by C<\\0> characters. See L<find(1)> option I<-print0>.
+
+=item *
+
+This command is not limited in the number of names that it
+can return.
+
+=item *
+
+The result list is not sorted.
+
+=back");
+
]
let all_functions = non_daemon_functions @ daemon_functions