<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>igreks開発日記</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/" />
    <link rel="self" type="application/atom+xml" href="http://www.igreks.jp/dev/atom.xml" />
    <id>tag:www.igreks.jp,2008-11-14:/dev//1</id>
    <updated>2010-07-29T07:11:31Z</updated>
    <subtitle>サーバ構築、WEBプログラミング、アフィリエイト、その他試行錯誤の履歴</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 4.22-ja</generator>

<entry>
    <title>getElementByIdの引数文字列を「&quot;」でくくるとバグる</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/07/getelementbyid.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.1774</id>

    <published>2010-07-29T06:58:47Z</published>
    <updated>2010-07-29T07:11:31Z</updated>

    <summary>テキストエリア挿入支援処理などを行うjavascriptの処理時に発見したこと。...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="HTML" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[テキストエリア挿入支援処理などを行うjavascriptの処理時に発見したこと。<br />
<br />
Vista+IE8の環境で「getElementById("moji")」とかやるとなぜかエラーになる。<br />
<br />
内容は「オブジェクトがありません」とのこと。<br />
<br />
<br />
無いわけない。<br />
<br />
ちゃんとid属性もname属性も指定して、値も一緒にしている。<br />
<br />
<br />
ためしに、<br />
<br />
getElementById(moji)<br />
<br />
とやったら、「'moji'は定義されていません」というエラー。<br />
まあ、当たり前だわな。<br />
<br />
しかし、<br />
<br />
getElementById('moji')<br />
<br />
とやると、うまくいく。<br />
<br />
<br />
IE7の時はこのエラーが出なかったような記憶がアルのだが・・・<br />
<br />
協調性を無視し我が道をいくMicrosoftに感謝。<br />
<br />
<br />
しかし何回も何回もソースを見直してたのがバカみたいだ。<br />
<br />
<br />
最近はどの言語でも"moji"と書いたら文字列で処理するだろが。普通は。<br />
]]>
        
    </content>
</entry>

<entry>
    <title>標準出力(STDOUT)を切る際の注意</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/07/stdout.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.1713</id>

    <published>2010-07-22T05:03:36Z</published>
    <updated>2010-07-29T06:58:32Z</updated>

    <summary>子プロセスに処理を渡して、親プロセスで標準出力を切るとき、 my $pid; i...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="apache" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="メール配信" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[子プロセスに処理を渡して、親プロセスで標準出力を切るとき、<br />
<br />
my $pid;<br />
if($pid = fork){<br />
　#親の処理<br />
　close (STDOUT);<br />
　wait;<br />
}<br />
elsif(defined $pid){<br />
　close (STDOUT);<br />
　#子の処理<br />
}<br />
　・<br />
　・<br />
　・<br />
<br />
<br />
みたいな感じで今までOKだったのだが、ロリポップ系サーバなどではこれがうまく行かない。ブラウザの出力自体は切れるのだが、子プロセスの処理を行ってくれない。<br />
<br />
WEBサーバによって変わると聞いたことがあるので、ググってみたところ、標準出力を切る部分を、<br />
<br />
close (STDOUT);<br />
close (STDERR);<br />
close (STDIN);<br />
<br />
とやったら上手く行った。<br />
<br />
apache2.0系（うちの環境）とapache1.3系（ロリポップ系？）でどうやら違うらしい。<br />
<br />
ちなみに、上記3つの順番が違っても1つ足りなくてもダメだった。<br />
<br />
close (STDIN);<br />
close (STDOUT);<br />
close (STDERR);<br />
<br />
↑これだとなぜか子プロセスが終了するまでブラウザが開放されない<br />
<br />
<br />
close (STDOUT);<br />
close (STDERR);<br />
close (STDIN);<br />
<br />
↑この順番じゃないとダメみたい。<br />
<br />
STDOUTだけだと、新しいapacheのときダメだよって聞いていたので、それとは逆の現象だが、解決したからまあいいか。]]>
        
    </content>
</entry>

<entry>
    <title>Postfix＋Perlで携帯空メール登録処理</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/06/postfixperl.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.1524</id>

    <published>2010-06-30T11:20:54Z</published>
    <updated>2010-07-22T05:03:19Z</updated>

    <summary>私はDocomoの携帯しか持ってないので、事前にauとsoftbankを持ってる...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="MySQL" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Post Fix" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="サーバ構築" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="メール配信" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[私はDocomoの携帯しか持ってないので、事前にauとsoftbankを持ってる友人に頼んで、メールヘッダなどを調査したらこんな感じ↓<br />
<br />
■　Docomo<br />
----------------------------------------------------------------------------------<br />
From ****@docomo.ne.jp  Wed May 26 17:54:11 2010<br />
Return-Path: <****@docomo.ne.jp><br />
X-Original-To: ***@igreks.jp<br />
Delivered-To: ***@igreks.jp<br />
Received: from localhost (localhost.localdomain [127.0.0.1])<br />
	by ***.igreks.jp (Postfix) with ESMTP id 5DE338B41B2<br />
	for <***@igreks.jp>; Wed, 26 May 2010 17:54:11 +0900 (JST)<br />
X-Virus-Scanned: amavisd-new at igreks.jp<br />
Received: from ***.igreks.jp ([127.0.0.1])<br />
	by localhost (igreks.jp [127.0.0.1]) (amavisd-new, port ****)<br />
	with ESMTP id kkpANBxiUasa for <****@igreks.jp>;<br />
	Wed, 26 May 2010 17:54:11 +0900 (JST)<br />
Received: from docomo.ne.jp (mail108.docomo.ne.jp [203.138.203.8])<br />
	by ***.igreks.jp (Postfix) with ESMTP id 3E6618B40B0<br />
	for <***@igreks.jp>; Wed, 26 May 2010 17:54:11 +0900 (JST)<br />
