Check whether at least two out of three procmail conditions are true - procmail

How do I check in procmail whether at least two out of three spam filters see the mail as spam? I don't want to have duplicate code due to multiple checks on the spam headers.
# Invoke bogofilter
:0 fw
| bogofilter -C -d /home/shared_directories/bogofilter -p -e
# Invoke bmf
:0 fw
| bmf -d /home/shared_directories/bmf -f text -p
# Invoke spambayes
:0 fw
| sb_filter -d /home/shared_directories/spambayes
# If two out of three filters agree it's spam, file it.
:0
* ^X-Bogosity: Spam
* ^X-Spam-Status: Yes
* ^X-Spambayes-Classification: spam
{
# Process the mail
}

You can use scoring with a base score of -1.
:0
* -1^0
* 1^0 ^X-Bogosity: Spam
* 1^0 ^X-Spam-Status: Yes
* 1^0 ^X-Spambayes-Classification: spam
{
# ... stuff
If a single condition matches, the score only goes to zero, so the compound result is no match. If two or more of the individual conditions bring the score above zero, the action is taken.
The procmailsc manual page explains this mechanism. It's not very widely used, and it has a number of complexities, but the basics are easy and straightforward.

Related

Telegraf: How to extract from field using regex processor?

I would like to extract the values for connections, upstream and downstream using telegraf regex processor plugin from this input:
2022/11/16 22:38:48 In the last 1h0m0s, there were 10 connections. Traffic Relayed ↑ 60 MB, ↓ 4 MB.
Using this configuration the result key "upstream" is a copy of the initial message but without a part of the 'regexed' stuff.
[[processors.regex]]
tagpass = ["snowflake-proxy"]
[[processors.regex.fields]]
## Field to change
key = "message"
## All the power of the Go regular expressions available here
## For example, named subgroups
pattern = 'Relayed.{3}(?P<UPSTREAM>\d{1,4}\W.B),'
replacement = "${UPSTREAM}"
## If result_key is present, a new field will be created
## instead of changing existing field
result_key = "upstream"
Current output:
2022/11/17 10:38:48 In the last 1h0m0s, there were 1 connections. Traffic 3 MB ↓ 5 MB.
How do I get the decimals?
I'm quite a bit confused how to use the regex here, because on several examples in the web it should work like this. See for example: http://wiki.webperfect.ch/index.php?title=Telegraf:_Processor_Plugins
The replacement config option specifies what you want to replace in for any matches.
I think you want something closer to this:
[[processors.regex.fields]]
key = "message"
pattern = '.*Relayed.{3}(?P<UPSTREAM>\d{1,4}\W.B),.*$'
replacement = "${1}"
result_key = "upstream"
to get:
upstream="60 MB"

Using rrdtool to monitor few servers

Please help to understand. I find the simple of script in off site about update RRDTool base.
But for me need to create one rrd base to all servers. Please help to understand what way the best and just give some point how to do this.
Send data from all servers to rrdtool base and update it? or try to get all data from server where rrdtool and update in local level?
#!/bin/sh
a=0
while [ "$a" == 0 ]; do
snmpwalk -c public 192.168.1.250 hrSWRunPerfMem > snmp_reply
total_mem=`awk 'BEGIN {tot_mem=0}
{ if ($NF == "KBytes")
{tot_mem=tot_mem+$(NF-1)}
}
END {print tot_mem}' snmp_reply`
# I can use N as a replacement for the current time
rrdtool update target.rrd N:$total_mem
# sleep until the next 300 seconds are full
perl -e 'sleep 300 - time % 300'
done # end of while loop

What tool to use for this regex

I am using a combination of Automator, Bash, and Exiftool to take filenames like this: 0615090217.jpg and change the date created to 2009:06:15 02:17:00.
Most of the pieces of the puzzle are working, I even have working regex, I just don't know how to apply it using bash or some combination of other tools. I've been seeing sed suggested, but I don't know how to apply it.
The following regex works here, but I don't know how to apply it in my setup:
Expression: /(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(.*)\.[^.]+$/g
Substitution: \n20$3:$1:$2 $4:$5:00\n\t
Text: 0615090217.jpg
The shell script in my Automator workflow looks like this:
for f in "$#"
do
FILENAME=$(basename "$f")
MYDATE='2010:07:09 12:22:00'
/usr/local/bin/exiftool -overwrite_original_in_place -preserve "-AllDates=${MYDATE}" "$f"
done
I want to replace MYDATE with a date extracted from the filename, using my regex or some other method. I feel like I'm close, it's just connecting the final dots.
If you're using OSX, FreeBSD, NetBSD, etc, then the date command lets you easily convert from one format to another:
#!/usr/bin/env bash
for f in "$#"
do
FILENAME=$(basename "$f")
MYDATE=$(date -j -f '%m%d%y%H%M.jpg' "$FILENAME" '+%Y-%m-%d %H:%M:00')
/usr/local/bin/exiftool \
-overwrite_original_in_place \
-preserve "-AllDates=${MYDATE}" \
"$f"
done
You can also achieve this by ripping apart the filename using bash's "Parameter Expansion", but that takes more typing.
Exiftool can do this by itself. There's no need for scripts, since that would just slow the whole process down because it would call exiftool for each file.
Try something like:
/usr/local/bin/exiftool -overwrite_original_in_place -preserve '-AllDates<${Filename;s/(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(.*)\.[^.]+$/20$3:$1:$2 $4:$5:00/}' DIR
I just lifted your regex and stuck it in, so test it out first, of course. My quick test here worked correctly, output below.
c:\>exiftool -g1 -alldates X:\!temp\0615090217.jpg
---- IFD0 ----
Modify Date : 2012:08:30 22:25:33
---- ExifIFD ----
Date/Time Original : 2013:18:08 19:04:15
Create Date : 2012:08:30 22:25:33
c:\>exiftool "-AllDates<${Filename;s/(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(.*)\.[^.]+$/20$3:$1:$2 $4:$5:00/}" X:\!temp\0615090217.jpg
1 image files updated
c:\>exiftool -g1 -alldates X:\!temp\0615090217.jpg
---- IFD0 ----
Modify Date : 2009:06:15 02:17:00
---- ExifIFD ----
Date/Time Original : 2009:06:15 02:17:00
Create Date : 2009:06:15 02:17:00

Expect - How can I perform multiple regular expression matches in one interact loop?

I'm trying to perform multiple regular expression matches on the same screen output, during one interact session. With the following code I'm getting the error message: "cannot use -o more than once"
Ultimately I want to extract several small data variables from each screen of output, using several regular expressions as detailed in this question. Is what I'm trying to do possible, if so what is the correct syntax?
interact {
#...
#... actions during interact loop to perform with variables extracted
#...
#variable extraction from output ------------------------------------
-o -nobuffer -re {(\[1;14H[a-zA-Z0-9]{1})[0-9]{5}} {
#get po number
set poraw $interact_out(0,string)
#get just po out
set po [string range $poraw 6 11]
#switch to lowercase
set po [string tolower $po]
#send_user " stored po: $po"
}
#get cost from po detail
#ex. 001b[14;27H 20.1900
-o -nobuffer -re {(\[14\;27H)[0-9]{0-6}\.{1}[0-9]{4}} {
set pocost $interact_out(0,string)
send_user " stored po cost: $pocost"
}
}
EDIT:
So the code that worked looks like this:
interact {
#...
-o
-nobuffer -re {(\[1;14H[a-zA-Z0-9]{1})[0-9]{5}} {
#get po number
set poraw $interact_out(0,string)
#get just po out
set po [string range $poraw 6 11]
#switch to lowercase
set po [string tolower $po]
}
#get cost from po detail
#ex. 001b[14;27H 20.1900
-nobuffer -re {(\[14\;27H) *[0-9]{0,6}\.{1}[0-9]{4}} {
set pocostraw $interact_out(0,string)
set pocosttrim [string range $pocostraw 7 17]
set pocost [string trimleft $pocosttrim ]
send_user " stored po cost: $pocost"
}
}
From man expect, section about interact:
The -o flag causes any following key-body pairs to be applied to the output of the current process. This can be useful, for example, when dealing with hosts that send unwanted characters during a telnet session. [emphasis mine]
So it seems that the -o changes the behavior from where it appears till the end of the interact block. Thus, it makes kind of sense that it can appear only once.
The solution is now obvious: put all the output expressions together at the end of the interact and add the -o just before the first one.

Creation of mass phrase search for website domain

I need to replace a single text phrase across my entire website domain with another one. What is the best way to do a mass search/ replace?
If you can do it file-by-file, then you could use a simple Perl one-liner:
perl -pi -e 's/search/replace/gi' filename.txt
If you are on a UNIX system with a shell, you can combine this with find to search and replace text on files in subdirectoies:
find /dir/to/files -iname 'foo.*' -exec perl ... {}\;
where ... is the above perl command.
I use KEDIT to do this every day. I have a script I wrote called TooMany.kex which allows me to edit a list of files across computers and networks. The only other way I know how to do it is using a shell script - you already have that.
* TooMany.kex - perform commands on files using a directory
* (this is designed to issue edit commands to too many files for the ring buffer)
* Multiple commands are separated by a semicolon ";"
*
* eg. TooMany c\one\two\**;c\two\three\**;file
* commands:
* 1. kedit "dirfileid.1()" (nodefext noprof'
* 2. c\one\two\**
* 3. c\two\three\**
* 4. file
*
parse arg CmdStr
if ftype.1() \= 'DIR' then do
'alert /The File Type Must Be "DIR"./ title /TooMany/'
exit
end
'nomsg less /</|/>/'
if rc = 0 then do
if nbscope.1() = 0 then do
'alert /No files found/ title /TooMany/'
exit
end
end
'top'
* give user something to look at while macro is running
'extract /nbfile/fileid'
* the number of files can change depending on the setting SCOPE/DISPLAY or ALL
size = nbscope.1()
if scope.1() = "ALL" then size = size.1()
nfiles = size
'msg Processing' size 'files.'
'refresh'
* save the directory file name
dir_fileid = fileid.1()
do nfiles - 1
* if less than 3K ISA free, leave early so user has some to work with
if memory.3() < 3 then do
'alert $TooMany aborting. ISA nearly full. You Forgot To File.$ title $TooMany$'
'qquit'
exit
end
'down'
'refresh'
'kedit "'dirfileid.1()'" (nodefext noprof'
if rc \= 0 then do
'alert $TooMany aborting. KEDIT rc='rc'$ title $TooMany$'
exit
end
Call ExecuteCommands
* edit file # 1 in the ring
'kedit "'fileid.1'" (noprof'
*'refresh'
end
* quit out of dir.dir and edit the last file
'next'
fid = dirfileid.1()
** 'qquit'
'kedit "'fid'" (nodefext noprof'
Call ExecuteCommands
'msg TooMany:' nfiles 'file(s) processed'
exit
ExecuteCommands:
* special skip files - don't edit the directory file
if dir_fileid = fileid.1() then return
* Execute commands separated by ";"
istart = 1
do forever
if pos(";",CmdStr,istart) = 0 then do
command substr(CmdStr,istart,length(CmdStr))
return
end
else do
iend = pos(";",CmdStr,istart)
command substr(CmdStr,istart,iend - istart)
istart = iend + 1
if istart > length(CmdStr) then return
end
end
return