summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2012-08-02 14:05:54 +0100
committerRichard W.M. Jones <rjones@redhat.com>2012-08-02 14:05:54 +0100
commitb3d0cc0588845d3cad3fd67943d93e1bd87b1700 (patch)
tree79486747a419a63700f497499dd56f56ebcba8aa
parentd40b5028762eeaf9235165301bd76d468b7e251c (diff)
downloadlibguestfs-b3d0cc0588845d3cad3fd67943d93e1bd87b1700.tar.gz
libguestfs-b3d0cc0588845d3cad3fd67943d93e1bd87b1700.tar.xz
libguestfs-b3d0cc0588845d3cad3fd67943d93e1bd87b1700.zip
grep: Add optargs to grep API and deprecate fgrep etc.
This commit makes grep into an optargs API, with flags for extended, fixed, [case-]insensitive and compressed. At the same time it deprecates: egrep, fgrep, grepi, egrepi, fgrepi, zgrep, zegrep, zfgrep, zgrepi, zegrepi and zfgrepi.
-rw-r--r--daemon/grep.c71
-rw-r--r--examples/virt-dhcp-address.c4
-rw-r--r--generator/generator_actions.ml82
-rw-r--r--gobject/Makefile.inc2
-rw-r--r--po/POTFILES1
-rw-r--r--src/inspect-fs.c13
6 files changed, 146 insertions, 27 deletions
diff --git a/daemon/grep.c b/daemon/grep.c
index 285c48ec..d0fd42bc 100644
--- a/daemon/grep.c
+++ b/daemon/grep.c
@@ -28,13 +28,40 @@
#include "daemon.h"
#include "actions.h"
+#define MAX_ARGS 64
+
static char **
-grep (const char *prog, const char *flag, const char *regex, const char *path)
+grep (const char *regex, const char *path,
+ int extended, int fixed, int insensitive, int compressed)
{
+ const char *argv[MAX_ARGS];
+ size_t i = 0;
char *out, *err;
int fd, flags, r;
char **lines;
+ if (extended && fixed) {
+ reply_with_error ("can't use 'extended' and 'fixed' flags at the same time");
+ return NULL;
+ }
+
+ if (!compressed)
+ ADD_ARG (argv, i, "grep");
+ else
+ ADD_ARG (argv, i, "zgrep");
+
+ if (extended)
+ ADD_ARG (argv, i, "-E");
+
+ if (fixed)
+ ADD_ARG (argv, i, "-F");
+
+ if (insensitive)
+ ADD_ARG (argv, i, "-i");
+
+ ADD_ARG (argv, i, regex);
+ ADD_ARG (argv, i, NULL);
+
CHROOT_IN;
fd = open (path, O_RDONLY|O_CLOEXEC);
CHROOT_OUT;
@@ -48,9 +75,9 @@ grep (const char *prog, const char *flag, const char *regex, const char *path)
* suppress this error and return an empty list.
*/
flags = COMMAND_FLAG_CHROOT_COPY_FILE_TO_STDIN | fd;
- r = commandrf (&out, &err, flags, prog, flag, regex, NULL);
+ r = commandrvf (&out, &err, flags, argv);
if (r == -1 || r > 1) {
- reply_with_error ("%s %s %s: %s", prog, flag, regex, err);
+ reply_with_error ("%s: %s", regex, err);
free (out);
free (err);
return NULL;
@@ -65,75 +92,85 @@ grep (const char *prog, const char *flag, const char *regex, const char *path)
return lines;
}
+/* Takes optional arguments, consult optargs_bitmask. */
char **
-do_grep (const char *regex, const char *path)
+do_grep (const char *regex, const char *path,
+ int extended, int fixed, int insensitive, int compressed)
{
- /* The "--" is not really needed, but it helps when we don't need a flag. */
- return grep ("grep", "--", regex, path);
+ if (!(optargs_bitmask & GUESTFS_GREP_EXTENDED_BITMASK))
+ extended = 0;
+ if (!(optargs_bitmask & GUESTFS_GREP_FIXED_BITMASK))
+ fixed = 0;
+ if (!(optargs_bitmask & GUESTFS_GREP_INSENSITIVE_BITMASK))
+ insensitive = 0;
+ if (!(optargs_bitmask & GUESTFS_GREP_COMPRESSED_BITMASK))
+ compressed = 0;
+
+ return grep (regex, path, extended, fixed, insensitive, compressed);
}
char **
do_egrep (const char *regex, const char *path)
{
- return grep ("egrep", "--", regex, path);
+ return grep (regex, path, 1, 0, 0, 0);
}
char **
do_fgrep (const char *regex, const char *path)
{
- return grep ("fgrep", "--", regex, path);
+ return grep (regex, path, 0, 1, 0, 0);
}
char **
do_grepi (const char *regex, const char *path)
{
- return grep ("grep", "-i", regex, path);
+ return grep (regex, path, 0, 0, 1, 0);
}
char **
do_egrepi (const char *regex, const char *path)
{
- return grep ("egrep", "-i", regex, path);
+ return grep (regex, path, 1, 0, 1, 0);
}
char **
do_fgrepi (const char *regex, const char *path)
{
- return grep ("fgrep", "-i", regex, path);
+ return grep (regex, path, 0, 1, 1, 0);
}
char **
do_zgrep (const char *regex, const char *path)
{
- return grep ("zgrep", "--", regex, path);
+ return grep (regex, path, 0, 0, 0, 1);
}
char **
do_zegrep (const char *regex, const char *path)
{
- return grep ("zegrep", "--", regex, path);
+ return grep (regex, path, 1, 0, 0, 1);
}
char **
do_zfgrep (const char *regex, const char *path)
{
- return grep ("zfgrep", "--", regex, path);
+ return grep (regex, path, 0, 1, 0, 1);
}
char **
do_zgrepi (const char *regex, const char *path)
{
- return grep ("zgrep", "-i", regex, path);
+ return grep (regex, path, 0, 0, 1, 1);
}
char **
do_zegrepi (const char *regex, const char *path)
{
- return grep ("zegrep", "-i", regex, path);
+ return grep (regex, path, 1, 0, 1, 1);
}
char **
do_zfgrepi (const char *regex, const char *path)
{
- return grep ("zfgrep", "-i", regex, path);
+ return grep (regex, path, 0, 1, 1, 1);
}
diff --git a/examples/virt-dhcp-address.c b/examples/virt-dhcp-address.c
index 3534f0bc..c6f25c6c 100644
--- a/examples/virt-dhcp-address.c
+++ b/examples/virt-dhcp-address.c
@@ -169,7 +169,9 @@ print_dhcp_address_linux (guestfs_h *g, char *root, const char *logfile)
char **lines, *p;
size_t len;
- lines = guestfs_egrep (g, "dhclient.*: bound to ", logfile);
+ lines = guestfs_grep_opts (g, "dhclient.*: bound to ", logfile,
+ GUESTFS_GREP_OPTS_EXTENDED, 1,
+ -1);
if (lines == NULL)
exit (EXIT_FAILURE);
diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml
index 555157cb..b7283d71 100644
--- a/generator/generator_actions.ml
+++ b/generator/generator_actions.ml
@@ -5131,28 +5131,88 @@ in the total size of file that can be handled." };
{ defaults with
name = "grep";
- style = RStringList "lines", [String "regex"; Pathname "path"], [];
+ style = RStringList "lines", [String "regex"; Pathname "path"], [OBool "extended"; OBool "fixed"; OBool "insensitive"; OBool "compressed"];
proc_nr = Some 151;
- protocol_limit_warning = true;
+ protocol_limit_warning = true; once_had_no_optargs = true;
tests = [
InitISOFS, Always, TestOutputList (
- [["grep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"]);
+ [["grep"; "abc"; "/test-grep.txt"; ""; ""; ""; ""]],
+ ["abc"; "abc123"]);
InitISOFS, Always, TestOutputList (
- [["grep"; "nomatch"; "/test-grep.txt"]], []);
+ [["grep"; "nomatch"; "/test-grep.txt"; ""; ""; ""; ""]], []);
(* Test for RHBZ#579608, absolute symbolic links. *)
InitISOFS, Always, TestOutputList (
- [["grep"; "nomatch"; "/abssymlink"]], [])
+ [["grep"; "nomatch"; "/abssymlink"; ""; ""; ""; ""]], []);
+ InitISOFS, Always, TestOutputList (
+ [["grep"; "abc"; "/test-grep.txt"; "true"; ""; ""; ""]],
+ ["abc"; "abc123"]);
+ InitISOFS, Always, TestOutputList (
+ [["grep"; "abc"; "/test-grep.txt"; ""; "true"; ""; ""]],
+ ["abc"; "abc123"]);
+ InitISOFS, Always, TestOutputList (
+ [["grep"; "abc"; "/test-grep.txt"; ""; ""; "true"; ""]],
+ ["abc"; "abc123"; "ABC"]);
+ InitISOFS, Always, TestOutputList (
+ [["grep"; "abc"; "/test-grep.txt"; "true"; ""; "true"; ""]],
+ ["abc"; "abc123"; "ABC"]);
+ InitISOFS, Always, TestOutputList (
+ [["grep"; "abc"; "/test-grep.txt"; ""; "true"; "true"; ""]],
+ ["abc"; "abc123"; "ABC"]);
+ InitISOFS, Always, TestOutputList (
+ [["grep"; "abc"; "/test-grep.txt.gz"; ""; ""; ""; "true"]],
+ ["abc"; "abc123"]);
+ InitISOFS, Always, TestOutputList (
+ [["grep"; "abc"; "/test-grep.txt.gz"; "true"; ""; ""; "true"]],
+ ["abc"; "abc123"]);
+ InitISOFS, Always, TestOutputList (
+ [["grep"; "abc"; "/test-grep.txt.gz"; ""; "true"; ""; "true"]],
+ ["abc"; "abc123"]);
+ InitISOFS, Always, TestOutputList (
+ [["grep"; "abc"; "/test-grep.txt.gz"; ""; ""; "true"; "true"]],
+ ["abc"; "abc123"; "ABC"]);
+ InitISOFS, Always, TestOutputList (
+ [["grep"; "abc"; "/test-grep.txt.gz"; "true"; ""; "true"; "true"]],
+ ["abc"; "abc123"; "ABC"]);
+ InitISOFS, Always, TestOutputList (
+ [["grep"; "abc"; "/test-grep.txt.gz"; ""; "true"; "true"; "true"]],
+ ["abc"; "abc123"; "ABC"])
];
shortdesc = "return lines matching a pattern";
longdesc = "\
This calls the external C<grep> program and returns the
-matching lines." };
+matching lines.
+
+The optional flags are:
+
+=over 4
+
+=item C<extended>
+
+Use extended regular expressions.
+This is the same as using the I<-E> flag.
+
+=item C<fixed>
+
+Match fixed (don't use regular expressions).
+This is the same as using the I<-F> flag.
+
+=item C<insensitive>
+
+Match case-insensitive. This is the same as using the I<-i> flag.
+
+=item C<compressed>
+
+Use C<zgrep> instead of C<grep>. This allows the input to be
+compress- or gzip-compressed.
+
+=back" };
{ defaults with
name = "egrep";
style = RStringList "lines", [String "regex"; Pathname "path"], [];
proc_nr = Some 152;
protocol_limit_warning = true;
+ deprecated_by = Some "grep";
tests = [
InitISOFS, Always, TestOutputList (
[["egrep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"])
@@ -5167,6 +5227,7 @@ matching lines." };
style = RStringList "lines", [String "pattern"; Pathname "path"], [];
proc_nr = Some 153;
protocol_limit_warning = true;
+ deprecated_by = Some "grep";
tests = [
InitISOFS, Always, TestOutputList (
[["fgrep"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"])
@@ -5181,6 +5242,7 @@ matching lines." };
style = RStringList "lines", [String "regex"; Pathname "path"], [];
proc_nr = Some 154;
protocol_limit_warning = true;
+ deprecated_by = Some "grep";
tests = [
InitISOFS, Always, TestOutputList (
[["grepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])
@@ -5195,6 +5257,7 @@ matching lines." };
style = RStringList "lines", [String "regex"; Pathname "path"], [];
proc_nr = Some 155;
protocol_limit_warning = true;
+ deprecated_by = Some "grep";
tests = [
InitISOFS, Always, TestOutputList (
[["egrepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])
@@ -5209,6 +5272,7 @@ matching lines." };
style = RStringList "lines", [String "pattern"; Pathname "path"], [];
proc_nr = Some 156;
protocol_limit_warning = true;
+ deprecated_by = Some "grep";
tests = [
InitISOFS, Always, TestOutputList (
[["fgrepi"; "abc"; "/test-grep.txt"]], ["abc"; "abc123"; "ABC"])
@@ -5223,6 +5287,7 @@ matching lines." };
style = RStringList "lines", [String "regex"; Pathname "path"], [];
proc_nr = Some 157;
protocol_limit_warning = true;
+ deprecated_by = Some "grep";
tests = [
InitISOFS, Always, TestOutputList (
[["zgrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])
@@ -5237,6 +5302,7 @@ matching lines." };
style = RStringList "lines", [String "regex"; Pathname "path"], [];
proc_nr = Some 158;
protocol_limit_warning = true;
+ deprecated_by = Some "grep";
tests = [
InitISOFS, Always, TestOutputList (
[["zegrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])
@@ -5251,6 +5317,7 @@ matching lines." };
style = RStringList "lines", [String "pattern"; Pathname "path"], [];
proc_nr = Some 159;
protocol_limit_warning = true;
+ deprecated_by = Some "grep";
tests = [
InitISOFS, Always, TestOutputList (
[["zfgrep"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"])
@@ -5265,6 +5332,7 @@ matching lines." };
style = RStringList "lines", [String "regex"; Pathname "path"], [];
proc_nr = Some 160;
protocol_limit_warning = true;
+ deprecated_by = Some "grep";
tests = [
InitISOFS, Always, TestOutputList (
[["zgrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])
@@ -5279,6 +5347,7 @@ matching lines." };
style = RStringList "lines", [String "regex"; Pathname "path"], [];
proc_nr = Some 161;
protocol_limit_warning = true;
+ deprecated_by = Some "grep";
tests = [
InitISOFS, Always, TestOutputList (
[["zegrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])
@@ -5293,6 +5362,7 @@ matching lines." };
style = RStringList "lines", [String "pattern"; Pathname "path"], [];
proc_nr = Some 162;
protocol_limit_warning = true;
+ deprecated_by = Some "grep";
tests = [
InitISOFS, Always, TestOutputList (
[["zfgrepi"; "abc"; "/test-grep.txt.gz"]], ["abc"; "abc123"; "ABC"])
diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc
index 3129275d..ba148b01 100644
--- a/gobject/Makefile.inc
+++ b/gobject/Makefile.inc
@@ -47,6 +47,7 @@ guestfs_gobject_headers= \
include/guestfs-gobject/optargs-mount_local.h \
include/guestfs-gobject/optargs-umount_local.h \
include/guestfs-gobject/optargs-umount.h \
+ include/guestfs-gobject/optargs-grep.h \
include/guestfs-gobject/optargs-mkfs.h \
include/guestfs-gobject/optargs-mount_9p.h \
include/guestfs-gobject/optargs-ntfsresize.h \
@@ -95,6 +96,7 @@ guestfs_gobject_sources= \
src/optargs-mount_local.c \
src/optargs-umount_local.c \
src/optargs-umount.c \
+ src/optargs-grep.c \
src/optargs-mkfs.c \
src/optargs-mount_9p.c \
src/optargs-ntfsresize.c \
diff --git a/po/POTFILES b/po/POTFILES
index ada0da87..dffa8994 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -146,6 +146,7 @@ gobject/src/optargs-copy_file_to_device.c
gobject/src/optargs-copy_file_to_file.c
gobject/src/optargs-e2fsck.c
gobject/src/optargs-fstrim.c
+gobject/src/optargs-grep.c
gobject/src/optargs-inspect_get_icon.c
gobject/src/optargs-internal_test.c
gobject/src/optargs-md_create.c
diff --git a/src/inspect-fs.c b/src/inspect-fs.c
index 00500675..33aff353 100644
--- a/src/inspect-fs.c
+++ b/src/inspect-fs.c
@@ -551,7 +551,7 @@ guestfs___first_line_of_file (guestfs_h *g, const char *filename)
return ret;
}
-/* Get the first matching line (using guestfs_egrep{,i}) of a small file,
+/* Get the first matching line (using egrep [-i]) of a small file,
* without any trailing newline character.
*
* Returns: 1 = returned a line (in *ret)
@@ -565,8 +565,9 @@ guestfs___first_egrep_of_file (guestfs_h *g, const char *filename,
char **lines;
int64_t size;
size_t i;
+ struct guestfs_grep_opts_argv optargs;
- /* Don't trust guestfs_egrep not to break with very large files.
+ /* Don't trust guestfs_grep not to break with very large files.
* Check the file size is something reasonable first.
*/
size = guestfs_filesize (g, filename);
@@ -579,7 +580,13 @@ guestfs___first_egrep_of_file (guestfs_h *g, const char *filename,
return -1;
}
- lines = (!iflag ? guestfs_egrep : guestfs_egrepi) (g, eregex, filename);
+ optargs.bitmask = GUESTFS_GREP_OPTS_EXTENDED_BITMASK;
+ optargs.extended = 1;
+ if (iflag) {
+ optargs.bitmask |= GUESTFS_GREP_OPTS_INSENSITIVE_BITMASK;
+ optargs.insensitive = 1;
+ }
+ lines = guestfs_grep_opts_argv (g, eregex, filename, &optargs);
if (lines == NULL)
return -1;
if (lines[0] == NULL) {