Date: Wed, 26 May 2010 17:54:09 +0900 (JST)<br />
From: ****@docomo.ne.jp<br />
To: ***@igreks.jp<br />
Subject: =?iso-2022-jp?B?GyRCMSsbKEI=?=<br />
Message-ID: <IMTa1-aH1323eedd0daQ@docomo.ne.jp><br />
MIME-Version: 1.0<br />
Content-Type: text/plain; charset="iso-2022-jp"<br />
Content-Transfer-Encoding: 7bit<br />
<br />
$BK\J8(B<br />
----------------------------------------------------------------------------------<br />
<br />
<br />
■　au<br />
----------------------------------------------------------------------------------<br />
From ****@ezweb.ne.jp  Wed May 26 18:24:29 2010<br />
Return-Path: <****@ezweb.ne.jp><br />
X-Original-To: ***@igreks.jp<br />
Delivered-To: ***@igreks.jp<br />
Received: from localhost (localhost.localdomain [127.0.0.1])<br />
	by ***.igreks.jp (Postfix) with ESMTP id F1F818B41B2<br />
	for <***@igreks.jp>; Wed, 26 May 2010 18:24:28 +0900 (JST)<br />
X-Virus-Scanned: amavisd-new at igreks.jp<br />
Received: from ***.igreks.jp ([127.0.0.1])<br />
	by localhost (igreks.jp [127.0.0.1]) (amavisd-new, port ****)<br />
	with ESMTP id CBSY6-Rv+mf6 for <***@igreks.jp>;<br />
	Wed, 26 May 2010 18:24:28 +0900 (JST)<br />
Received: from ezweb.ne.jp (nx3oBP07-06.ezweb.ne.jp [59.135.39.240])<br />
	by ***.igreks.jp (Postfix) with ESMTP id D7FC88B40B0<br />
	for <***@igreks.jp>; Wed, 26 May 2010 18:24:28 +0900 (JST)<br />
Received: from nxev04mp06 (localhost [127.0.0.1])<br />
	by nxev04mp06.ezweb.ne.jp (EZweb Mail) with SMTP id 955ED5BC640B4<br />
	for <***@igreks.jp>; Wed, 26 May 2010 18:24:28 +0900 (JST)<br />
From: ****@ezweb.ne.jp<br />
To: ***@igreks.jp<br />
Subject: =?iso-2022-jp?B?GyRCMSsbKEI=?=<br />
Message-ID: <2010052618242860697200007c12@nxev04mp06.ezweb.ne.jp><br />
Date: Wed, 26 May 2010 18:24:28 +0900<br />
Mime-Version: 1.0<br />
Content-Type: text/plain; charset="iso-2022-jp"<br />
Content-Transfer-Encoding: 7bit<br />
<br />
$B%6!<%6!<(B<br />
----------------------------------------------------------------------------------<br />
<br />
<br />
■　Softbank<br />
----------------------------------------------------------------------------------<br />
From ****@softbank.ne.jp  Wed May 26 18:24:36 2010<br />
Return-Path: <****@softbank.ne.jp><br />
X-Original-To: ***@igreks.jp<br />
Delivered-To: ***@igreks.jp<br />
Received: from localhost (localhost.localdomain [127.0.0.1])<br />
	by ***.igreks.jp (Postfix) with ESMTP id 975BD8B41B2<br />
	for <***@igreks.jp>; Wed, 26 May 2010 18:24:36 +0900 (JST)<br />
X-Virus-Scanned: amavisd-new at igreks.jp<br />
Received: from ***.igreks.jp ([127.0.0.1])<br />
	by localhost (igreks.jp [127.0.0.1]) (amavisd-new, port ****)<br />
	with ESMTP id HQrmiDMGcT3n for <***@igreks.jp>;<br />
	Wed, 26 May 2010 18:24:36 +0900 (JST)<br />
Received: from mmrts049p01c.softbank.ne.jp (mmrts049p01c.softbank.ne.jp [123.108.236.27])<br />
	by ***.igreks.jp (Postfix) with SMTP id 6D9898B40B0<br />
	for <***@igreks.jp>; Wed, 26 May 2010 18:24:36 +0900 (JST)<br />
Subject: =?ISO-2022-JP?B?GyRCJCYkcyQzGyhC?=<br />
Mime-Version: 1.0<br />
Content-Type:text/plain;charset=ISO-2022-JP<br />
Content-Transfer-Encoding:7bit<br />
Date: Wed, 26 May 2010 18:24:35 +0900<br />
Message-ID: <20100526182435672870.2aea@0016E68F5982><br />
From: <****@softbank.ne.jp><br />
To: ***@igreks.jp<br />
Sender:****@softbank.ne.jp<br />
X-Priority: 3<br />
<br />
$B%b%j%b%j(B<br />
----------------------------------------------------------------------------------<br />
<br />
<br />
仕様としては、<br />
<br />
・DBはMySQL<br />
・空メの送信先は「reg_kara_mail@igreks.jp」とする<br />
・空メの件名に名前を指定できる。<br />
・登録済みの場合はエラーメールを返す。<br />
・空メ本文にメルマガIDをあらかじめ記載しておく。<br />
・メルマガIDが認識できない場合もエラーメールを返す。<br />
・読者データテーブル名は仮に「user_'メルマガID'」、文字コードはUTF8とする。<br />
<br />
これを受けて、スクリプトはざっとこんな感じに。<br />
※おおまかな流れだけで、細かい点は割愛してます<br />
<br />
<br />
■　空メール登録処理用CGI（karame.cgi）<br />
-----------------------------------------------------------------------------------<br />
#!/usr/bin/perl<br />
<br />
package main;<br />
<br />
use strict;<br />
use CGI;<br />
use DBI;<br />
use Unicode::Japanese;<br />
<br />
require './lib/get.pl';　#各種データ取得用ライブラリ（詳細割愛）<br />
require './lib/proc.pl';　#各種処理用ライブラリ（詳細割愛）<br />
require './lib/db.pl';　#DB接続、各種SQL実行用ライブラリ（詳細割愛）<br />
require './lib/start.pl';　#メール配信用ライブラリ（詳細割愛）<br />
<br />
&db::open();　#DB接続<br />
<br />
my $sys_msg = '';　#エラー返信用メッセージ<br />
my ($email, $name, $id);<br />
<br />
######　メールから標準入力をパース<br />
my $grep = '[\d\w-.+]+\@[\d\w-]+(\.[\d\w-]+)+';　#メールアドレスの正規表現<br />
<br />
while(<>){<br />
　if($_ =~ /^From.*?($grep)/i || $_ =~ /^Return-Path:.*?&lt;($grep)&gt;/i){<br />
　　$email = $1;　#メールアドレス<br />
　}<br />
　if($_ =~ /^Subject:\s*(.+)$/i){<br />
　　$name  .= $1;　#名前<br />
　}<br />
　if($_ =~ /^\s*(=\?ISO-2022-JP.+\?=)\s*$/i){　#件名が途中で改行されてる時のため<br />
　　$name  .= $1;<br />
　}<br />
　if($_ =~ /^mid:(.+)$/){<br />
　　$id    = $1;　#メルマガID<br />
　}<br />
}<br />
if($email){<br />
　if($id){<br />
　　my $stg = &get::setting_data($id);　#メルマガ設定データ取得<br />
　　if($stg){<br />
　　####### 読者テーブル内重複チェック<br />
　　&db::query("<br />
　　　SELECT * FROM user_$id WHERE email='$email'<br />
　　");<br />
　　my $href = $db::sth-&gt;fetchrow_hashref();<br />
　　if($href){<br />
　　　#すでに登録済みの場合<br />
　　　$sys_msg = &lt;&lt;EOM;<br />
　　　　送信いただいたメールアドレス「$email」はすでに登録済みです。<br />
　　　　このまま次回の配信をお待ちください。			<br />
EOM<br />
　　　$sys_msg =~ s/\t//g;<br />
　　　#メール返信処理<br />
　　　&start::return_mail(<br />
　　　　'空メール登録処理エラー',<br />
　　　　$sys_msg,<br />
　　　);<br />
　　　exit;<br />
　　}<br />
　　if($name){<br />
　　　#名前の入力があった場合<br />
　　　$name = Unicode::Japanese-&gt;new(<br />
　　　　&proc::base64decode($name),　#Base64デコード処理<br />
　　　　'jis'<br />
　　　)-&gt;utf8;　#JISからUTF8に変換<br />
　　}<br />
　　######## 新規登録<br />
　　&db::query("<br />
　　　INSERT IGNORE INTO user_$$pd{'id'} (<br />
　　　　no,　　#オートインクリメント<br />
　　　　email,<br />
　　　　name,<br />
　　　　・<br />
　　　　・<br />
　　　　・<br />
　　　)<br />
　　　VALUES(<br />
　　　　'',<br />
　　　　'$email',<br />
　　　　'$name',<br />
　　　　・<br />
　　　　・<br />
　　　　・<br />
　　　)<br />
　　");<br />
　}<br />
　else{<br />
　　$sys_msg = &lt;&lt;EOM;<br />
　　　登録しようとしたメールマガジンは存在しないか、すでに廃刊されています。<br />
　　　お手数ですが、詳しくは発行者までお問い合わせください。<br />
EOM<br />
　}<br />
}<br />
else{<br />
　$sys_msg = &lt;&lt;EOM;<br />
　　送信いただいた情報に不備があり登録できませんでした。<br />
　　空メール本文の内容は変更せずに送信してください。<br />
　　何度もこのエラーメールが返信される場合は、お手数ですが発行者までお問い合わせください。<br />
EOM<br />
}<br />
<br />
########## エラー返信処理<br />
if($sys_msg){<br />
　&start::return_mail(<br />
　　'空メール登録処理エラー',<br />
　　$sys_msg,<br />
　);<br />
}<br />
&db::close();　#DB切断<br />
<br />
exit;<br />
<br />
-----------------------------------------------------------------------------------<br />
<br />
<br />
<br />
■Postfixエイリアス設定ファイル（/etc/aliase）に以下を追加<br />
-----------------------------------------------------------------------------------<br />
reg_kara_mail:　　"|cd 'karame.cgiがあるディレクトリの絶対パス'; ./karame.cgi"<br />
-----------------------------------------------------------------------------------<br />
<br />
■リスタート<br />
-----------------------------------------------------------------------------------<br />
# newaliases<br />
<br />
# /etc/init.d/postfix restart<br />
-----------------------------------------------------------------------------------<br />
<br />
<br />
■以下のようなメールを「reg_kara_mail@igreks.jp」宛に送る<br />
<br />
　件名：自分の名前もしくは空白<br />
　本文：mid:melmagaID<br />
<br />
以上。<br />
<br />
<br />
※レンタルサーバなどでエイリアスが設定できない場合は、後からcronなどでPOPアクセスして処理するなどの方法もある。（参考→<a href="http://www.igreks.jp/dev/2009/06/pop.html">http://www.igreks.jp/dev/2009/06/pop.html</a>）<br />
この場合は返信メールが即時配信されない。<br />
<br />
<br />
※ディズニーモバイルとかwilcomは調べてないけど、まあだいたい同じだべってことで。<br />
]]>
        
    </content>
</entry>

<entry>
    <title>自力base64エンコードとデコード</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/06/base64.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.1523</id>

    <published>2010-06-30T11:11:18Z</published>
    <updated>2010-06-30T13:42:45Z</updated>

    <summary>メールの件名だけのためにMIME::Base64とか使いたくないなーと思ったので...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="メール配信" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[メールの件名だけのためにMIME::Base64とか使いたくないなーと思ったので。<br />
<br />
ほぼ、こちら（<a href="http://nabe.blog.abk.nu/064">http://nabe.blog.abk.nu/064</a>）の丸写しでごめんなさい。<br />
<br />
<br />
-----------------------------------------------------------------------<br />
<br />
#エンコード<br />
<br />
my $subject1 = &base64_Encode($target1);<br />
<br />
#デコード<br />
<br />
my $subject2 = &base64_Decode($target2);<br />
<br />
<br />
<br />
sub base64_Encode {<br />
	my ($target) = @_;<br />
	my ($base) = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"<br />
					."abcdefghijklmnopqrstuvwxyz"<br />
					."0123456789+/";<br />
	my $eStr = "";<br />
	my $pStr = unpack("B*",$target);<br />
	for(my $i = 0;my $cStr = substr($pStr,$i,6); $i += 6){<br />
		$eStr .= substr($base,ord(pack("B*","00".$cStr)),1);<br />
		if(length($cStr) == 2){<br />
			$eStr .= "==";<br />
		}<br />
		elsif(length($cStr) == 4){<br />
			$eStr .= "=";<br />
		}<br />
 	}<br />
	return("=?ISO-2022-JP?B?$eStr?=");<br />
}<br />
<br />
sub base64_Decode {<br />
	my ($str)  = @_;<br />
	$str =~ s/=\?ISO-2022-JP\?B\?([A-Za-z0-9\+\/=]*)\?=/{&base64_Decode2($1)}/egi;<br />
	return $str;<br />
}<br />
sub base64_Decode2 {<br />
	my ($str) = @_;<br />
	my @base64ary = (<br />
		 0, 0, 0, 0,  0, 0, 0, 0,   0, 0, 0, 0,  0, 0, 0, 0,	# 0x00〜0x1f<br />
		 0, 0, 0, 0,  0, 0, 0, 0,   0, 0, 0, 0,  0, 0, 0, 0,	# 0x10〜0x1f<br />
		 0, 0, 0, 0,  0, 0, 0, 0,   0, 0, 0,62,  0, 0, 0,63,	# 0x20〜0x2f<br />
		52,53,54,55, 56,57,58,59,  60,61, 0, 0,  0, 0, 0, 0,	# 0x30〜0x3f<br />
		 0, 0, 1, 2,  3, 4, 5, 6,   7, 8, 9,10, 11,12,13,14,	# 0x40〜0x4f<br />
		15,16,17,18, 19,20,21,22,  23,24,25, 0,  0, 0, 0, 0,	# 0x50〜0x5f<br />
		 0,26,27,28, 29,30,31,32,  33,34,35,36, 37,38,39,40,	# 0x60〜0x6f<br />
		41,42,43,44, 45,46,47,48,  49,50,51, 0,  0, 0, 0, 0	# 0x70〜0x7f<br />
	);<br />
	my $ret;<br />
	my $buf;<br />
	my $f;<br />
	if (substr($str, -1) eq  '=') { $f=1; }<br />
	if (substr($str, -2) eq '==') { $f=2; }<br />
	for(my $i=0; $i&lt;length($str); $i+=4){<br />
		$buf  = ($buf&lt;&lt;6) + $base64ary[ ord(substr($str,$i  ,1)) ];<br />
		$buf  = ($buf&lt;&lt;6) + $base64ary[ ord(substr($str,$i+1,1)) ];<br />
		$buf  = ($buf&lt;&lt;6) + $base64ary[ ord(substr($str,$i+2,1)) ];<br />
		$buf  = ($buf&lt;&lt;6) + $base64ary[ ord(substr($str,$i+3,1)) ];<br />
		$ret .= chr(($buf & 0xff0000)&gt;&gt;16) . chr(($buf & 0xff00)&gt;&gt;8) . chr($buf & 0xff);<br />
	}<br />
	if ($f&gt;0) { chop($ret); }<br />
	if ($f&gt;1) { chop($ret); }<br />
	return $ret;<br />
}<br />
<br />
-----------------------------------------------------------------------<br />
]]>
        
    </content>
</entry>

<entry>
    <title>forkした子プロセス内でも親プロセスと同じMySQLコネクションを使う方法</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/06/forkmysql.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.1522</id>

    <published>2010-06-30T10:29:09Z</published>
    <updated>2010-07-23T05:39:23Z</updated>

    <summary>結論から言うと、親プロセスの「wait;」の直後にもう一度MySQL接続処理を呼...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="MySQL" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[結論から言うと、親プロセスの「wait;」の直後にもう一度MySQL接続処理を呼ぶ。<br />
※2010/7/23追記：さらに各プロセスの頭でMySQL接続処理を呼ぶ。<br />
ただそれだけ。<br />
<br />
<br />
■MySQL接続用（db.pl）<br />
--------------------------------------------------------------------------<br />
package db;<br />
<br />
use strict;<br />
<br />
sub open{<br />
	my $dbs = "DBI:mysql:$dbname:$dbhost";<br />
	our $dbh = DBI->connect($dbs,$dbuser,$dbpass);<br />
	if(!$dbh){	die 'MySQL connection error!'; }<br />
}<br />
<br />
sub query{<br />
	my ($sql) = @_;<br />
	our $sth = $db::dbh->prepare($sql) || die $db::dbh->errstr();<br />
	my $exec = $sth->execute() || die $sth->errstr();<br />
	return $exec;<br />
}<br />
<br />
sub close{<br />
	$db::sth->finish();<br />
	$db::dbh->disconnect();<br />
}<br />
<br />
1;<br />
--------------------------------------------------------------------------<br />
<br />
<br />
■よくあるforkの処理<br />
--------------------------------------------------------------------------<br />
#!/usr/bin/perl<br />
<br />
use strict;<br />
use DBI;<br />
<br />
require 'db.pl';　########　上のファイル読み込み<br />
&db::open();　#########　最初のMySQL接続<br />
<br />
（親プロセス処理）<br />
<br />
my $pid;<br />
FORK: {<br />
　if($pid = fork) {<br />
　　&db::open();　######　←【ここで単発接続】<br />
　　（親プロセス処理）<br />
<br />
　　close(STDOUT);<br />
　　wait;<br />
　　&db::open();　　######　←【ここで再接続】これはfork終了後の処理用<br />
　}<br />
　elsif (defined $pid) {<br />
　　&db::open();　######　←【ここで単発接続】<br />
　　close(STDOUT);<br />
<br />
　　（子プロセス処理）<br />
<br />
　　exitしなくても勝手にexitされる？<br />
　}<br />
　elsif($! =~ /No more process/){<br />
　　sleep 5;<br />
　　redo FORK;<br />
　}<br />
　else{<br />
　　die 'Fork is not supported!';<br />
　}<br />
} # End Of Label:FORK<br />
<br />
<br />
（親プロセス処理再開）<br />
<br />
&db::close();　#########　正規のMySQL接続切断<br />
exit;<br />
--------------------------------------------------------------------------<br />
<br />
<br />
<br />
今まで、子プロセス内処理が終われば、全体の処理も終わるような構造のスクリプトばっかりだったので、なかなか気づかなかった。<br />
ログも「mysql server has gone away...」ってしか出ないし。<br />
標準出力を切ってるからブラウザからのデバックだけだと気がつかず、メルマガの空メール処理実装しようとして初めて気がついた。<br />
<br />
一般的には、子プロセス内に入ったら、改めて子プロセス専用のコネクションを作らないと、子プロセスの終了時にMySQLコネクションが切断されてしまうらしい。<br />
（つまり、親と同じコネクションを使っていると、親のコネクションも切れる）<br />
全然しらんかった。<br />
<br />
<br />
でも、なぜか子プロセスの最初で「&db::open();」してもダメだった。<br />
perlのforkは親の変数が子に全部コピーされるから（同じデータベースハンドル、またはステートメントハンドルを使っている）なのかな？<br />
<br />
<br />
わざわざ、子プロセス専用のSQL発行サブルーチン作るのも非効率だし、どうしようかなと悩んだ挙句こうなった。<br />
<br />
<br />
時々、MilkyStepで即時配信メールが送れなくなるのはコレのせいだったりして。<br />
<br />
<br />
※2010/7/23追記：<br />
子プロセスの処理中に親プロセスが終了しても、子プロセスのMySQL接続が切れる。<br />
また、親が終了する前に子のプロセスIDを使い始めると親のMySQL接続が切れる。<br />
原因はよくわからんが、親・子それぞれの頭で接続処理を単発で入れたら上手く行った。<br />
]]>
        
    </content>
</entry>

<entry>
    <title>またclamavエラー関係のcronログ</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/06/clamavcron.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.1389</id>

    <published>2010-06-15T06:11:33Z</published>
    <updated>2010-06-30T10:28:56Z</updated>

    <summary>clamav0.96をインストールした先々月くらいから、毎日のclamav起動時...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="サーバ構築" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[clamav0.96をインストールした先々月くらいから、毎日のclamav起動時にいっぱいエラーが出てた。<br />
<br />
最初は面倒くさいので無視してたが、cronのこのメールのせいでサンダーバードまで重くなってきたので何とかしてみよう。<br />
<br />
<br />
LibClamAV Warning: cli_scanbzip: bzip2 support not compiled in　とか<br />
LibClamAV Warning: pread fail: page 0 pages 1...　とか<br />
なんかいっぱい出てるので、まず最初の行から。<br />
<br />
えー、bzipがサポートされてませんよと・・・<br />
<br />
じゃあインストールすればいいんだべってことで<br />
<br />
# yum install bzip2<br />
<br />
しかし、<br />
<br />
# すでにインストール済みです・・・<br />
<br />
<br />
<br />
というわけで、ここはあきらめて（早っ）clamavのconfigure,make,make installだけしなおして次へ。<br />
<br />
<br />
pread fail のエラーの情報はググると見つかるものの、とりあえずみんなpread処理を回避して対処してるみたいなので、私もそうしよう。<br />
<br />
というわけで、「/etc/cron.daily/clamav」を以下の用に変更。<br />
<br />
-----------------------------------------------------------------------------------------------------------<br />
/usr/bin/clamscan -r --quiet --log=/var/log/clamav.log --move=/var/infected_virus/<br />
<br />
　　　↓<br />
<br />
/usr/bin/clamscan --exclude-dir=/sys -r --quiet --log=/var/log/clamav.log --move=/var/infected_virus/<br />
-----------------------------------------------------------------------------------------------------------<br />
<br />
<br />
<br />
では、明日起きてからのお楽しみ。<br />
]]>
        
    </content>
</entry>

<entry>
    <title>clamavの影響である日突然メールが配信されなくなるの巻</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/04/clamav.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.892</id>

    <published>2010-04-19T12:08:31Z</published>
    <updated>2010-04-20T12:25:38Z</updated>

    <summary>毎日決まった時刻に送られてくる自動メルマガがなぜか今日は送られてこない。 おかし...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Post Fix" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="サーバ構築" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="メール配信" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[毎日決まった時刻に送られてくる自動メルマガがなぜか今日は送られてこない。<br />
<br />
おかしいなと思いつつもこういうときに限って日曜日で出かけたりしてる。<br />
<br />
<br />
帰ってからサーバをチェックしてみるとなんと配送されてないキュー（deferedにたまりっぱなし）が約7000件・・・。<br />
<br />
<br />
maillogをチェックしようにもどうやらログが膨大になりすぎてなかなか問題の部分が表示されない・・・<br />
<br />
ようやく確認できたのが、<br />
<br />
LibClamAV Warning: ***********************************************************<br />
LibClamAV Warning: ***  This version of the ClamAV engine is outdated.     ***<br />
LibClamAV Warning: *** DON'T PANIC! Read <a href="http://www.clamav.net/support/faq">http://www.clamav.net/support/faq</a> ***<br />
LibClamAV Warning: ***********************************************************<br />
LibClamAV Error: cli_hex2str(): Malformed hexstring: This ClamAV version has reached End of Life! Please upgrade to version 0.95 or later. For more information see  www.clamav.net/eol-clamav-094 and www.clamav.net/download (length: 169)<br />
LibClamAV Error: Problem parsing database at line 742<br />
LibClamAV Error: Can't load daily.ndb: Malformed database<br />
LibClamAV Error: cli_tgzload: Can't load daily.ndb<br />
LibClamAV Error: Can't load /usr/XXXXXX/clamav/daily.cld: Malformed database<br />
ERROR: Malformed database<br />
<br />
とゆー部分。<br />
<br />
<br />
最初の4行はいつものことなのでいいんだが、その後になんか見慣れないエラーが。<br />
<br />
ここに気づくまでにかなりハマってしまい、amavisの設定ファイルやclamavの設定ファイルをいろいろいじくってみたり、パッケージをインストールしなおしてみたりしてもさっぱり変わらず、ようやくこちらのサイト<br />
→<a href="http://homepage.mac.com/yuji_okamura/iSawIt/archives/2010/04/entry_2452.html">http://homepage.mac.com/yuji_okamura/iSawIt/archives/2010/04/entry_2452.html</a><br />
のおかげで原因ぽいのがわかりました。<br />
<br />
つまり簡単に言うと、clamavのバージョンを0.95以上にしないと、ついにファイルのスキャンができなくなりましたってゆーことらしい。<br />
<br />
たしかにmaillogの他の部分を見てみると、「clamavのソケットに接続できなくてウイルススキャンに失敗しました」→「配送に失敗しました」みたいな流れがずらっと続いている。<br />
（でもRPMで定期的に更新してんのはamavisの方なんだから、フツーは最初にamavisの方を疑うよなぁ・・・）<br />
<br />
<br />
ほんでもって例のごとく、clamavの最新パッケージはyumから引っ張れないので以下を参考に、最新版のソースをダウンロードしてアップデートをしたわけです。<br />
<br />
<a href="http://d.hatena.ne.jp/ooolong/20080102/1199294335">http://d.hatena.ne.jp/ooolong/20080102/1199294335</a><br />
<a href="http://yokensaka.com/fedora/index.php?itemid=158">http://yokensaka.com/fedora/index.php?itemid=158</a><br />
<br />
一個目のリンクはどうやら2個目のリンクの対処法を元に書いてあるみたいなんだけど、「yumのclamavパッケージ（依存も含む）を削除しておく」ってゆーのがウチの環境ではいけなかったみたいですね。<br />
yumで削除したらinit.dのリストまでいじくられるわけで、デーモン（サービス）一覧からamavisデーモンまで無くなってしまったわけで・・・<br />
<br />
ほんなわけで、再度yumからamavis-new、clamav、clamav-serverなどなど依存関係も含めてまるごとインストールしなおしてinit.dを元に戻した状態で、clamavの最新ソースを入れ直し（configure→make→make install）たらうまく行ったのです。<br />
<br />
<br />
以上の作業が終わった時点から、溜まってたキューがどんどん送信され始めました。<br />
<br />
<br />
ただ、GUIでサービス一覧を確認すると、amavisdは復活したけど今まであったclam.amavisdは復活しない。<br />
<br />
でもコマンドで、<br />
-----------------------------------<br />
<br />
chkconfig --list<br />
<br />
-----------------------------------<br />
で確認すると、デーモン一覧にclamd.amavisdが入っている。<br />
どうやらGUIにはパッケージでインストールしたものしか反映されないっぽい。<br />
<br />
とりあえず、起動してみる。<br />
-------------------------------------<br />
<br />
/etc/init.d/clamd.amavisd start<br />
<br />
------------------------------------<br />
<br />
<br />
よし！起動成功！<br />
ついでにランレベル3から5をONにする。<br />
<br />
----------------------------------------<br />
<br />
chkconfig clamd.amavisd on<br />
<br />
---------------------------------------<br />
<br />
<br />
デーモンを起動するとmaillogで騒いでた、「clamd.sock」が「/var/spool/amavisd」の中に出現。<br />
<br />
これで「clamd.sockが見つかりません」というエラーが解決でき、点と点がつながったわけだ。<br />
<br />
あ、そうそう、freshclamの定期実行もデフォルトに戻ってしまうみたいなので、<br />
「/etc/sysconfig/freshclam」を開いて、最後の行をコメントアウトする。<br />
<br />
-----------------------------------------------------------------------<br />
<br />
FRESHCLAM_DELAY=disabled-warn	# REMOVE ME<br />
　　　　　↓<br />
#FRESHCLAM_DELAY=disabled-warn	# REMOVE ME<br />
<br />
----------------------------------------------------------------------<br />
<br />
<br />
しかしclamavのおかげで費やした労力は今までも計りしれず、これからもこんな感じでやんなきゃなんねーのかと思うと、他のアンチウィルスソフトを使いたくなってしまうのは私だけではないはず。<br />
<br />
<br />
<br />
]]>
        
    </content>
