chiark / gitweb /
redaction works and documented; script for running on bessar to get everything only...
authorian <ian>
Mon, 16 Jun 2008 01:19:13 +0000 (01:19 +0000)
committerian <ian>
Mon, 16 Jun 2008 01:19:13 +0000 (01:19 +0000)
hostside/evdev-manip-bessar [new file with mode: 0755]
hostside/evdev-manip.c

diff --git a/hostside/evdev-manip-bessar b/hostside/evdev-manip-bessar
new file mode 100755 (executable)
index 0000000..583c66a
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+supp () { s="$s --redaction $* --suppress"; }
+
+supp  EV REL REL Y
+supp  EV REL REL X
+supp  0x01 02
+supp  0x01 02
+supp  EV MSC
+supp  0x0c 01
+supp  0xffbc 88 0xffbc 00
+
+./evdev-manip --redact $s \
+ --evdev /dev/input/event3 \
+ --hiddev /dev/hiddev0 
index 29e1263bf243b0a5c5ab60f719b0bc2aab4317b4..c4d46f3965290d3674d10702068fce3075e7f1f3 100644 (file)
  *  global options:
  *     --stdin-monitor      quit if stdin becomes readable
  *
+ *  redaction mode options:
+ *
+ *     --redaction <str>... --suppress  do not print these
+ *     --redaction <str>... --show      print these normally
+ *
+ *        Longest matching <str>... applies.  Later identical
+ *        <str>... paths override earlier ones.
+ *
+ *     --new-redactions     resets everything to default (which is --show)
+ *
+ *        Every device specified after --new-redactions gets the new
+ *        set of redactions, which includes even redactions specified
+ *        _after_ the device but _before_ the next --new-redactions.
+ *        It is not possible to selectively edit the redactions list;
+ *        devices which need different redaction lists need them
+ *        respecifying.
+ *
  *  per-device options (applies only to next device):
  *    --label LABEL         use LABEL instead of path in redacted output
  *
@@ -59,6 +76,14 @@ typedef struct ModeInfo ModeInfo;
 typedef const ModeInfo *Mode;
 typedef const KindInfo *Kind;
 
