postfix利用寄件者刪除mail queue

是歐萊禮postfix技術手冊(白鴿書)中的perl程式, 只改了一些變數名稱與一各地方印刷錯誤(但是忘記錯誤在哪裡了)

貼上來是因為, 某時候會忽然需要用到, 放網站上方便點=.=

#############################################

#!/usr/bin/perl

## delmail
## delete postfix mail queue by sender address

## usage:: delmail <email_address>

use strict;

my $LISTQ = "/usr/sbin/postqueue -p";
my $POSTSUPER = "/usr/sbin/postsuper";

my $mail_addr = "";
my $qid = "";
my $uid = $>;

if ( @ARGV != 1) {
die "Usage: delmail <Email\@Address>\n";
} else {
$mail_addr = $ARGV[0];
}

if ( $uid != 0 ) {
die "You must be root to delete mail queue.\n";
}

open (QUEUE, "$LISTQ |") ||
die "Can't get pipe to $LISTQ: $!\n";

my $entry = <QUEUE>;
$/ = "";

while ($entry = <QUEUE> ) {
if ($entry =~ / $mail_addr$/m) {
($qid) = split(/\s+/, $entry, 2);
$qid =~ s/[\*\!]//;
print  $qid."\n";
next unless ($qid);
if (system($POSTSUPER, "-d", $qid) != 0) {
die "Error occur while Excuting $POSTSUPER, error code".($?/256)."\n";
}
}
}
close(QUEUE);

if (! $qid) {
die "No messages from <$mail_addr> found in mail queue.\n";
}

exit 0;
廣告

system log scan script written by perl

I forgot where the original script from, seems it’s from sun a perl script to check if messeges or syslog (mail log in solaris) has specified keyword. It needs to run hourly, the script only check last hours logs.

A new function was added, if there no new lines need to inform the script will skip mail action.

這是從sun網站上抓來的log scan script, 大概是從sun網站抓的吧, 我已經忘記了, 改寫部分功能讓它檢查log時如果沒有新發現就不要寄信出來. 這script要排程每各小時讓它跑, 因為它只會檢查上一各小時的log.

#########################################################


#!/bin/perl -w
# msg_log - A sysadmin tool...
# Scans indicated files for indicated things...

# NOTE:  You NEED to READ The Code and SET Some Variables BEFORE Installing!
#        Those areas which need setting are INDICATED by the word 'Set ...'.
# Version v0.05s -

# 071004 modified by parus, not mail if no new entry
# scan specified log file a hour ago, if anything new mail to user's mailbox

use strict;
use diagnostics;

# Set your path to sendmail. Oops! That means "Here there be Unix..."
my $SENDMAIL = '/usr/lib/sendmail';

# Set (pick) a reporting style...
my $report = 1; # Note: 0 = Complete, 1 = Summary reporting...

# WARNING: Selecting 0 (Complete reporting) can generate A LOT of data!!!
# Set your locahost, default host; and localdomain, default domain:
my $defaulthost   = "localhost";
my $defaultdomain = "localdomain";

# I'll get your host and userID (who will get these reports?)
# Or Set a recipient at the end of the first command here:
chomp(my $userid = `/usr/ucb/whoami` || `/usr/bin/whoami` || 'root');# Set as appropriate for your system.
chomp(my $host   = `/bin/hostname` || `/bin/uname -n` || $defaulthost);
chomp(my $domain = `/bin/domainname` || $defaultdomain);

# NOTE:  Some of these logs may require root access to view...
# Use with appropriate caution!  You've been warned!

# Where are your system logs?  The defaults are for Solaris (the OpSys I use...)
# Note:  You can add other logs to scan here as needed...
my $msgpath = '/var/adm/messages';
#my $supath  = '/var/adm/sulog';    # Requires root access to view...
my $syspath = '/var/log/syslog';

# What do you wish to scan the 'messages' log for?
my $msglog = '(fail|snif|unkn|denied|root|inetd|warn|fatal|full|error|NOTICE|WARN|Failed)';

