[exim-dev] Add case-ignore to exiqgrep

Αρχική Σελίδα
Delete this message
Reply to this message
Συντάκτης: Todd Lyons
Ημερομηνία:  
Προς: exim-dev
Αντικείμενο: [exim-dev] Add case-ignore to exiqgrep
There was a serverfault post I just answered where someone asked how
to do a case-insensitive search for a specific domain that was
clogging his queue, and the sender was deliberately toggling case of
random characters.

http://serverfault.com/questions/535879/case-insensitive-exiqgrep/535916#535916

I instructed him to wrap his domain with the perl inline modifiers
method. It got me thinking that a simple addition to exiqgrep could
probably solve this. The -i option is already used, so I settled on
-I to trigger a case insensitive search. There are two ways that I
could think of for it to work:

1) do a /$opt{f}/i or a /$opt{r}/i
2) wrap the values like this:
    "(?i:" . $opt{f} . ")"


Personally I think #1 is an issue because you've doubled the amount of
if statements being processed in the loop (for -r and -f). True, for
cases where -I is *not* used, the first if would immediately fail,
skipping the case insensitve pattern match, then go on to the original
(faster because it's case-sensitve) pattern match. However, I also
think #2 is an issue because it's sloppier and more prone to problems
just wrapping user provided text strings like that. However, the speed
advantage is that it gets executed once and the speed of the inner
loop remains unchanged.

Speed is only an issue if you run large queues. In my case, where my
queues tend to fluctuate between 20 and 300 for a normal day, it
doesn't make a noticeable difference.

Does anybody think this is a good addition? A useless addition?
(obviously at least one person on serverfault would use it :-) I'll
commit it unless I hear complaints or suggestions for a better way to
do it.

[root@ivwm51 ~]# diff -ruN /usr/sbin/exiqgrep.sav /usr/sbin/exiqgrep
--- /usr/sbin/exiqgrep.sav    2013-09-03 13:40:41.000000000 +0000
+++ /usr/sbin/exiqgrep    2013-09-03 13:42:57.000000000 +0000
@@ -43,7 +43,7 @@
   $base = 62;
 };


-getopts('hf:r:y:o:s:zxlibRc',\%opt);
+getopts('hf:r:y:o:s:zxliIbRc',\%opt);
if ($opt{h}) { &help; exit;}

 # Read message queue output into hash
@@ -64,6 +64,7 @@
 Selection criteria:
     -f <regexp>    Match sender address sender (field is "< >" wrapped)
     -r <regexp>    Match recipient address
+    -I        Ignore case when matching sender/recipient
     -s <regexp>    Match against the size field from long output
     -y <seconds>    Message younger than
     -o <seconds>    Message older than
@@ -115,12 +116,16 @@
     foreach my $msg (keys(%id)) {
         if ($opt{f}) {
             # Match sender address
+            next unless ($opt{I} &&
+                    $id{$msg}{from} =~ /$opt{f}/i);
             next unless ($id{$msg}{from} =~ /$opt{f}/);
         }
         if ($opt{r}) {
             # Match any recipient address
             my $match = 0;
             foreach my $rcpt (@{$id{$msg}{rcpt}}) {
+                $match++ if ($opt{I} &&
+                        $rcpt =~ /$opt{r}/i);
                 $match++ if ($rcpt =~ /$opt{r}/);
             }
             next unless ($match);


Output from the program using the original inline modifier method and -I:

OVZ-CentOS58[root@ivwm51 ~]# exiqgrep -r @yahOo.com
OVZ-CentOS58[root@ivwm51 ~]# exiqgrep -r crazyivan@???
28h  4.0K 1VGRud-0001sm-P1 <> *** frozen ***
      crazyivan@???


OVZ-CentOS58[root@ivwm51 ~]# exiqgrep -r crazyIvan@???
OVZ-CentOS58[root@ivwm51 ~]# exiqgrep -r '(?i:crazyIvan@???)'
28h  4.0K 1VGRud-0001sm-P1 <> *** frozen ***
      crazyivan@???


OVZ-CentOS58[root@ivwm51 ~]# exiqgrep -I -r crazyIvan@???
28h  4.0K 1VGRud-0001sm-P1 <> *** frozen ***
      crazyivan@???


OVZ-CentOS58[root@ivwm51 ~]# exiqgrep -i -I -r crazyIvan@???
1VGRud-0001sm-P1


--
The total budget at all receivers for solving senders' problems is $0.
If you want them to accept your mail and manage it the way you want,
send it the way the spec says to. --John Levine