diff options
-rw-r--r-- | daemon/grep.c | 71 | ||||
-rw-r--r-- | examples/virt-dhcp-address.c | 4 | ||||
-rw-r--r-- | generator/generator_actions.ml | 82 | ||||
-rw-r--r-- | gobject/Makefile.inc | 2 | ||||
-rw-r--r-- | po/POTFILES | 1 | ||||
-rw-r--r-- | src/inspect-fs.c | 13 |
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) { |