XSERVER で メール着信を通知する。

さて、メールサーバをXserver で使用していますが、

共有サーバで、メール着信の通知を別のアドレスに送る方法です。

 

まず、perlスクリプトを用意します。

はまったポイントがいくつか。
@マークは、ダブルクォーテーション内だと、配列変数として展開されるようです。
シングルクォーテーションで囲うか、エスケープして下さい。

※ 完成後、icloudのメールアドレスに送ると文字化けしました。(gmai yahoo は問題なし)
$subject = jcode($subject)->mime_encode;を追加したら解消しました。(多分)

#!/usr/bin/perl

use Jcode;
use MIME::Words qw(:all);
use POSIX qw(strftime);

$SENDMAIL;
$sendmail_cmd = "/usr/sbin/sendmail -t";

#=====================================================
# DECODEする関数
#=====================================================
sub DecodeFld($) {
    my($sBuff) = @_;
    my($sRes, $sWk);
    chomp($sBuff);
    foreach $sWk (decode_mimewords( $sBuff, )){
        ($sTxt, $sCode) = @$sWk;
        $sRes .= $sTxt;
    }
    return $sRes;
}

#=====================================================
# 本体開始
#=====================================================
$r_subject = '';
$r_mail_to = '';
$r_mail_from = '';
$flg_subject = 0;
$flg_read_end = 0;
$flg_go = 0;

#open(DATAFILE, ">", "log.txt") or die("Error:$!");
#print DATAFILE "開始\n";
#close(DATAFILE);

#ヘッダ部から情報抽出
while (<STDIN>) {

    #ヘッダ情報抽出終了後、パイプを空送りしてSTDINを終了させる
    if($flg_read_end){
        next;
    }

    #ヘッダ部の終了チェック
    if(length == 1){
        $flg_read_end = 1;
        next;
    }

    #Subjectの取得
    if($flg_subject == 1){
        if(/^[ \t](.+)/){
            $r_subject .= $1;
        }
        else{
            $flg_subject = 2;
        }
    }
    elsif($flg_subject == 0 && /^Subject: (.+)/){
        $r_subject = $1;
        $flg_subject = 1;
    }

    #FromやTo、その他フラグの取得
    if(/^From: .*<(.+)>.*/){
        $r_mail_from = $1;
    }
    elsif(/^From: (.+)/){
        $r_mail_from = $1;
    }
    elsif(/^To: .*<(.+)>.*/){
        $r_mail_to = $1;
    }
    elsif(/^To: (.+)/){
        $r_mail_to = $1;
    }
}

#       open(DATAFILE, ">", "log.txt") or die("Error:$!");
#       print DATAFILE "$mail_to\n";
#       print DATAFILE "$subject\n";
#       close(DATAFILE);


#Subjectのデコード
$r_subject = &DecodeFld("$r_subject");  #Subject欄デコード(JISコードのまま)

#       open(DATAFILE, ">>", "log.txt") or die("Error:$!");
#       print DATAFILE "$mail_to\n";
#       print DATAFILE "$subject\n";
#       close(DATAFILE);
#文字コード変換(JIS→EUC)
#&Jcode::convert(\$subject, "euc");

#       open(DATAFILE, ">>", "log.txt") or die("Error:$!");
#       print DATAFILE "$mail_to\n";
#       print DATAFILE "$subject\n";
#       close(DATAFILE);

#通知メール対象チェック
if($r_subject =~ /^\[SPAM\]/){
    $flg_go = 1;
}

#通知メール送信

#open(DATAFILE, ">>", "log.txt") or die("Error:$!");
#print DATAFILE "mail送信前\n";
#close(DATAFILE);

    if($flg_go == 0){

        open(MAIL, "| $sendmail -t") or $err = 1;
        if($err == 0){
                $nowStr =  strftime("%Y_%m_%d_%H_%M_%S", localtime(time));
                $subject =$r_mail_to.'に新着メール'.$nowStr;
                $from = $r_mail_to;
                $to = $ARGV[0];
                $cc = "";

$message =<<__E_O_F__;
$r_mail_from から メールが着信しました。
件名: $r_subject
        このメールは自動送信されています。
__E_O_F__

&Jcode::convert(\$subject, 'jis');
$subject = jcode($subject)->mime_encode;
&Jcode::convert(\$message, "jis");

&Jcode::convert(\$subject, 'jis');
$subject = jcode($subject)->mime_encode;
&Jcode::convert(\$message, "jis");

open($SENDMAIL, "|$sendmail_cmd") or die "$sendmail_cmd [$!]";

$text =<<E_O_M;
From: <$from>
To: $to
Cc: $cc
Subject: $subject
Content-Transfer-Encoding: 7bit
Content-type: text/plain;charset="ISO-2022-JP"

$message
E_O_M

print $SENDMAIL $text;

close($SENDMAIL);

#       open(DATAFILE, ">>", "log.txt") or die("Error:$!");
#       print DATAFILE "mailSent\n";
#       close(DATAFILE);
        }
    }

(※各所にコメントで入っている
# open(DATAFILE, ">>", "log.txt") or die("Error:$!");
# print DATAFILE "XXXXX\n";
# close(DATAFILE);
デバッグ用。ログの出力される場所は、~/ドメイン/mail/ドメイン/メールアドレス のディレクトリ内です。)