</entry>

<entry>
    <title>バウンスメールのオートリプレイ（自動返信）メールを自動的に処理する</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/04/post-6.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.759</id>

    <published>2010-04-01T06:42:43Z</published>
    <updated>2010-04-19T12:08:16Z</updated>

    <summary>メルマガを発行していて部数が増えてくるとよくあるのが、宛先からの自動返信。 「勝...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="メール配信" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[メルマガを発行していて部数が増えてくるとよくあるのが、宛先からの自動返信。<br />
<br />
「勝手に送ってくんなボケ」とか<br />
「Re:クソスパマーへ返信します。」<br />
<br />
とかいろいろ。<br />
<br />
あと最近多いのが、<br />
「いつも、メルマガ、楽しみに拝見しています。<br />
実は、今回、メルマガ発行者さんに伝えたいことがあってメールしました。<br />
　・<br />
　・<br />
　・<br />
このシステムで毎月、収入を得ています。<br />
何もできない私でできるのですから、こんな素晴らしいメルマガを<br />
書かれる方なら、きっとできることでしょう。<br />
一度、下記のホームページをご覧になって下さい。<br />
→URL」<br />
<br />
といった、稼げる系の情報商材を自動返信で売り込んでくるメール。<br />
<br />
だいたい送信元はgooメールかGメールのどちらか。<br />
<br />
もちろん私は同意を得ていないメールアドレスをメルマガに勝手に登録したりしませんから、ボケとかクソとかは完全に向こう側のおかどちがいなのですが、さすがに毎回ボケとかクソとか言われるのは腹が立つ。<br />
<br />
過去記事（<a href="http://www.igreks.jp/dev/2009/06/pop.html">http://www.igreks.jp/dev/2009/06/pop.html</a>）で書いたPOPアクセスを用いてメルマガなどのエラーアドレスを自動で処理できる。<br />
<br />
しかし、このやり方だけだと自動返信メールが処理できない。<br />
なぜなら故意に設定された自動返信メールは、本文中にFROMとかTOとかSMTPサーバの返すメッセージが書いてないから。<br />
つまり、フツーのメールを装って送信されてくる。<br />
<br />
なので、前回のスクリプトを改良して自動返信メールにも対応させてみる。<br />
<br />
<br />
<br />
<br />
[動作条件]<br />
・perl5以上（確認した環境はは5.10）かつMail::POP3Clientモジュールがインストールされていること。<br />
・POPアクセスにSSLを用いる場合（Gmailなど）は、さらにIO::Socket::SSLモジュール（要コンパイラ）が必要。<br />
・あらかじめエラーメール受信専用のアドレスを作っておいて、メール送信する時にエンペロープFROMをそのアドレスに指定しておく。<br />
・CRONなどで以下のスクリプトを実行する。<br />
-------------------------------------------------------------------<br />
#/usr/bin/perl -w<br />
use strict;<br />
use Mail::POP3Client;<br />
<br />
my $log = "POPサーバに接続中・・・\n";<br />
<br />
#コンストラクタ　<br />
my $pop = new Mail::POP3Client(<br />
　　USER => 'pop_user', #popサーバのユーザ名<br />
　　PASSWORD => 'pop_pwd', #同パスワード<br />
　　HOST => 'pop.gmail.com', #popサーバ名<br />
　　AUTH_MODE => 'BEST', #認証モード（たいていはBESTでOK）<br />
　　DEBUG => 0, #デバッグ有無（正の整数を指定すると、プロンプトにサーバとのやりとりが表示される）<br />
　　TIMEOUT => 10, #接続タイムアウト秒（デフォルトは60）<br />
　　USESSL => 'true' #SSLを使わない場合は0（Gmailは使う）<br />
　);<br />
<br />
<br />
if($pop->Count < 0){ #接続に失敗すると-1が返るらしい<br />
　$log .= "POPサーバに接続できませんでした";<br />
}<br />
else{<br />
　$log .= "ID[$id]のエラーメールアドレスを調査中・・・\n";<br />
　　if($pop->Count != 0){<br />
　　　my $cnt = $pop->Count;<br />
　　　my @err = ();<br />
　　　my $suc = 0;<br />
　　　my %diag = ();　###　エラーの原因格納用ハッシュ（任意）<br />
　　　my @next_ck = ();<br />
　　　$log .= "　　$cnt件のエラーメールアドレスを処理中・・・\n";<br />
　　　for(my $i=1; $i<=$cnt; $i++){<br />
　　　　my $pars_ok = 0;　####　パース成功フラグ<br />
　　　　foreach($pop->Body($i)){<br />
　　　　　###本文（SMTPサーバが返すメッセージ）からエラーになった宛先をパース<br />
　　　　　if(<br />
　　　　　　$_ =~ /^To:.*?\?iso-2022-jp\?B\?.+?\?=.*?<([\d\w-.+]+\@[\d\w-]+(\.[\d\w-]+)+)>/i ||<br />
　　　　　　$_ =~ /^Delivered-To:.*?([\d\w-.+]+\@[\d\w-]+(\.[\d\w-]+)+)/i ||<br />
　　　　　　$_ =~ /^X-Yahoo-Forwarded:.*?from.*?([\d\w-.+]+\@[\d\w-]+(\.[\d\w-]+)+).*?to/i<br />
　　　　　){<br />
　　　　　　$pars_ok = 1;<br />
　　　　　　push(@err,$1);<br />
　　　　　　$suc++;<br />
　　　　　　$pop->Delete($i);<br />
　　　　　　####### Diagnosis　エラーの原因チェック<br />
　　　　　　if($_ =~ /5\.4\.4|Host.*?not found/i){<br />
　　　　　　　$diag{'Host_not_exists'}++;		#ホストまたはドメインが存在しない<br />
　　　　　　}<br />
　　　　　　elsif($_ =~ /550|553|554|5\.0\.0|5\.1\.1|5\.7\.1/){<br />
　　　　　　　$diag{'Account_not_exists'}++;	#受信先又は転送先のアカウントが存在しない<br />
　　　　　　}<br />
　　　　　　elsif($_ =~ /421|450|4\.2\.1|User disk quota/i){<br />
　　　　　　　$diag{'Mailbox_unavailable'}++;	#受信先又は転送先のメールボックスが一時的に利用不可<br />
　　　　　　}<br />
　　　　　　elsif($_ =~ /451|452/){<br />
　　　　　　　$diag{'Server_error'}++;			#配信時サーバエラー<br />
　　　　　　}<br />
　　　　　　elsif($_ =~ /432|454|534|535|538/){<br />
　　　　　　　$diag{'Authen_error'}++;			#認証エラー<br />
　　　　　　}<br />
　　　　　　else{<br />
　　　　　　　$diag{'Other'}++;					#その他<br />
　　　　　　}<br />
　　　　　　last;<br />
　　　　　}<br />
　　　　}#foreach<br />
　　　　######　パースできなかったエラーメールは次のチェックへ<br />
　　　　push(@next_ck,$i) if !$pars_ok;<br />
　　　}#for<br />
　　　if(@next_ck != 0){<br />
　　　　for(my $i=0; $i<@next_ck; $i++){<br />
　　　　　#######　今度はヘッダをチェック<br />
　　　　　foreach($pop->Head($next_ck[$i])){<br />
　　　　　　if(<br />
　　　　　　　######　自動返信元をパース<br />
　　　　　　　$_ =~ /^From:.*?([\d\w-.+]+\@[\d\w-]+(\.[\d\w-]+)+)/i ||<br />
　　　　　　　$_ =~ /^From:.*?\?iso-2022-jp\?B\?.+?\?=.*?<([\d\w-.+]+\@[\d\w-]+(\.[\d\w-]+)+)>/i<br />
　　　　　　){<br />
　　　　　　　###　パースされたアドレスがデータベースにあるかチェック<br />
　　　　　　　&db::query("SELECT email FROM usertable WHERE email='$1'");<br />
　　　　　　　my $exists = $db::sth->fetchrow_array();<br />
　　　　　　　if($exists){<br />
　　　　　　　　###　あれば削除対象に<br />
　　　　　　　　push(@err,$1);<br />
　　　　　　　}<br />
　　　　　　　$suc++;<br />
　　　　　　　#####　メール削除フラグ<br />
　　　　　　　$pop->Delete($next_ck[$i]);<br />
　　　　　　　$diag{'Auto_return'}++;			#自動返信が設定されている<br />
　　　　　　　last;<br />
　　　　　　}<br />
　　　　　}#foreach<br />
　　　　}#for<br />
　　　}<br />
　　　if(@err){<br />
　　　　####エラーアドレスをDBから削除する処理など<br />
　　　　foreach(@err){<br />
　　　　　&db::query("DELETE FROM usertable WHERE email='$_'");<br />
　　　　}<br />
　　　　$log .= "$suc件のエラーメールアドレスをデータベースから削除しました\n";<br />
　　　}<br />
　　　###パースに失敗することもあるでしょう。<br />
　　　if(($cnt- $suc) > 0){<br />
　　　　$log .= "※".($cnt- $suc)."件のエラーメールアドレスを削除できませんでした\n";<br />
　　　}<br />
　}<br />
　else{<br />
　　$log .= "エラーメールアドレスはありませんでした\n";<br />
　}<br />
}<br />
<br />
#接続終了（このときメールがサーバから削除される）<br />
$pop->Close;<br />
<br />
print $log;<br />
<br />
------------------------------------------------------------------------<br />
<br />
<br />
<br />
<br />
あー疲れた。<br />
<br />
<br />
<br />
<br />
]]>
        
    </content>
