mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
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.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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"])
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user