From 7ab8a3261b5b6f2404155a397dd3950fb7a67c8f Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Fri, 27 Dec 2013 15:58:27 +0400 Subject: [PATCH] show: Implement simple images filtering The -F|--fields option specifies which fields (by name, comma separated) should be printed. For nested fields all names in path should be specified. Signed-off-by: Pavel Emelyanov --- crtools.c | 7 ++++++- include/cr_options.h | 1 + protobuf.c | 27 +++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/crtools.c b/crtools.c index fb04e20cc..ade755c55 100644 --- a/crtools.c +++ b/crtools.c @@ -98,7 +98,7 @@ int main(int argc, char *argv[]) return 1; while (1) { - static const char short_opts[] = "dsRf:t:p:hcD:o:n:v::xVr:jlW:L:"; + static const char short_opts[] = "dsRf:F:t:p:hcD:o:n:v::xVr:jlW:L:"; static struct option long_opts[] = { { "tree", required_argument, 0, 't' }, { "pid", required_argument, 0, 'p' }, @@ -108,6 +108,7 @@ int main(int argc, char *argv[]) { "daemon", no_argument, 0, 'd' }, { "contents", no_argument, 0, 'c' }, { "file", required_argument, 0, 'f' }, + { "fields", required_argument, 0, 'F' }, { "images-dir", required_argument, 0, 'D' }, { "work-dir", required_argument, 0, 'W' }, { "log-file", required_argument, 0, 'o' }, @@ -163,6 +164,9 @@ int main(int argc, char *argv[]) case 'f': opts.show_dump_file = optarg; break; + case 'F': + opts.show_fmt = optarg; + break; case 'r': opts.root = optarg; break; @@ -451,6 +455,7 @@ usage: "\n" "Show options:\n" " -f|--file FILE show contents of a checkpoint file\n" +" -F|--fields FIELDS show specified fields (comma separated)\n" " -D|--images-dir DIR directory where to get images from\n" " -c|--contents show contents of pages dumped in hexdump format\n" " -p|--pid PID show files relevant to PID (filter -D flood)\n" diff --git a/include/cr_options.h b/include/cr_options.h index b2f8b6c8a..ef69f9ca0 100644 --- a/include/cr_options.h +++ b/include/cr_options.h @@ -13,6 +13,7 @@ struct script { struct cr_options { int final_state; char *show_dump_file; + char *show_fmt; bool check_ms_kernel; bool show_pages_content; bool restore_detach; diff --git a/protobuf.c b/protobuf.c index 885a62f84..62aa57164 100644 --- a/protobuf.c +++ b/protobuf.c @@ -16,6 +16,7 @@ #include "util.h" #include "string.h" #include "sockets.h" +#include "cr_options.h" #include "protobuf.h" @@ -408,6 +409,29 @@ static int pb_optional_field_present(const ProtobufCFieldDescriptor *field, return 1; } +static bool should_show_field(const char *name) +{ + char *s, *e; + int len; + + if (!opts.show_fmt) + return true; + + len = strlen(name); + s = opts.show_fmt; + + while (1) { + e = strchrnul(s, ','); + if (e - s == len) { + if (!strncmp(name, s, len)) + return true; + } + if (*e == '\0') + return false; + s = e + 1; + } +} + static void pb_show_msg(const void *msg, pb_pr_ctl_t *ctl) { int i; @@ -428,6 +452,9 @@ static void pb_show_msg(const void *msg, pb_pr_ctl_t *ctl) continue; } + if (!should_show_field(fd.name)) + continue; + if (fd.label == PROTOBUF_C_LABEL_REPEATED) { nr_fields = *(size_t *)(msg + fd.quantifier_offset); data = (unsigned long *)*data;