#!PERL_COMMAND
-# $Cambridge: exim/src/src/exipick.src,v 1.4 2005/03/22 15:07:42 ph10 Exp $
+# $Cambridge: exim/src/src/exipick.src,v 1.5 2005/06/07 09:15:04 ph10 Exp $
# This variable should be set by the building process to Exim's spool directory.
my $spool = 'SPOOL_DIRECTORY';
use Getopt::Long;
my($p_name) = $0 =~ m|/?([^/]+)$|;
-my $p_version = "20050225.0";
+my $p_version = "20050604.1";
my $p_usage = "Usage: $p_name [--help|--version] (see --help for details)";
my $p_cp = <<EOM;
Copyright (c) 2003-2005 John Jetmore <jj33\@pobox.com>
'or' => \$G::or, # 'or' the criteria
'f:s' => \$G::qgrep_f, # from regexp
'r:s' => \$G::qgrep_r, # recipient regexp
- #'s:s' => \$G::qgrep_s, # match against size field
+ 's:s' => \$G::qgrep_s, # match against size field
'y:s' => \$G::qgrep_y, # message younger than (secs)
'o:s' => \$G::qgrep_o, # message older than (secs)
'z' => \$G::qgrep_z, # frozen only
'show-tests' => \$G::show_tests # display tests as applied to each message
) || exit(1);
-push(@ARGV, "\$sender_address =~ /$G::qgrep_f/") if ($G::qgrep_f);
-push(@ARGV, "\$recipients =~ /$G::qgrep_r/") if ($G::qgrep_r);
-push(@ARGV, "\$message_age < $G::qgrep_y") if ($G::qgrep_y);
-push(@ARGV, "\$message_age > $G::qgrep_o") if ($G::qgrep_o);
-push(@ARGV, "\$deliver_freeze") if ($G::qgrep_z);
-push(@ARGV, "!\$deliver_freeze") if ($G::qgrep_x);
+push(@ARGV, "\$sender_address =~ /$G::qgrep_f/") if ($G::qgrep_f);
+push(@ARGV, "\$recipients =~ /$G::qgrep_r/") if ($G::qgrep_r);
+push(@ARGV, "\$shown_message_size eq $G::qgrep_s") if ($G::qgrep_s);
+push(@ARGV, "\$message_age < $G::qgrep_y") if ($G::qgrep_y);
+push(@ARGV, "\$message_age > $G::qgrep_o") if ($G::qgrep_o);
+push(@ARGV, "\$deliver_freeze") if ($G::qgrep_z);
+push(@ARGV, "!\$deliver_freeze") if ($G::qgrep_x);
$G::mailq_bp = $G::mailq_bp; # shut up -w
$G::and = $G::and; # shut up -w
$G::msg_ids = {};
} elsif (/^(.*?)\s+(eq|ne)\s+(.*)$/) {
#print STDERR "found as string cmp\n";
my $var = lc($1); my $op = $2; my $val = $3;
+ $val =~ s|^(['"])(.*)\1$|$2|;
push(@c, { var => $var, cmp => "(\"\$var\" $op \"$val\") ? 1 : 0" });
if ($var eq 'message_id' && $op eq "eq") {
#print STDERR "short circuit @c[-1]->{cmp} $val\n";
$self->{_output_idonly} = 0;
$self->{_output_brief} = 0;
$self->{_output_flatq} = 0;
- $self->{_show_vars} = {};
+ $self->{_show_vars} = [];
$self->_reset();
return($self);
my $s = shift;
foreach my $v (split(/\s*,\s*/, $s)) {
- $self->{_show_vars}{$v}++;
+ push(@{$self->{_show_vars}}, $v);
}
}
# line 2
chomp($_ = <I>);
- return(0) if (!/^(.+)\s(\d+)\s(\d+)$/);
+ return(0) if (!/^(.+)\s(\-?\d+)\s(\-?\d+)$/);
$self->{_vars}{originator_login} = $1;
$self->{_vars}{originator_uid} = $2;
$self->{_vars}{originator_gid} = $3;
my $bytes = $_;
return(0) if (read(I, $_, $bytes) != $bytes);
chomp(); # may regret this later
+ $self->{_vars}{message_linecount} += scalar(split(/\n/)) if ($t ne '*');
# build the $header_ variable, following exim's rules (sort of)
if (/^([^ :]+):(.*)$/s) {
my $v = "header_" . lc($1);
$self->{_vars}{message_size} += $self->{_vars}{message_body_size} + 1;
}
+ $self->{_vars}{message_linecount} += $self->{_vars}{body_linecount};
+
+ my $i = $self->{_vars}{message_size};
+ if ($i == 0) { $i = ""; }
+ elsif ($i < 1024) { $i = sprintf("%d", $i); }
+ elsif ($i < 10*1024) { $i = sprintf("%.1fK", $i / 1024); }
+ elsif ($i < 1024*1024) { $i = sprintf("%dK", ($i+512)/1024); }
+ elsif ($i < 10*1024*1024) { $i = sprintf("%.1fM", $i/(1024*1024)); }
+ else { $i = sprintf("%dM", ($i + 512 * 1024)/(1024*1024)); }
+ $self->{_vars}{shown_message_size} = $i;
+
return(1);
}
return if ($self->{_delivered});
if ($self->{_output_idonly}) {
- print $fh $self->{_message}, "\n";
+ print $fh $self->{_message};
+ foreach my $v (@{$self->{_show_vars}}) {
+ print $fh " $v='", $self->get_var($v), "'";
+ }
+ print $fh "\n";
return;
}
else { printf $fh "%2dh ", $i; }
} else { printf $fh "%2dm ", $i; }
- $i = $self->{_vars}{message_size};
- if ($i == 0) { $i = " "; }
- elsif ($i < 1024) { $i = sprintf("%5d", $i); }
- elsif ($i < 10*1024) { $i = sprintf("%4.1fK", $i / 1024); }
- elsif ($i < 1024*1024) { $i = sprintf("%4dK", ($i+512)/1024); }
- elsif ($i < 10*1024*1024) { $i = sprintf("%4.1fM", $i/(1024*1024)); }
- else { $i = sprintf("%4dM", ($i + 512 * 1024)/(1024*1024)); }
- print $fh "$i ";
+ if ($self->{_output_flatq} && $self->{_show_vars}) {
+ print $fh join(';',
+ map { "$_='".$self->get_var($_)."'" }
+ (@{$self->{_show_vars}})
+ );
+ } else {
+ printf $fh "%5s", $self->{_vars}{shown_message_size};
+ }
+ print $fh " ";
}
print $fh "$self->{_message} ";
print $fh "From: " if ($self->{_output_brief});
print $fh " *** frozen ***" if ($self->{_vars}{deliver_freeze});
print $fh "\n";
- foreach my $v (keys(%{$self->{_show_vars}})) {
+ foreach my $v (@{$self->{_show_vars}}) {
printf $fh " %25s = '%s'\n", $v, $self->get_var($v);
}
push(@r, $r);
}
print $fh " To: ", join(';', @r);
+ if ($self->{_show_vars}) {
+ print $fh " Vars: ", join(';',
+ map { "$_='".$self->get_var($_)."'" }
+ (@{$self->{_show_vars}})
+ );
+ }
} elsif ($self->{_output_flatq}) {
print $fh " *** frozen ***" if ($self->{_vars}{deliver_freeze});
my @r = ();
By default criteria using the '=' operator are caseless. Specifying this option make them respect case.
+=item --show-vars <variable>[,<variable>...]
+
+Cause the value of each specified variable to be displayed for every message dispayed. For instance, the command "exipick --show-vars '$sender_ident' 'sender_host_address eq 127.0.01'" will show the ident string for every message submitted via localhost. How exactly the variable value is diplayed changes according to what output format you specify.
+
+=item --show-rules
+
+If specified the internal representation of each message criteria is shown. This is primarily used for debugging purposes.
+
+==item --show-tests
+
+If specified, for every message (regardless of matching criteria) the criteria's actual value is shown and the compiled internal eval is shown. This is used primarily for debugging purposes.
+
+=item --flatq
+
+Change format of output so that every message is on a single line. Useful for parsing with tools such as sed, awk, cut, etc.
+
=item The -bp* options all control how much information is displayed and in what manner. They all match the functionality of the options of the same name in Exim. Briefly:
=item -bp display the matching messages in 'mailq' format.
=item -r <regexp> Same as '$recipients = <regexp>'
+=item -s <string> Same as '$shown_message_size eq <string>'
+
=item -y <seconds> Same as '$message_age < <seconds>'
=item -o <seconds> Same as '$message_age > <seconds>'
The size of the body in bytes.
+=item . $message_linecount
+
+The number of lines in the entire message (body and headers).
+
=item . $message_size
The size of the message in bytes.
The number of Received: header lines in the message.
-=item + $received_time
+=item . $received_time
The epoch time at which the message was received.
The identification received in response to an RFC 1413 request for remote messages, the login name of the user that called Exim for locally generated messages.
+=item + $shown_message_size
+
+This non-standard variable contains the formatted size string. That is, for a message whose $message_size is 66566 bytes, $shown_message_size is 65K.
+
=item . $smtp_active_hostname
The value of the active host name when the message was received, as specified by the "smtp_active_hostname" option.