</entry>

<entry>
    <title>dovecotのよくわからんエラー</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/03/dovecot.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.511</id>

    <published>2010-03-01T17:24:52Z</published>
    <updated>2010-03-01T17:55:58Z</updated>

    <summary>久々にメールアドレスでも新しく作ろうと思って、nologinで新規ユーザ作成して...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Post Fix" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="サーバ構築" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="メール配信" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[久々にメールアドレスでも新しく作ろうと思って、nologinで新規ユーザ作成してみた。<br />
<br />
thunderbirdでちゃちゃちゃとアカウント設定して、いざ受信って思ったら、<br />
「接続：ホストにログイン情報を送信しています・・・」<br />
のまま音沙汰なし。<br />
<br />
パスワードとかいろいろ確認しても特におかしくないので、とりあえずmaillogを確認したら、こんなメッセージが。<br />
<br />
-----------------------------------------------------------------------------------------<br />
dovecot.... mail_location not set and autodetection failed: Mail storage autodetection failed with home=......<br />
-----------------------------------------------------------------------------------------<br />
<br />
うーん、これはなんだろう。<br />
<br />
なんか雰囲気的に、メールボックスの場所が指定されてないから、メールを取りにいけません的な感じだろうか・・・<br />
<br />
おかしいなあ、前までは普通にユーザ作成してメーラーの設定するだけですぐにいけたんだけどなあ・・・<br />
と思いつつ、とりあえず問題ありそうな「/etc/dovecot.conf」を確認。<br />
<br />
ってゆうか、このファイル一回も中身見たことないし〜。<br />
<br />
メールサーバ入れたときもdovecotの設定なんか一回もやんなかったのに・・・<br />
デフォルトでいままでいけてたんですけどね。<br />
<br />
<br />
でもなんかこの辺が臭かったので、<br />
<br />
-------------------------------------------------------------------------------------------<br />
# Location for users' mailboxes. This is the same as the old default_mail_env<br />
# setting. The default is empty, which means that Dovecot tries to find the<br />
# mailboxes automatically. This won't work if the user doesn't have any mail<br />
# yet, so you should explicitly tell Dovecot the full location.<br />
#<br />
# If you're using mbox, giving a path to the INBOX file (eg. /var/mail/%u)<br />
# isn't enough. You'll also need to tell Dovecot where the other mailboxes are<br />
# kept. This is called the "root mail directory", and it must be the first<br />
# path given in the mail_location setting.<br />
#<br />
# There are a few special variables you can use, eg.:<br />
#<br />
#   %u - username<br />
#   %n - user part in user@domain, same as %u if there's no domain<br />
#   %d - domain part in user@domain, empty if there's no domain<br />
#   %h - home directory<br />
#<br />
# See <doc/wiki/Variables.txt> for full list. Some examples:<br />
#<br />
#   mail_location = maildir:~/Maildir<br />
#   mail_location = mbox:~/mail:INBOX=/var/mail/%u<br />
#   mail_location = mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%n<br />
#<br />
# <doc/wiki/MailLocation.txt><br />
#<br />
#mail_location = <br />
-------------------------------------------------------------------------------------------<br />
<br />
google様で直訳してみると、locationの設定は必須ですよ〜みたいな感じなのかな？<br />
<br />
とりあえず例のまんま設定してみる。<br />
<br />
-------------------------------------------------------------------------------------------<br />
mail_location = mbox:~/mail:INBOX=/var/mail/%u<br />
-------------------------------------------------------------------------------------------<br />
<br />
てなかんじ。<br />
<br />
すると・・・おお！メーラーがちゃんとメールを読みに行った！<br />
<br />
なんじゃそりゃ。<br />
<br />
<br />
ユーザディレクトリにも「mail」ディレクトリが作成されてる。<br />
さっきまで無かったのに・・・<br />
この「mail」ディレクトリって何なのかわかんなかったけど、dovecotが勝手に作ってるんですね・・・<br />
<br />
<br />
とりあえずpopはOKそうなので、ついでにSMTP（postfix）の方も確認。<br />
/etc/postfix/main.cfを開いて、それっぽい部分を見てみると、<br />
<br />
-------------------------------------------------------------------------------------------<br />
# DELIVERY TO MAILBOX<br />
#<br />
# The home_mailbox parameter specifies the optional pathname of a<br />
# mailbox file relative to a user's home directory. The default<br />
# mailbox file is /var/spool/mail/user or /var/mail/user.  Specify<br />
# "Maildir/" for qmail-style delivery (the / is required).<br />
#<br />
#home_mailbox = Mailbox<br />
#home_mailbox = Maildir/<br />
-------------------------------------------------------------------------------------------<br />
<br />
どうやら、デフォルトのメールボックスは/var/spool/mail/userか、 /var/mail/userで、何もいじらないとここにメールを届けに行くらしい。<br />
というわけで、さっきのdovecotの設定とつじつまがあってるのでOK。<br />
<br />
まあ、ちゃんとした人たちはMaildir形式にちゃんと設定してるんだろうけど、横着な私はこれで問題無し。<br />
<br />
<br />
一応確認のためにpostfixから送信して、dovecotで取りに行ってちゃんと読めたのでめでたし。<br />
<br />
しかし軽く7時間かかったのは痛かった。<br />
<br />
<br />
サーバ立ち上げた時から今まで問題なかったのに、いつからdovecotのデフォルト設定変わったの？って感じ。<br />
<br />
アップデートなんてまったくやってないのに。<br />
<br />
・・・よくわからないなー]]>
        
    </content>