+typedef enum { RA_Show, RA_IntermediateNode, RA_Suppress } RedactionAction;
+
+typedef struct RedactionNode {
+  const char *str;
+  void *children; /* tsearch tree of RedactionNodes */
+  RedactionAction act;
+} RedactionNode;
+
 struct ModeInfo {
   void (*evdev_event)(Device *d, const struct input_event *ie);
   void (*evdev_readable)(Device *d);
@@ -78,7 +103,8 @@ struct KindInfo {
 
 typedef struct {
   int elide;
-} DeviceFlags;
+  RedactionNode redactions; /* root; .str is 0 and irrelevant */
+} DeviceOptions;
 
 typedef struct {
   struct hiddev_field_info fi;
@@ -90,7 +116,7 @@ struct Device {
   const char *label;
   int fd;
   const KindInfo *kind;
-  DeviceFlags flags;
+  DeviceOptions opts;
   union {
     struct {
       void *froot;
@@ -106,7 +132,7 @@ static Mode mode;
 static Kind kind;
 static int grab, stdinmonitor;
 static const char *expect_sysfs, *label;
-static DeviceFlags dflags= { 1 };
+static DeviceOptions dopts;
 
 static int ndevices;
 static Device *devices;
@@ -358,7 +384,7 @@ static int hiddev_elide(Device *d, const struct hiddev_usage_ref *ur,
   if (!f)
     return 0;
   
-  if (!d->flags.elide)
+  if (!d->opts.elide)
     return 0;
 
   unsigned relevant_flags= f->fi.flags &
@@ -546,10 +572,41 @@ static const ModeInfo mode_dump= {
 
 /*---------- mode redact ----------*/
 
+static int redaction_node_compar(const void *a_v, const void *b_v) {
+  const RedactionNode *a=a_v, *b=b_v;
+  return strcmp(a->str, b->str);
+}
+
+static RedactionNode *redact_find_node(int nstrs, const char *strs[nstrs]) {
+  RedactionNode key, *lastfound, *search;
+  void **rn_vp;
+
+  lastfound= search= &dopts.redactions;
+  for (;;) {
+    if (!nstrs) return lastfound;
+    key.str= strs[0];
+    rn_vp= tfind(&key, &search->children, redaction_node_compar);
+    if (!rn_vp) return lastfound;
+    search= *rn_vp;
+    if (search->act != RA_IntermediateNode)
+      lastfound= search;
+    strs++;
+    nstrs--;
+  }
+}
+
 static void redact_redacted(Device *d, int nstrs, const char *strs[nstrs],
                            int value) {
   int i;
-  
+  RedactionNode *rn;
+
+  rn= redact_find_node(nstrs, strs);
+  switch (rn->act) {
+  case RA_Show: break;
+  case RA_Suppress: return;
+  default: abort();
+  }
+
   printf("%s %d", d->label, value);
   for (i=0; i<nstrs; i++)
     printf(" %s", strs[i]);
@@ -562,6 +619,38 @@ static const ModeInfo mode_redact= {
   redact_redacted, dump_died, mainloop
 };
 
+static void redaction(const char ***argv) {
+  RedactionNode *path, *newnode;
+  void **searched;
+  const char *arg;
+
+  path= &dopts.redactions;
+  for (;;) {
+    arg= *++(*argv);
+    if (!arg) badusage("missing str or action for --redaction");
+    if (arg[0]=='-') break;
+    newnode= mmalloc(sizeof(*newnode));
+    newnode->str= arg;
+    searched= tsearch(newnode, &path->children, redaction_node_compar);
+    if (!searched) diee("allocate new redaction node");
+    if (*searched == newnode) {
+      newnode->children= 0;
+      newnode->act= RA_IntermediateNode;
+      path= newnode;
+    } else {
+      free(newnode);
+      path= *searched;
+    }
+  }
+  if (!strcmp(arg,"--suppress")) {
+    path->act= RA_Suppress;
+  } else if (!strcmp(arg,"--show")) {
+    path->act= RA_Show;
+  } else {
+    badusage("unknown or missing action for --redaction");
+  }
+}
+
 /*---------- main program ----------*/
 
 static void getdevice(const char *path) {
@@ -573,7 +662,7 @@ static void getdevice(const char *path) {
   d->path= mstrdup(path);
   d->fd= open(path, O_RDONLY);  if (d->fd<0) diee("%s: failed to open",path);
   d->kind= kind;
-  d->flags= dflags;
+  d->opts= dopts;
 
   if (label) {
     d->label= label;
@@ -590,6 +679,7 @@ int main(int argc, const char **argv) {
 
   mode= &mode_dump;
   kind= &kind_evdev;
+  dopts.elide= 1;
 
   while ((arg= *++argv)) {
     if (arg[0] != '-') {
@@ -601,14 +691,21 @@ int main(int argc, const char **argv) {
     else if (!strcmp(arg,"--label")) {
       if (!(label= *++argv)) badusage("missing arg for --expect-sysfs");
     }
+    else if (!strcmp(arg,"--redaction")) {
+      redaction(&argv);
+    }
+    else if (!strcmp(arg,"--new-redactions")) {
+      dopts.redactions.children= 0;
+      dopts.redactions.act= RA_Show;
+    }
     else if (!strcmp(arg,"--dump-raw")) { mode= &mode_dump; }
     else if (!strcmp(arg,"--redact")) { mode= &mode_redact; }
     else if (!strcmp(arg,"--evdev")) { kind= &kind_evdev; }
     else if (!strcmp(arg,"--hiddev")) { kind= &kind_hiddev; }
     else if (!strcmp(arg,"--grab")) { grab= 1; }
     else if (!strcmp(arg,"--no-grab")) { grab= 0; }
-    else if (!strcmp(arg,"--show-unchanged")) { dflags.elide= 0; }
-    else if (!strcmp(arg,"--elide-unchanged")) { dflags.elide= 1; }
+    else if (!strcmp(arg,"--show-unchanged")) { dopts.elide= 0; }
+    else if (!strcmp(arg,"--elide-unchanged")) { dopts.elide= 1; }
     else if (!strcmp(arg,"--stdin-monitor")) { stdinmonitor= 1; }
     else badusage("unknown option");
   }