[Project] Rework grep to be plain Lua command

This commit is contained in:
Vsevolod Stakhov 2018-05-29 13:53:53 +01:00
parent 6f1ac61c71
commit 680fd4843c
2 changed files with 62 additions and 160 deletions

View File

@ -1,6 +1,59 @@
return function(_, res)
--[[
Copyright (c) 2018, Vsevolod Stakhov <vsevolod@highsecure.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
]]--
local argparse = require "argparse"
-- Define command line options
local parser = argparse()
:name "rspamadm grep"
:description "rspamadm grep - search for patterns in rspamd logs"
:help_description_margin(30)
parser:option "-s --string"
:description('Plain string to search (case-insensitive)')
:argname "<str>"
parser:flag "-l --lua"
:description('Use Lua patterns in string search')
parser:option "-p --pattern"
:description('Pattern to search for (regex)')
:args(1)
:argname "<re>"
parser:argument "input":args "*"
:description('Process specified inputs')
:default("stdin")
parser:flag "-S --sensitive"
:description('Enable case-sensitivity in string search')
:default("false")
parser:flag "-o --orphans"
:description('Print orphaned logs')
parser:flag "-P --partial"
:description('Print partial logs')
local function handler(args)
local rspamd_regexp = require 'rspamd_regexp'
local res = parser:parse(args)
if not res['string'] and not res['pattern'] then
parser:error('string or pattern options must be specified')
end
if res['string'] and res['pattern'] then
parser:error('string and pattern options are mutually exclusive')
end
local buffer = {}
local matches = {}
@ -16,7 +69,7 @@ return function(_, res)
end
local plainm = true
if res['luapat'] then
if res['lua'] then
plainm = false
end
local orphans = res['orphans']
@ -26,7 +79,7 @@ return function(_, res)
if search_str and not sensitive then
search_str = string.lower(search_str)
end
local inputs = res['inputs']
local inputs = res['input'] or {'stdin'}
for _, n in ipairs(inputs) do
local h, err
@ -110,3 +163,9 @@ return function(_, res)
end
end
end
return {
handler = handler,
description = parser.description,
name = 'grep'
}

View File

@ -1,157 +0,0 @@
/*-
* Copyright (c) 2017, Andrew Lewis <nerf@judo.za.org>
* Copyright (c) 2017, Vsevolod Stakhov <vsevolod@highsecure.ru>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "config.h"
#include "rspamadm.h"
#include "lua/lua_common.h"
static gchar *string = NULL;
static gchar *pattern = NULL;
static gchar **inputs = NULL;
static gboolean sensitive = FALSE;
static gboolean orphans = FALSE;
static gboolean partial = FALSE;
static gboolean luapat = FALSE;
static void rspamadm_grep (gint argc, gchar **argv,
const struct rspamadm_command *cmd);
static const char *rspamadm_grep_help (gboolean full_help,
const struct rspamadm_command *cmd);
struct rspamadm_command grep_command = {
.name = "grep",
.flags = 0,
.help = rspamadm_grep_help,
.run = rspamadm_grep,
.lua_subrs = NULL,
};
static GOptionEntry entries[] = {
{"string", 's', 0, G_OPTION_ARG_STRING, &string,
"Plain string to search (case-insensitive)", NULL},
{"lua", 'l', 0, G_OPTION_ARG_NONE, &luapat,
"Use Lua patterns in string search", NULL},
{"pattern", 'p', 0, G_OPTION_ARG_STRING, &pattern,
"Pattern to search for (regex)", NULL},
{"input", 'i', 0, G_OPTION_ARG_STRING_ARRAY, &inputs,
"Process specified inputs (stdin if unspecified)", NULL},
{"sensitive", 'S', 0, G_OPTION_ARG_NONE, &sensitive,
"Enable case-sensitivity in string search", NULL},
{"orphans", 'o', 0, G_OPTION_ARG_NONE, &orphans,
"Print orphaned logs", NULL},
{"partial", 'P', 0, G_OPTION_ARG_NONE, &partial,
"Print partial logs", NULL},
{NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}
};
static const char *
rspamadm_grep_help (gboolean full_help, const struct rspamadm_command *cmd)
{
const char *help_str;
if (full_help) {
help_str = "Search for patterns in rspamd logs\n\n"
"Usage: rspamadm grep <-s string | -p pattern> [-i input1 -i input2 -S -o -P]\n"
"Where options are:\n\n"
"-s: Plain string to search (case-insensitive)\n"
"-l: Use Lua patterns in string search\n"
"-p: Pattern to search for (regex)\n"
"-i: Process specified inputs (stdin if unspecified)\n"
"-S: Enable case-sensitivity in string search\n"
"-o: Print orphaned logs\n"
"-P: Print partial logs\n";
}
else {
help_str = "Search for patterns in rspamd logs";
}
return help_str;
}
static void
rspamadm_grep (gint argc, gchar **argv, const struct rspamadm_command *cmd)
{
GOptionContext *context;
GError *error = NULL;
lua_State *L;
ucl_object_t *obj, *nobj;
gchar **elt;
context = g_option_context_new (
"grep - search for patterns in rspamd logs");
g_option_context_set_summary (context,
"Summary:\n Rspamd administration utility version "
RVERSION
"\n Release id: "
RID);
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_set_ignore_unknown_options (context, FALSE);
if (!g_option_context_parse (context, &argc, &argv, &error)) {
rspamd_fprintf (stderr, "option parsing failed: %s\n", error->message);
g_error_free (error);
exit (1);
}
if (!pattern && !string) {
rspamd_fprintf (stderr, "no search pattern specified\n");
exit (1);
}
if (pattern && string) {
rspamd_fprintf (stderr, "-s and -p are mutually-exclusive\n");
exit (1);
}
L = rspamd_lua_init ();
rspamd_lua_set_path (L, NULL, ucl_vars);
obj = ucl_object_typed_new (UCL_OBJECT);
if (string) {
ucl_object_insert_key (obj, ucl_object_fromstring (string),
"string", 0, false);
}
if (pattern) {
ucl_object_insert_key (obj, ucl_object_fromstring (pattern),
"pattern", 0, false);
}
nobj = ucl_object_typed_new (UCL_ARRAY);
if (!inputs) {
ucl_array_append (nobj, ucl_object_fromstring ("stdin"));
}
else {
for (elt = inputs; *elt != NULL; elt ++) {
ucl_array_append (nobj, ucl_object_fromstring (*elt));
}
}
ucl_object_insert_key (obj, nobj, "inputs", 0, false);
ucl_object_insert_key (obj, ucl_object_frombool (sensitive),
"sensitive", 0, false);
ucl_object_insert_key (obj, ucl_object_frombool (orphans),
"orphans", 0, false);
ucl_object_insert_key (obj, ucl_object_frombool (partial),
"partial", 0, false);
ucl_object_insert_key (obj, ucl_object_frombool (luapat),
"luapat", 0, false);
rspamadm_execute_lua_ucl_subr (L,
argc,
argv,
obj,
"grep");
ucl_object_unref (obj);
}