</entry>

<entry>
    <title>MySQL:新しいテーブル構造に合わせてテーブルをコピー</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/02/mysql-1.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.464</id>

    <published>2010-02-18T01:48:51Z</published>
    <updated>2010-03-01T17:24:32Z</updated>

    <summary>前記事（http://www.igreks.jp/dev/2010/01/mys...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="MySQL" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[前記事（<a href="http://www.igreks.jp/dev/2010/01/mysql.html">http://www.igreks.jp/dev/2010/01/mysql.html</a>）のようにALTER TABLEを使って更新するのもいいのだが、できれば構造のテンプレートに合わせて一発でコピーしたい。<br />
<br />
ただ単にテーブルの構造とデータをコピーする場合、普通は、<br />
<br />
---------------------------------------------------------------------------------------<br />
CREATE TABLE sample_new LIKE sample_original<br />
INSERT INTO sample_new SELECT * FROM sample_original<br />
---------------------------------------------------------------------------------------<br />
<br />
<br />
しかし、新しい構造のテーブルにあわせて、構造を変更しながらデータをコピーするといった方法が見つからないため、スクリプトの処理を合わせて実現してみる。<br />あんまりスマートじゃないけど・・・<br /><br />まず、最新の構造のテンプレートを作っておく。<br />
<br />
<br />
■最新のテーブル構造のテンプレート（tbl.pl）<br />
---------------------------------------------------------------------------------------<br />
<br />
package tbl;<br />
<br />
sub conf{<br /><blockquote>my %tbl = (<br /><br /><blockquote>
		'table_a' =&gt; {<br /><blockquote>
			'column'	=&gt; '<br /><blockquote>
				id         INT           AUTO_INCREMENT PRIMARY KEY,<br />
				column_1    VARCHAR(36),<br />
			        column_2    VARCHAR(255),<br />column_3    VARCHAR(255)<br /></blockquote>
			',<br />
			'option'	=&gt; '<br /><blockquote>
				ENGINE = MyISAM DEFAULT CHARSET = utf8<br /></blockquote>
			'<br /></blockquote>
		},<br /><br />
		'table_b' =&gt; {<br /><blockquote>'column'	=&gt; '<br /><blockquote>id INT          NOT NULL AUTO_INCREMENT PRIMARY KEY,<br />column_1 INT,<br />column_2 VARCHAR(255),<br />column_3 VARCHAR(255)<br /></blockquote>',<br />
			'option'	=&gt; '<br /><blockquote>
				ENGINE = MyISAM DEFAULT CHARSET = utf8<br /></blockquote>
			'<br /></blockquote>
		},<br /></blockquote><blockquote><blockquote>・<br />・<br />・<br /></blockquote></blockquote>);<br />return \%tbl;<br /></blockquote>}<br />
				1;<br /><br />