# What do you wish to scan the 'sulog' log for (requires r00t axces) ?
#my $sulog = '(su)';

# What do you wish to scan the 'syslog' log for?
my $syslog = '(denied|unix)';

# Example of DATE: Tue Feb  2 19:34:24 EST 1999
my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
my   @days = qw(Sun Mon Tue Wed Thu Fri Sat);
my ($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime;
#  (  00   20    20    16   10    63    06 197 01); # Last two not used...
# Ex: $days[$wday] $months[$mon] $mday $hour:$min:$sec $year
my $thour = 0;
if ( $hour == 00 ) {
$thour = 23;
}
else {
$thour = $hour -1;
}
my $today = $months[$mon] . " " . sprintf("%2d", $mday) . " " . sprintf("%02d", $thour); # Get just today's Date...

my $ntday = sprintf("%02d", ++$mon) . '/' . sprintf("%02d", $mday); # Get just today's Numbers...

# ..... Start Main Logic .....
# Add each path_to_log, Log_date_format, and search_data here as
# previsouly defined above...
#print MAIL "$supath -\n";
#&process_log($supath, $ntday, $sulog);

my @messege = process_log($msgpath, $today, $msglog);
my @system = process_log($syspath, $today, $syslog);

if ( scalar @messege > 0 || scalar @system > 0 ) {
&write_mail();
}

# ..... End Main Logic .....

exit; # End of program...

##############################
##### Subroutine Area... #####
##############################
sub process_log {
my $target_log  = shift;
my $search_date = shift;
my $search_data = shift;
open (MY_LOGS, "$target_log") or die "Can't find $target_log: $!";
while (<MY_LOGS>) {
chomp;              # no newline...
s/#.*//; # no comments...
s/^\s+//; # no leading whitespace...
s/\s+$//; # no trailing whitespace...
next unless length; # anything to process?
next unless /$search_date/;
if ($report) {
next unless /$search_data/i;
}
push(@_,$_);
}
return @_;
}

sub write_mail {
open (MAIL, "| $SENDMAIL $userid") || die ("$0: Can't open $SENDMAIL: $!\n");
print MAIL "Reply-to: root\@$domain\n";
print MAIL "From: \"$host.Message.Log\" \<root\@$host.$domain\>\n";
print MAIL "To: $userid\n";
print MAIL "Subject: $host MsgLog Report at ", scalar localtime, "\n";
print MAIL "\n\n";
print MAIL "\n\n";
($report) ? print MAIL "Summary" : print MAIL "Complete";
print MAIL " report from " . $host . $domain . ":\n";

print MAIL "\n$msgpath -\n";
foreach (@messege) {print MAIL "$_\n"};

print MAIL "\n$syspath -\n";
foreach (@system) {print MAIL "$_\n"};

print MAIL "\n\nEnd of Report...\n";
close (MAIL);
}

由文件檔塞資料進MS SQL

這其實不是一個完整的程式,只是一個常用的片段。

呼叫ODBC 走ODBC將文字檔中的資料一行一行的餵進MS SQL之中

#########################################################

#written by parus on someday in 2005

use Win32::ODBC;

$file = “";
#the file contains data source
$table = “";
#the table feed the data
$dsn = “";
#the odbc name you give on client
$idname = “";
#the username of DB
$password = “";
#the password of db user

($mday, $mon, $year) = (localtime( time() ))[3..5];
$today = sprintf “%04d%02d%02d", $year + 1900, $mon + 1, $mday;
#today’s date

$dbh = new Win32::ODBC(“DSN=$dsn;UID=$idname;PWD=$password;");
die “Unable to connect to DSN m2kcathmail: “.Win32::ODBC::Error()."\n" if ! $dbh;
open (FILE,$file) or die “$!";
while () {
chomp;
$sql = “Insert into “.$table." values (,".$_.","$today",)";
#this sql statement insert the data and date into specified table
$rc=$dbh->Sql($sql);
if ($rc){
print “Error $rc".$dbh->error();
exit(0);
}
}
$dbh->Close();
close FILE;

信件寄送時間測試程式

這是一個小PERL程式,用來針對MAIL系統除錯用的。原理是這樣:透過一台SMTP SERVER寄送一封小信件上面什麼都沒有,只有帶時間戳記。然後去POP3 SERVER上將這封信收下來,計算收到信的時間與信上時間的差別,如此便可以知道郵件系統的效能。因為不同的地方寄信得到的數字會不同,所以可以多試幾 個點,以找出是否有什麼地方會卡住。

當然,要使用這程式必須在機器上(不論是什麼OS)有安裝PERL,並有安裝SMTP與POP3模組。
這程式會把收下來的信件存成一個檔案,包括信件標頭,以供除錯用。

###################################################

#sendtestmail.pl written by parus on 20060208
# sent a test mail to specified mail address and caclute spend time period
# !!before use empty the reciver’s mail box or it’ll cause terrible result

use Net::SMTP;
use Net::SMTP_auth;
use Net::POP3;

$body = time();

#variable here
#sender mail address
$from_addr = “;
#reciver mail address
$to_addr = “;
#smtp server with username & password
$smtpserver = “;
$smtpuser = “;
$smtppass = “;
#pops server with username & password
$pop3server = “;
$pop3user = “;
$pop3pass = “;
#####################################

#mail subject
$subject = “Mail pass through test";

print “Start: “.$smtpserver."\n";
print “Goal: “.$pop3server."\n\n";

$smtp = Net::SMTP_auth->new(
$smtpserver,
Hello => ‘jimmylin.com.tw’,
Timeout => 30,
Debug => 0,
) or die “Ops, Can’t connect to smtp server!";
$smtp->auth(‘LOGIN’, $smtpuser, $smtppass);

$smtp->mail($from_addr);
$smtp->to($to_addr);

$smtp->data();
$smtp->datasend(“To: $to_addr\n");
$smtp->datasend(“Subject: $subject\n");
$smtp->datasend($body."\n");
$smtp->dataend();

$smtp->quit;

$pop = Net::POP3->new($pop3server);
$pop = Net::POP3->new($pop3server, Timeout => 60, Debug => 0,);

$i = 0;

if ($pop->login($pop3user, $pop3pass) > 0) {
my $msgnums = $pop->list; # hashref of msgnum => size
foreach my $msgnum (keys %$msgnums) {
my $msg = $pop->get($msgnum);
my $now = time();
open (FILE,">>$now") or die “$!";
print FILE @$msg;
close FILE; #save mail as file
my $start =@$msg[-2];
$diff = $now – $body;
#print $body."\n";
#print $now."\n";
print “Spend “.$diff." seconds during transfer mail.\n";
$pop->delete($msgnum);
}
$pop->quit;
}
else {
$pop->quit;
$i++;
print $i;
sleep 5;
$pop->login($pop3user, $pop3pass);
}

我竟然不會用PHP寫TELNET功能 @@

DATE: 02/24/2005 10:04:37 PM

這兩天寫各小工具
需要TELNET到遠端一台SERVER去執行幾各指令,並抓回回傳值
本來想 不就是TELNET 直接開SOCKET就得了 小事一件

沒想到…..
開SOCKET是沒有錯
回傳值卻始終是亂碼,可是TELNET應該是回傳字串阿 DO SI DA

話說回來,這是啥年代了,還用TELNET,不知道有個咚咚叫SSH嗎?
只是很不幸的,執行PHP的地方是一台暈倒2000
(我也好想暈倒 >_<)
不管我自己寫也好,抓別人寫的元件也好
一樣是 DA MAE

火大不用PHP改用PERL…….竟然也是一樣
這…這…
我敗了 Orz
為什麼我得要開這種拼裝車ㄌ….
換台LINUX或BSD不就一切都解決了嗎
天阿 誰來解救我