で、これをmail_alert2.pl として保存します。
場所は ~/ドメイン名/script ディレクトリに置きます。
chmod 700 で権限を設定してください。 chmod 700 ~/ドメイン名/script/mail_alert2.pl

最後に~/ドメイン名/mail/ドメイン名/メールアドレス  にある、 .mailfilter の最終行に、以下を追加します。

cc "| ../../../script/mail_alert.pl 通知先メールアドレス"

これで無事、文字化けなしで通知メールが送られました。
初めてのPerlでした。

参考アドレス
Xserver、Sixcoreでメール着信通知を設定する方法 | 冨山陽平のブログ “思いきり やりぬく”
http://faq.sakuratan.com/wiki/wiki.cgi?%c3%e5%bf%ae%c4%cc%c3%ce%a5%e1%a1%bc%a5%eb%a5%d7%a5%ed%a5%b0%a5%e9%a5%e0%ce%e3
Perlで日本語のメールを送信する方法

2023-01-13 追記
ちなみにspam 扱いされると、転送されないようです。
テストのメールがspam扱いされてしまい、ダメでした。
迷惑メール設定で、ホワイトリストに追加したら転送されました。

エクセルで 貼り付け時 日付にならないようにする

エクセルにデータを張り付けるときに、

分数や、ハイフンでつながった数字(住所等)を張り付けると、

日付に勝手に変換されてしまうことがあります。

 

これを避けるには、

① 貼り付け先で、日付になってしまう列の書式を文字列にしておく

② 張り付けるときに、右クリックして 貼り付けオプションの[貼り付け先の書式に合わせる] を選択します。

 

これでできます。

Office 365 で 再認証したい

Offce365 で 一度非アクティブ化してもう一度再認証したい場合。

 

アカウントに登録されたデバイス名をすぐに変更したい場合などに有効です。

(コンピュータ名を変更すると、そのうち自動で変更されるそうです。)

 

エクセル等を開いても認証画面が出てこない場合は、

 

時刻を一か月以上先に進めて、エクセルを開きなおすと、認証画面が出てきます。

 

時刻がそのままだと、アカウントにログインできないので、

認証画面がでて、サインインをクリックし、IDを入力する画面になったら、

時刻を正常な時間に戻します。

これで、待つことなく再認証できます。

.NET の DataGridViewが遅すぎる。

何度も苦しんできた、.net の DataGridViewのパフォーマンスですが、

ここで一度パフォーマンスを上げるために(下げないために)必要なことを記録しておきます。

 

プロパティ

 ColumnHeaderHeightSIzeMode

    RowHeadersWidthSizeMode

 

の二つは、「絶対にAuto」にしてはいけません。

この二つでパフォーマンスは激落ちです。3秒→ 5分くらい。

 

後は、DataSource にDataTableを突っ込むときは、

一度Visible = False にしたほうが速いような気がします。

Visible = False で処理できる部分は、なるべくDataGridView.Visible = False で

処理を行います。

 

列幅、行高さの調整は、うまくいかなければ、自前で作ったほうがいいです。

DataGridViewのプロパティやメソッドは、visible との兼ね合い、別のプロパティ変更の順番とか、結構色々なところに依存していて、うまくいかないことが多いです。

 

ちゃんとしてあげれば、

3000行を超えるデータも1秒くらいで表示できたりします。

VB.NET OleDbDataAdapter.Fill で DataTable が Nothing になることがある。

MDBにOleDbDataAdapter で sql を発行して DataTable を取得しています。

 

レコード件数がなければ、Table.Rows.Count = 0 になります。

ということで、

Dim Table  As DataTable = GetTable("select * from MasterTable1;") 

For i as Integer = 0 to Table.Rows.Count -1

    MessageBox.Show(Table.Rows(i)(0))

Next

 

のようなコードを書いているのですが、

 

時折原因のわからないエラーが起きていました。

調べてみると、

  Table に OleDbDataAdapter.Fill したときに、

Table がNothing になることがあるのです。

データが取得できずに空になっているのですが・・・。

そうなると、Table.Rows.Count のところで例外が飛びます。

 

原因として考えられるのは、LANケーブルの中途半端な損傷等の、ネットワークの物理的な問題。もしくは、ネットワーク構成の問題か。。。

現象の多発するPCのLANケーブルはつぶれており、中途半端な損傷が発生していた可能性が高いです。

 

といことで、

Dim Table  As DataTable = GetTable("select * from MasterTable1;") 

If Not Table Is Nothing Then

   For i as Integer = 0 to Table.Rows.Count -1

      MessageBox.Show(Table.Rows(i)(0))

   Next

End If

 のようにすれば、例外は出なくなります。

 

 

Chronyd 同期できない CentOS7

Chronyd で同期できない現象が起こっていましたが。

セグメント3つを許可していたのですが、一行で設定してはだめっだったようです。

allow 192.168.1.0/24

allow 192.168.2.0/24

allow 192.168.3.0/24

のように、3行にわけたらできました。

ちなみに、allow 192.168.1.0/24 192.168.2.0/24 192.168.3.0/24 と書いた場合は、

一番最初の 192.168.1.0/24 だけ許可されるようです。

Base64の肝

Base64はShift -JISなどの文字列を、US-ASCII で表現するための符号化方式です。

US-ASCII は64文字で構成されています。

元のShift-JISをビット列に変換してつなげ、6ビットずつに区切りなおすと、

64文字で表現可能になります。 (2の6乗は64)