---------------------------------------------------------------------------------------<br /><br /><br />テンプレートを読み込んで新しいテーブルを一時作成し、<br />そのテーブルに既存のテーブルのデータをインポートする。<br /><br />■更新処理（tbl_update.pl）<br />
---------------------------------------------------------------------------------------<br />#!/usr/bin/perl<br /><br />package::main;<br /><br />my $dbh;<br />・<br />・<br />・<br /># この辺でデータベースへの接続処理（詳細割愛）<br /><br />print "Content-type: text/html\n\n";<br /><br />print "&lt;p&gt;データベースの再構築を開始します&lt;/p&gt;\n";<br /><br /># 既存のテーブル名をリストで取得<br />my $sth = $dbh-&gt;prepare("SHOW TABLES LIKE 'hoge_%'") || die $dbh-&gt;errstr();<br />$sth-&gt;execute();<br />my @hoge_tbl = ();<br />while(my @tbl = $sth-&gt;fetchrow_array()){<br /><blockquote>push(@hoge_tbl,$tbl[0]);<br /></blockquote>}<br /><br /># テンプレート読み込み<br />
require "./tbl.pl";<br />
my $tbl = &amp;tbl::conf(); # ※リファレンスで受け取り<br />
<br />foreach(@hoge_tbl){<br /><br /># 既存テーブルのカラム名をリストで取得<br />my @cols = ();<br />my $sth = $dbh-&gt;prepare("DESCRIBE $_") || die $dbh-&gt;errstr();<br />$sth-&gt;execute();<br />
while(my $href = $sth-&gt;fetchrow_hashref()){<br /><blockquote>push(@cols,$href-&gt;{'Field'});&nbsp; # unshiftしちゃだめよ<br /></blockquote>}<br />my $cols = join(',',@cols);<br /><br />#####################################<br /># テーブル名の末尾に個別にIDとかが付いてなければこの処理はいらない<br />$_ =~ /hoge_(.+?)(_.+?)?$/;<br />my $name = $1;<br />######################################<br /><br /># 新しい構造の空テーブルを「pre_***」という名前で一旦作成<br />my $sth = $dbh-&gt;prepare("<br /><blockquote>CREATE TABLE IF NOT EXISTS pre_$_ (<br /><blockquote>$$tbl{$name}{'column'}<br /></blockquote>) $$tbl{$name}{'option'}<br /></blockquote>") || die $dbh-&gt;errstr();<br />$sth-&gt;execute();<br /><br /># 既存のテーブルのデータを、カラム名を明示的に指定して挿入<br /># これをしないとカラムの数が合いませんよ！と怒られる<br />my $sth = $dbh-&gt;prepare("INSERT INTO pre_$_ ($cols) SELECT * FROM $_"); # ※1<br />$sth-&gt;execute();<br /><br />
# 既存のテーブル削除<br />my $sth = $dbh-&gt;prepare("DROP TABLE IF EXISTS $_");<br />$sth-&gt;execute();<br />
<br /># 新しいテーブルのリネーム（"pre_"をとる）<br />my $sth = $dbh-&gt;prepare("ALTER TABLE pre_$_ RENAME $_");<br />$sth-&gt;execute();<br /><br />}<br /><br />print "&lt;p&gt;データベースの再構築が完了しました。&lt;/p&gt;\n";<br />
<br />exit;<br />---------------------------------------------------------------------------------------<br /><br /><br />以上。<br /><br />新しいテーブルにカラムが追加されてる場合は問題ないが、カラムが削除された場合は、多分※1のところでエラーになる・・・<br /><br />こういうの一発でできるSQLないのかなぁ。<br /><br />

]]>
        
    </content>
</entry>

<entry>
    <title>ハッシュの値(value)の重複チェック</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/02/value.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.453</id>

    <published>2010-02-15T04:23:23Z</published>
    <updated>2010-02-18T01:47:27Z</updated>

    <summary>配列関係の重複チェックは一度ハッシュ（%check）に入れると簡単 ------...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[配列関係の重複チェックは一度ハッシュ（%check）に入れると簡単<br />
<br />
<br />
-----------------------------------------------------------------------------------------<br />
<br />
my %hash = (<br />
 a => 'あああ',<br />
 b => 'いいい', <br />
 c => 'ううう',<br />
 d => 'あああ',<br />
 e => 'おおお',<br />
 f => 'あああ'<br />
);<br />
<br />
my %check = ();<br />
<br />
for(values %hash){<br />
 die "$_ が重複してるよ！" if $check{$_};<br />
 $check{$_} = 1; #### 1とかaとか好きなの入れる<br />
}<br />
<br />
-----------------------------------------------------------------------------------------<br />
]]>
        
    </content>
</entry>

<entry>
    <title>LWPのレスポンス確認用メソッドまとめ：Summary of verification methods of HTTP response by LWP</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/02/lwpsummary-of-verification-methods-of-http-response-by-lwp.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.452</id>

    <published>2010-02-06T06:45:30Z</published>
    <updated>2010-02-15T04:18:57Z</updated>

    <summary>LWPを使ったhttpレスポンスの取得には、HTTP::Request(::Co...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[LWPを使ったhttpレスポンスの取得には、HTTP::Request(::Common)モジュールを使ってリクエストのオブジェクトを作っておくと、レスポンス情報を確認するさまざまなメソッドを使用することができる。<br />
<br />
HTTPモジュール群にはまず「HTTP::Message」があり、このオブジェクトには幾つかのヘッダとコンテント（ボディ）取得用のクラスが入ってるが、このクラスは抽象クラスである。<br />
つまりHTTP::RequestとHTTP::Responseのための基本クラスとしてだけ使われ、それ自身のインスタンスは生成されることはない。<br />
<br />
「HTTP::Response」はHTTP形式のレスポンスをカプセル化するクラスである。<br />
このクラスのインスタンスは通常、LWP::UserAgentオブジェクトのrequestメソッドによって作成され返される。<br />
<br />
また、「HTTP::Headers」は同様にHTTP形式のメッセージヘッダをカプセル化するクラスである。<br />
このクラスのインスタンスは通常、HTTP::RequestやHTTP::Responseクラスのメンバー変数として、ライブラリ内部用に作成される。<br />
<br />
つまり、<br />
<br />
my $url = '<a href="http://yahoo.co.jp';">http://yahoo.co.jp';</a><br />
my $ua = LWP::UserAgent->new();<br />
my $req = &HTTP::Request::Common::GET($url);<br />
my $res = $ua->request($req);<br />
<br />
のように、レスポンス用オブジェクト($res)生成しておけば、上の3つのモジュールで定義されているメソッドは全てこのオブジェクト($res)から以下のように参照することができる。<br />
<br />
---------------------------------------------------------------------------------------------------<br />
<br />
（HTTP::Message）<br />
<br />
■$res->protocol([$proto])<br />
・・・そのメッセージに使われるHTTPプロトコルを設定する。protocol()は"HTTP/1.0"または"HTTP/1.1"のような文字列が返る。<br />
<br />
■$res->content([$content])<br />
・・・引数が与えられていれば、コンテントを設定する。引数が無ければ、コンテントは触れられずに返される。<br />
<br />
■$res->add_content($data)<br />
・・・前のコンテントの末尾にさらにデータを追加する。<br />
<br />
■$res->content_ref<br />
・・・コンテント文字列へのリファレンスを返す。<br />
コンテントが巨大であれば、この方法が効率的。また、直接操作が出来る。<br />
例：${$res->content_ref} =~ s/\bfoo\b/bar/g;<br />
<br />
■$res->headers;<br />
・・・HTTP::Headersオブジェクトを返す。<br />
<br />
■$res->headers_as_string([$endl])<br />
・・・HTTP::Headers->as_stringを呼び出す。<br />
<br />
（HTTP::Headers）<br />
<br />
■$res->header($field [=> $value],...)<br />
・・・ヘッダの値を取得または設定する。<br />
ヘッダ・フィールド名は大文字／小文字を区別しない。<br />
引数が無い場合は複数の（$field => $values)の組を受け取る。<br />
$valueを複数設定することにより１回の呼び出しでたくさんのフィールドを更新することも可能。$valuesにはスカラまたはスカラのリストへのリファレンスを指定することができる。<br />
$valueが未定義だったり指定されていなければヘッダは変更されない。<br />
<br />
複数の値を持つフィールドは、スカラ・コンテキストでは","を区切り文字としてつなげられ返される。<br />
<br />
（例）<br />
　$header->header(MIME_Version => '1.0',<br />
　　　　　　User_Agent   => 'My-Web-Client/0.01');<br />
　$header->header(Accept => "text/html, text/plain, image/*");<br />
　$header->header(Accept => [qw(text/html text/plain image/*)]);<br />
　@accepts = $header->header('Accept');<br />
<br />
■$res->scan(\&doit)<br />
・・・ヘッダそれぞれにサブルーチンを適用する。コールバック・ルーチンは２つのパラメータ（フィールド名と１つの値）で呼び出される。<br />
ヘッダが1つ以上の値を持っていれば、ルーチンはそれぞれの値につき1回呼ばれる。コールバック・ルーチンに渡されるフィールド名はHTTP仕様で提案されている大文字／小文字をもち、推奨されている"Good Practice"の順でやってくる。<br />
<br />
■$res->as_string([$endl])<br />
・・・フォーマットされたMIMEヘッダとしてヘッダ・フィールドを返す。<br />
文字列を組み立てるために内部でscan()メソッドを使っているので、結果はHTTP仕様で提案されている大文字小文字で、ヘッダ・フィールドの順序の推奨されている"Good Practice"に従う。<br />
長いヘッダの値はたたまれない。<br />
<br />
オプションのパラメータには使用する行末シーケンスを指定できる。デフォルトは"\n"。<br />
この場合、ヘッダに埋め込まれた"\n"文字は、この行末シーケンスで置きかえられる。<br />
<br />
■$res->push_header($field, $val)<br />
・・・指定されたヘッダに新しいフィールドの値を追加する。<br />
ヘッダ・フィールド名は大文字小文字を区別しない。<br />
同じフィールド名で、値を持たずに指定した場合、前の値が残る。<br />
引数にはスカラやスカラのリストへのリファレンスを指定することが出来る。<br />
<br />
（例）$header->push_header(Accept => 'image/jpeg');<br />
<br />
■$res->remove_header($field,...)<br />
・・・指定された名前を持つヘッダを削除する<br />
<br />
（HTTP::Response）<br />
<br />
■$res->code([$code])<br />
・・・レスポンスコード(301など)を返す。<br />
<br />
■$res->message([$message])<br />
・・・レスポンスメッセージを返す。<br />
<br />
■$res->request([$request])<br />
・・・このレスポンスを発生したリクエストのリファレンスを返す。<br />
ここまでの間に、リダイレクトや認証のリトライがある場合もあるので、$ua->request()メソッドに渡されたものと同じリクエストである必要はない。<br />
<br />
■$res->previous([$previousResponse])<br />
・・・最初のレスポンスがリダイレトクまたは認証されていなければ、レスポンスのチェーンを返す。<br />
<br />
■$res->status_line<br />
・・・文字列"$res->code + $res->message"を返す。<br />
もしmessage属性が設定されていなければ、code（HTTP::Statusを参照にした）の公的な名前に置き換えられる。<br />
<br />
■$res->base<br />
・・・レスポンスのベースURLを返す。<br />
戻り値はURIオブジェクトへのリファレンス。<br />
<br />
ベースURLは以下のいずれかの情報源から１〜３の優先順で取得される。<br />
<br />
　1. ドキュメント内容に埋め込まれたもの：例えばHTMLドキュメント内での<BASE HREF="..."><br />
　2. レスポンスでの"Content-Base:"または"Content-Locatin:"ヘッダ<br />
　　古いHTTP実装との互換性のため、"Base:"ヘッダも探す。<br />
　3. このレスポンスを要求したURL。<br />
　　これはレスポンスの前に、いくつかのリダイレクトを受信しているかもしれないため、$ua->request()メソッドに渡された元のURLでない場合もある。<br />
<br />
 ■$res->as_string<br />
・・・コンテントのプレーンテキストを返す。<br />
主にデバッグのために使われる。引数は指定できない。<br />
<br />
■$res->is_info<br />
■$res->is_success<br />
■$res->is_redirect<br />
■$res->is_error<br />
・・・レスポンスが情報的(informational)であるか、成功したか、リダイレクトであるか、エラーであるかを返す。<br />
（偽ならおそらくundefか0を返す）<br />
<br />
■$res->error_as_HTML()<br />
・・・何のエラーが発生したかを示す完全なHTMLドキュメントが入っている文字列を返す。<br />
このメソッドは$res->is_errorがTRUEのときだけ呼ぶべき。<br />
<br />
■$res->current_age<br />
・・・<draft-ietf-http-v11-spec-07> section 13.2.3.によって指定されたレスポンスの"現在の年齢"("current age")を計算する。<br />
レスポンスの年齢は元のサーバサーバーによって送信されてからの時間。<br />
返される値は累計秒。<br />
<br />
■$res->freshness_lifetime<br />
・・・<draft-ietf-http-v11-spec-07> section 13.2.4.で指定されたそのレスポンスの"新鮮期間"("freshness lifetime")を計算する。<br />
"新鮮期間"はレスポンスが生成されてから終了するまでの時間の長さ。<br />
返される値は累計秒。<br />
<br />
■$res->is_fresh<br />
・・・freshness_lifetime()とcurrent_age()の値をベースに、レスポンスが新鮮であればTRUEを返す。<br />
レスポンスがもはや新鮮でなければ、もう一度取り出されるか、元のサーバによって再評価されるべきである。<br />
<br />
■$res->fresh_until<br />
・・・このエンティティがもはや新鮮ではない時刻を返す。<br />
<br />
<br />
------------------------------------------------------------------------------------------------------<br />
<br />
参考URL：<br />
<a href="http://homepage3.nifty.com/hippo2000/perltips/HTTP/Headers.html">http://homepage3.nifty.com/hippo2000/perltips/HTTP/Headers.html</a><br />
<a href="http://homepage3.nifty.com/hippo2000/perltips/HTTP/Message.html">http://homepage3.nifty.com/hippo2000/perltips/HTTP/Message.html</a><br />
<a href="http://homepage3.nifty.com/hippo2000/perltips/HTTP/Response.html">http://homepage3.nifty.com/hippo2000/perltips/HTTP/Response.html</a><br />
]]>
        
    </content>
</entry>

<entry>
    <title>LWPでwebサイトの文字コード(charset)を取得する:Get the charcter set of a website by LWP)</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/02/lwpwebcharsetget-the-charcter-set-of-a-website-by-lwp.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.451</id>

    <published>2010-02-06T06:28:56Z</published>
    <updated>2010-02-06T06:43:17Z</updated>

    <summary>----------------------------------------...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="HTML" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="apache" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[----------------------------------------------------------------------------------------------<br />
<br />
#!/usr/bin/perl -w<br />
<br />
use strict;<br />
use LWP::UserAgent;<br />
use HTTP::Request::Common;<br />
<br />
# オブジェクト作成<br />
my $ua = LWP::UserAgent->new();<br />
my $url = '<a href="http://yahoo.co.jp';">http://yahoo.co.jp';</a><br />
my $req = &HTTP::Request::Common::GET($url);<br />
<br />
# レスポンスを得る<br />
my $res = $ua->request($req);<br />
<br />
# フィールド名を指定してヘッダを取得<br />
my $con_type = $res->header('Content-Type');<br />
<br />
#処理<br />
if($con_type =~ /shift_jis/i){<br />
　　# (sjis用エンコーディング処理)<br />
}<br />
elsif($con_type =~ /euc-jp/i){<br />
　　# (ujis用エンコーディング処理)<br />
}<br />
elsif($con_type =~ /utf-8/i){<br />
　　# (utf8用エンコーディング処理)<br />
}<br />
　　・<br />
　　・<br />
　　・<br />
<br />
----------------------------------------------------------------------------------------------<br />
<br />
<br />
※charsetをダイレクトに返してくれるメソッドはどうやら無いらしい・・・<br />
あったら教えてください。]]>
        
    </content>
</entry>

<entry>
    <title>Crypt::SSLeayが無くてもLWPでhttpsがリクエストできる件</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/02/cryptssleaylwphttps.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.450</id>

    <published>2010-02-03T00:29:43Z</published>
    <updated>2010-02-06T06:28:27Z</updated>

    <summary>多くの参考サイトや本では、LWPモジュール群を利用してのSSLアクセスには「Cr...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="サーバ構築" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[多くの参考サイトや本では、LWPモジュール群を利用してのSSLアクセスには「Crypt::SSLeay」モジュールが必要と説明されているが、どうやら「Net::SSLaey」モジュールがあれば可能なようだ。<br />
<br />
もちろんサーバにSSL環境（OpenSSLとかmodSSLとか）があるっていうのが前提ではあるが。<br />
<br />
OpenSSLとLWPのつなぎ役をしてくれるのがCrypt::SSLeayだが、もともと、OpenSSLとSSLeayとの高度な機能インタフェースを提供するモジュールが「Net::SSLaey」モジュールである。<br />
<br />
<br />
以下確認作業<br />
<br />
■まず適当なスクリプトでPerlの@INCの中身を確認----------------------------------------------------------------------------------------------<br />
#!/usr/bin/perl<br />
<br />
print "Content-type: text/plain\n\n";<br />
<br />
foreach(@INC){<br />
print $_.'\n';<br />
}<br />
<br />
exit;<br />
----------------------------------------------------------------------------------------------<br />
<br />
■結果↓<br />
<br />
----------------------------------------------------------------------------------------------<br />
/usr/local/lib/perl5/site_perl/5.10.0/i386-linux-thread-multi<br />
/usr/local/lib/perl5/site_perl/5.10.0<br />
/usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi<br />
/usr/lib/perl5/vendor_perl/5.10.0<br />
/usr/lib/perl5/vendor_perl<br />
/usr/lib/perl5/5.10.0/i386-linux-thread-multi<br />
/usr/lib/perl5/5.10.0<br />
/usr/lib/perl5/site_perl<br />
.<br />
----------------------------------------------------------------------------------------------<br />
<br />
■次に、Crypt::SSLeayとNet::SSLeayが入っているか確認↓<br />
<br />
----------------------------------------------------------------------------------------------<br />
（コマンド）<br />
$ su<br />
# cd /<br />
<br />
# find -path *Crypt/SSL*<br />
<br />
#<br />
（↑Crypt::SSLeayは入っていない）<br />
<br />
# find -path *Net/SSL*<br />
<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/Net/SSLeay<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/Net/SSLeay/Handle.pm<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/Net/SSLeay.pm<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/auto/Net/SSLeay<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/auto/Net/SSLeay/https_cat.al<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/auto/Net/SSLeay/do_https4.al<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/auto/Net/SSLeay/get_httpx3.al<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/auto/Net/SSLeay/get_http.al<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/auto/Net/SSLeay/put_http.al<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/auto/Net/SSLeay/want_read.al<br />
　　　・<br />
　　　・<br />
　　　・<br />
（以下省略）<br />
<br />
（↑@INCでは「/usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi」にNet::SSLeayが入っている）<br />
----------------------------------------------------------------------------------------------<br />
<br />
■試しに名前を変えてみる↓<br />
<br />
----------------------------------------------------------------------------------------------<br />
# cd /usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/Net<br />
# mv SSLeay.pm SSLeay.pm2<br />
----------------------------------------------------------------------------------------------<br />
<br />
■スクリプト↓でhttpsにリクエストしてみる<br />
<br />
----------------------------------------------------------------------------------------------<br />
#!/usr/bin/perl<br />
<br />
use strict;<br />
use LWP::UserAgent;<br />
use HTTP::Request::Common;<br />
<br />
my $ua = LWP::UserAgent->new();<br />
<br />
my $url = "<a href="https://www.hogehoge.jp">https://www.hogehoge.jp</a>"; # 実在するセキュアサイト<br />
<br />
$request = &HTTP::Request::Common::GET($url);<br />
$response = $ua->request($request);<br />
<br />
print "Content-type: text/plain\n\n";<br />
print $response->status_line;<br />
<br />
exit;<br />
----------------------------------------------------------------------------------------------<br />
<br />
■実行結果↓<br />
<br />
----------------------------------------------------------------------------------------------<br />
<br />
 501 Protocol scheme 'https' is not supported<br />
<br />
（httpsプロトコルはサポートしていません）<br />
----------------------------------------------------------------------------------------------<br />
<br />
■SSLeay.pmを元に戻す↓<br />
<br />
----------------------------------------------------------------------------------------------<br />
# mv SSLeay.pm2 SSLeay.pm<br />
----------------------------------------------------------------------------------------------<br />
<br />
■さっきのスクリプトをもう一度実行↓<br />
<br />
----------------------------------------------------------------------------------------------<br />
<br />
 302 Found<br />
<br />
（ファイルが存在します＝接続成功）<br />
----------------------------------------------------------------------------------------------<br />
<br />
<br />
めでたしめでたし。<br />
]]>
        
    </content>
</entry>

<entry>
    <title>特定のプロセスを実行しているファイル名を調べる</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/01/post-5.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.446</id>

    <published>2010-01-27T11:38:50Z</published>
    <updated>2010-02-03T00:20:18Z</updated>

    <summary>あるプロセスがサーバに過大な負荷をかけているとき、その犯人と、原因のプログラムフ...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="サーバ構築" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[あるプロセスがサーバに過大な負荷をかけているとき、その犯人と、原因のプログラムファイルを発見する一番早い（？）方法。<br />
<br />
<br />
まずtopコマンドやpsコマンドで、そのプロセスのプロセス番号を調べる。<br />
<br />
-------------------------------------------------------------------------------------------<br />
<br />
$ su<br />
<br />
# top<br />
<br />
-------------------------------------------------------------------------------------------<br />
<br />
<br />
プロセス番号がわかったら、<br />
<br />
-------------------------------------------------------------------------------------------<br />
<br />
# ls -l /proc/(プロセス番号)/exe <br />
<br />
-------------------------------------------------------------------------------------------<br />
<br />
として、実行ファイルのシンボリックリンクを参照する。<br />
※エディタで直接/proc/(プロセス番号)/exe にアクセスしてもバイナリファイルなので見れません。<br />
<br />
<br />
結果↓<br />
<br />
------------------------------------------------------------------------------------------<br />
<br />
lrwxrwxrwx 1 hoge.hoge 0 2010-01-27 05:23 <br />
/proc/プロセス番号/exe -> /home/●●/hoge/○○○<br />
<br />
------------------------------------------------------------------------------------------<br />
<br />
つまり「●●」が犯人で「○○○」が問題のファイル。<br />
<br />
<br />
<br />
あとは犯人に警告するなりプロセスをkillするなりご自由に。]]>
        
    </content>
</entry>

</feed>
