diff -urN tiarra-20040223-2/ChangeLog tiarra-20040307/ChangeLog
--- tiarra-20040223-2/ChangeLog	2004-02-23 15:36:00.000000000 +0900
+++ tiarra-20040307/ChangeLog	2004-03-07 19:37:53.000000000 +0900
@@ -1,5 +1,37 @@
+2004-03-07  Topia  <topia@clovery.jp>
+
+	* tiarra:
+	  - untaint を行うようにした。
+
+	* main/Configuration.pm:
+	  - 呼び出す関数名を間違えていた bug を修正。
+
+	* main/Mask.pm:
+	  - untaint を行うようにした。
+
+	* main/Multicast.pm:
+	  - ERR_NOTONCHANNEL, ERR_NOSUCHCHANNEL を *_sent に追加。
+
+	* main/IrcIO/Server.pm:
+	  - nick 変更の prefix category を nick::system にした。
+	  - _START_WHOIS_REPLY を呼ぶときに defined check をしてない bug
+	    を修正。
+
+	* module/Client/Cache.pm:
+	  - destruct を追加。
+	  - ChannelInfo につける remark にパッケージ名をつけて、
+	    他のモジュールとかぶらないようにした。
+
+	* module/Client/Eval.pm:
+	  - untaint を行うようにした。
+	  - 複数行の出力をちゃんと処理するようにした。
+
 2004-02-23  Topia  <topia@clovery.jp>
 
+	* module/Debug/RawLog.pm:
+	  - 追加。生の IRC メッセージ(のようなもの?)を ::printmsg を使って
+	    表示する。
+
 	* main/IrcIO/Client.pm:
 	  - RunLoop を Runloop と typo していたのを修正。
 
@@ -1412,7 +1444,7 @@
 
 	* これ以前のログは書いていません。
 
-#       Id: $Id: ChangeLog,v 1.132 2004/02/23 06:24:20 topia Exp $
+#       Id: $Id: ChangeLog,v 1.134 2004/03/07 10:34:19 topia Exp $
 #   Author: $Author: topia $
-#     Date: $Date: 2004/02/23 06:24:20 $
-# Revision: $Revision: 1.132 $
+#     Date: $Date: 2004/03/07 10:34:19 $
+# Revision: $Revision: 1.134 $
diff -urN tiarra-20040223-2/NEWS tiarra-20040307/NEWS
--- tiarra-20040223-2/NEWS	2004-02-23 15:36:00.000000000 +0900
+++ tiarra-20040307/NEWS	2004-03-07 19:37:53.000000000 +0900
@@ -1,5 +1,14 @@
+2004-03-07  Topia  <topia@clovery.jp>
+
+	* 全般
+	   - taint check モードで動作するようになりました(多分)。
+
 2004-02-23  Topia  <topia@clovery.jp>
 
+	* Debug::RawLog.pm
+	  - 追加。生の IRC メッセージ(のようなもの?)を ::printmsg を使って
+	    表示する。
+
 	* sample.conf
 	  - 順序が変わっています。注意してください。
 	  - general/omit-sysmsg-prefix-when-possible 削除。
diff -urN tiarra-20040223-2/main/Configuration.pm tiarra-20040307/main/Configuration.pm
--- tiarra-20040223-2/main/Configuration.pm	2004-02-23 15:36:00.000000000 +0900
+++ tiarra-20040307/main/Configuration.pm	2004-03-07 19:37:54.000000000 +0900
@@ -1,5 +1,5 @@
 # -----------------------------------------------------------------------------
-# $Id: Configuration.pm,v 1.24 2004/02/23 02:46:18 topia Exp $
+# $Id: Configuration.pm,v 1.25 2004/03/07 10:34:19 topia Exp $
 # -----------------------------------------------------------------------------
 # このクラスはフック`reloaded'を用意します。
 # フック`reloaded'は、設定ファイルがリロードされた時に呼ばれます。
@@ -223,7 +223,7 @@
 sub _complete_block_with_defaults {
     my ($blocks, $defaults) = @_;
 
-    while (my ($default_block_name,$default_block) = each %{$defaults}) {
+    while (my ($default_block_name,$default_block) = each %$defaults) {
 	# このブロックは存在しているか？
 	unless (defined $blocks->get($default_block_name)) {
 	    # ブロックごと省略されていたので空のブロックを定義。
@@ -246,7 +246,7 @@
 	    }
 	}
 	if (values %$must_check_child) {
-	    _complete_block_with_defaults_recursive($block, $must_check_child);
+	    _complete_block_with_defaults($block, $must_check_child);
 	}
     }
 }
diff -urN tiarra-20040223-2/main/IrcIO/Server.pm tiarra-20040307/main/IrcIO/Server.pm
--- tiarra-20040223-2/main/IrcIO/Server.pm	2004-02-23 15:36:00.000000000 +0900
+++ tiarra-20040307/main/IrcIO/Server.pm	2004-03-07 19:37:54.000000000 +0900
@@ -1,5 +1,5 @@
 # -----------------------------------------------------------------------------
-# $Id: Server.pm,v 1.53 2004/02/23 06:24:20 topia Exp $
+# $Id: Server.pm,v 1.54 2004/03/07 10:34:19 topia Exp $
 # -----------------------------------------------------------------------------
 # IrcIO::ServerはIRCサーバーに接続し、IRCメッセージをやり取りするクラスです。
 # このクラスはサーバーからメッセージを受け取ってチャンネル情報や現在のnickなどを保持しますが、
@@ -438,7 +438,7 @@
 		    my $old_nick = $msg->nick;
 		    RunLoop->shared_loop->broadcast_to_clients(
 			IRCMessage->new(
-			    Prefix => RunLoop->shared_loop->sysmsg_prefix(qw(priv system)),
+			    Prefix => RunLoop->shared_loop->sysmsg_prefix(qw(priv nick::system)),
 			    Command => 'NOTICE',
 			    Params => [$local_nick,
 				       "*** Your global nick in ".
@@ -805,8 +805,8 @@
 	$p->username($msg->param(2));
 	$p->userhost($msg->param(3));
 	$p->realname($msg->param(5));
+	$this->_START_WHOIS_REPLY($p);
     }
-    $this->_START_WHOIS_REPLY($p);
 }
 
 sub _START_WHOIS_REPLY {
@@ -1004,7 +1004,7 @@
 	    Param => $next_nick));
     RunLoop->shared_loop->broadcast_to_clients(
 	new IRCMessage(
-	    Prefix => RunLoop->shared_loop->sysmsg_prefix(qw(priv system)),
+	    Prefix => RunLoop->shared_loop->sysmsg_prefix(qw(priv nick::system)),
 	    Command => 'NOTICE',
 	    Params => [RunLoop->shared_loop->current_nick,$msg_for_user]));
     main::printmsg($msg_for_user);
diff -urN tiarra-20040223-2/main/Mask.pm tiarra-20040307/main/Mask.pm
--- tiarra-20040223-2/main/Mask.pm	2004-02-23 15:36:00.000000000 +0900
+++ tiarra-20040307/main/Mask.pm	2004-03-07 19:37:54.000000000 +0900
@@ -1,5 +1,5 @@
 # -----------------------------------------------------------------------------
-# $Id: Mask.pm,v 1.13 2003/12/31 05:39:35 admin Exp $
+# $Id: Mask.pm,v 1.14 2004/03/07 10:34:19 topia Exp $
 # -----------------------------------------------------------------------------
 # $Clovery: tiarra/main/Mask.pm,v 1.10 2003/07/24 03:08:26 topia Exp $
 package Mask;
@@ -100,8 +100,10 @@
     if ($use_re && substr($work, 0, 3) eq 're:') {
       # 正規表現
       $work = substr($work,3);
+      # untaint
+      $work =~ /\A(.*)\z/s;
       $work = eval {
-	qr/$work/;
+	qr/$1/;
       }; if ($@) {
 	$work = '';
 	carp "error in regex: $@";
diff -urN tiarra-20040223-2/main/Multicast.pm tiarra-20040307/main/Multicast.pm
--- tiarra-20040223-2/main/Multicast.pm	2004-02-23 15:36:01.000000000 +0900
+++ tiarra-20040307/main/Multicast.pm	2004-03-07 19:37:54.000000000 +0900
@@ -1,5 +1,5 @@
 # -----------------------------------------------------------------------------
-# $Id: Multicast.pm,v 1.22 2004/02/23 02:46:18 topia Exp $
+# $Id: Multicast.pm,v 1.23 2004/03/07 10:34:19 topia Exp $
 # -----------------------------------------------------------------------------
 # サーバーからクライアントにメッセージが流れるとき、このクラスはフィルタとして
 # ネットワーク名を付加します。
@@ -357,7 +357,7 @@
 		((map { ("$_", "ENDOF$_"); } qw(INVITELIST EXCEPTLIST BANLIST)),
 		 (map {"ENDOF$_"} qw(WHO NAMES)),
 		 qw(LIST CHANNELMODEIS NOTOPIC TOPIC TOPICWHOTIME))),
-	   qw(ERR_TOOMANYCHANNELS))},
+	   qw(ERR_TOOMANYCHANNELS ERR_NOTONCHANNEL ERR_NOSUCHCHANNEL))},
     do {
 	no strict 'refs';
 	map {
@@ -431,7 +431,7 @@
 		 (map {"ENDOF$_"} qw(WHO NAMES)),
 		 qw(LIST CHANNELMODEIS NOTOPIC TOPIC TOPICWHOTIME),
 		 qw(INVITING UNIQOPIS WHOREPLY))),
-	   qw(ERR_TOOMANYCHANNELS))},
+	   qw(ERR_TOOMANYCHANNELS ERR_NOTONCHANNEL ERR_NOSUCHCHANNEL))},
     do {
 	no strict 'refs';
 	map {
diff -urN tiarra-20040223-2/module/Client/Cache.pm tiarra-20040307/module/Client/Cache.pm
--- tiarra-20040223-2/module/Client/Cache.pm	2004-02-23 15:36:01.000000000 +0900
+++ tiarra-20040307/module/Client/Cache.pm	2004-03-07 19:37:54.000000000 +0900
@@ -1,5 +1,5 @@
 # -----------------------------------------------------------------------------
-# $Id: Cache.pm,v 1.4 2004/02/23 02:46:19 topia Exp $
+# $Id: Cache.pm,v 1.5 2004/03/07 10:34:19 topia Exp $
 # -----------------------------------------------------------------------------
 package Client::Cache;
 use strict;
@@ -19,6 +19,21 @@
     return 0;
 }
 
+sub destruct {
+    my ($this) = shift;
+    # cleaning remarks
+
+    # チャンネルについている remark を削除。
+    foreach my $network (@{RunLoop->shared_loop->networks}) {
+	foreach my $ch (@{$network->channels}) {
+	    $ch->remark("__PACKAGE__/fetching-switches", undef, 'delete');
+	    $ch->remark("__PACKAGE__/fetching-who", undef, 'delete');
+	}
+    }
+
+    # クライアントについてるのは削除しない。
+}
+
 sub message_io_hook {
     my ($this,$msg,$io,$type) = @_;
 
@@ -29,21 +44,21 @@
 			    !defined $msg->param(1)) {
 	    my $ch = $io->channel($msg->param(0));
 	    if (defined $ch) {
-		$ch->remark('fetching-switches', 1);
+		$ch->remark("__PACKAGE__/fetching-switches", 1);
 	    }
 	} elsif ($type eq 'in' &&
 		     $msg->command eq RPL_CHANNELMODEIS &&
 			 Multicast::channel_p($msg->param(1))) {
 	    my $ch = $io->channel($msg->param(1));
 	    if (defined $ch) {
-		$ch->remark('fetching-switches', undef, 'delete');
+		$ch->remark("__PACKAGE__/fetching-switches", undef, 'delete');
 	    }
 	} elsif ($type eq 'out' &&
 		     $msg->command eq 'WHO' &&
 			 Multicast::channel_p($msg->param(0))) {
 	    my $ch = $io->channel($msg->param(0));
 	    if (defined $ch) {
-		$ch->remark('fetching-who', 1);
+		$ch->remark("__PACKAGE__/fetching-who", 1);
 	    }
 	} elsif ($type eq 'in' &&
 		     $msg->command eq RPL_WHOREPLY &&
@@ -51,7 +66,7 @@
 	    # 処理の都合上、一つでも帰ってきた時点で取り消し。
 	    my $ch = $io->channel($msg->param(1));
 	    if (defined $ch) {
-		$ch->remark('fetching-who', undef, 'delete');
+		$ch->remark("__PACKAGE__/fetching-who", undef, 'delete');
 	    }
 	}
     }
@@ -106,7 +121,7 @@
 		    return undef;
 		}
 	    } else {
-		if ($ch->remark('fetching-switches')) {
+		if ($ch->remark("__PACKAGE__/fetching-switches")) {
 		    # 取得しているクライアントがいるなら、今回は消す。
 		    return undef;
 		}
@@ -138,9 +153,6 @@
 			RunLoop->shared_loop->current_nick,
 			$chan_long,
 		       ],
-		    Remarks => {
-			'fill-prefix-when-sending-to-client' => 1,
-		    },
 		   );
 		my @messages;
 		eval {
@@ -186,7 +198,7 @@
 		    $sender->remark('who-cache-used', $remark);
 		    return undef;
 		} else {
-		    if ($ch->remark('fetching-who')) {
+		    if ($ch->remark("__PACKAGE__/fetching-who")) {
 			# 取得しているクライアントがいるなら、今回は消して便乗。
 			return undef;
 		    }
diff -urN tiarra-20040223-2/module/Client/Eval.pm tiarra-20040307/module/Client/Eval.pm
--- tiarra-20040223-2/module/Client/Eval.pm	2004-02-23 15:36:01.000000000 +0900
+++ tiarra-20040307/module/Client/Eval.pm	2004-03-07 19:37:54.000000000 +0900
@@ -1,5 +1,5 @@
 # -----------------------------------------------------------------------------
-# $Id: Eval.pm,v 1.2 2004/02/23 02:46:19 topia Exp $
+# $Id: Eval.pm,v 1.3 2004/03/07 10:34:19 topia Exp $
 # -----------------------------------------------------------------------------
 package Client::Eval;
 use strict;
@@ -23,7 +23,9 @@
 		# die handler
 		local $SIG{__DIE__} = sub { $err = $_[0]; };
 		no strict;
-		$ret = eval($method);
+		# untaint
+		$method =~ /\A(.*)\z/s;
+		$ret = eval($1);
 	    };
 
 	    my $message = IRCMessage->new(
@@ -39,9 +41,9 @@
 		    $new->param(1, $_);
 		    $sender->send_message($new);
 		} (
-		    'method: '.Dumper($method),
-		    'result: '.Dumper($ret),
-		    'error: '.$err,
+		    (split /\n/, 'method: '.Dumper($method)),
+		    (split /\n/, 'result: '.Dumper($ret)),
+		    (split /\n/, 'error: '.$err),
 		   );
 		return undef;
 	    };
diff -urN tiarra-20040223-2/module/Debug/RawLog.pm tiarra-20040307/module/Debug/RawLog.pm
--- tiarra-20040223-2/module/Debug/RawLog.pm	1970-01-01 09:00:00.000000000 +0900
+++ tiarra-20040307/module/Debug/RawLog.pm	2004-03-07 19:37:54.000000000 +0900
@@ -0,0 +1,94 @@
+# -*- cperl -*-
+# $Clovery: tiarra/module/Debug/RawLog.pm,v 1.2 2003/05/30 11:09:24 topia Exp $
+# copyright (C) 2003 Topia <topia@clovery.jp>. all rights reserved.
+
+package Debug::RawLog;
+use strict;
+use warnings;
+use base qw(Module);
+use Module::Use qw(Tools::DateConvert);
+use Tools::DateConvert;
+use Mask;
+use Multicast;
+
+sub message_io_hook {
+    my ($this,$message,$io,$type) = @_;
+
+    my $prefix = 'RAWLOG: ';
+    my $conf_entry = 'enable-';
+
+    $prefix .= do {
+	if ($type eq 'in') {
+	    '<<';
+	} elsif ($type eq 'out') {
+	    '>>';
+	} else {
+	    '--';
+	}
+    };
+
+    $prefix .= do {
+	if ($io->server_p()) {
+	    'SERVER(' . $io->network_name() . ') ';
+	} elsif ($io->client_p()) {
+	    'CLIENT(' . ($io->option('logname') || $io->fullname()) . ') ';
+	} else {
+	    '------ ';
+	}
+    };
+
+    $conf_entry .= do {
+	if ($io->server_p()) {
+	    'server'
+	} elsif ($io->client_p()) {
+	    'client';
+	}
+    };
+
+    $conf_entry .= '-' . $type;
+
+    # break with last
+    while (1) {
+	last if (($message->command =~ /^P[IO]NG$/) &&
+		     $this->config->ignore_ping);
+	last unless ($this->config->get($conf_entry));
+	my $msg = $message->clone;
+	if ($this->config->resolve_numeric && $message->command =~ /^\d{3}$/) {
+	    $msg->command(
+		(NumericReply::fetch_name($message->command)||'undef').
+		    '('.$message->command.')');
+	}
+	::printmsg($prefix . $msg->serialize());
+	last;
+    }
+
+    return $message;
+}
+
+1;
+
+=pod
+info: $BI8=`=PNO$K%/%i%$%"%s%H$d%5!<%P$H$NDL?.$r%@%s%W$9$k!#(B
+default: off
+
+# 0 $B$^$?$O>JN,$GI=<($7$J$$!#(B 1 $B$GI=<($9$k!#(B
+# $B%/%i%$%"%s%H%*%W%7%g%s$N(B logname $B$K$h$C$F!"%@%s%W$K;H$&L>A0$r;XDj$G$-$^$9!#(B
+
+# $B%5!<%P$+$i$NF~NO(B
+enable-server-in: 1
+
+# $B%5!<%P$X$N=PNO(B
+enable-server-out: 1
+
+# $B%/%i%$%"%s%H$+$i$NF~NO(B
+enable-client-in: 0
+
+# $B%/%i%$%"%s%H$X$N=PNO(B
+enable-client-out: 0
+
+# PING/PONG $B$rL5;k$9$k(B
+ignore-ping: 1
+
+# NumericReply $B$NL>A0$r2r7h$7$FI=<($9$k(B($B$A$c$s$H$7$?(B dump $B$G$OL5$/$J$j$^$9(B)
+resolve-numeric: 1
+=cut
diff -urN tiarra-20040223-2/sample.conf tiarra-20040307/sample.conf
--- tiarra-20040223-2/sample.conf	2004-02-23 15:36:00.000000000 +0900
+++ tiarra-20040307/sample.conf	2004-03-07 19:37:53.000000000 +0900
@@ -1,6 +1,6 @@
 # -*- tiarra-conf -*-
 # -----------------------------------------------------------------------------
-# $Id: sample.conf,v 1.64 2004/02/23 02:46:17 topia Exp $
+# $Id: sample.conf,v 1.65 2004/02/23 08:27:11 topia Exp $
 # -----------------------------------------------------------------------------
 # tiarra.conf サンプル
 #
@@ -870,6 +870,31 @@
   command: eval
 }
 
+- Debug::RawLog {
+  # 標準出力にクライアントやサーバとの通信をダンプする。
+
+  # 0 または省略で表示しない。 1 で表示する。
+  # クライアントオプションの logname によって、ダンプに使う名前を指定できます。
+  
+  # サーバからの入力
+  enable-server-in: 1
+  
+  # サーバへの出力
+  enable-server-out: 1
+  
+  # クライアントからの入力
+  enable-client-in: 0
+  
+  # クライアントへの出力
+  enable-client-out: 0
+  
+  # PING/PONG を無視する
+  ignore-ping: 1
+  
+  # NumericReply の名前を解決して表示する(ちゃんとした dump では無くなります)
+  resolve-numeric: 1
+}
+
 - Log::Channel {
   # チャンネルやprivのログを取るモジュール。
 
diff -urN tiarra-20040223-2/tiarra tiarra-20040307/tiarra
--- tiarra-20040223-2/tiarra	2004-02-23 15:36:00.000000000 +0900
+++ tiarra-20040307/tiarra	2004-03-07 19:37:53.000000000 +0900
@@ -5,7 +5,7 @@
 # This is free software; you can redistribute it and/or modify it
 #   under the same terms as Perl itself.
 # -----------------------------------------------------------------------------
-# $Id: tiarra,v 1.33 2004/02/23 02:46:18 topia Exp $
+# $Id: tiarra,v 1.34 2004/03/07 10:34:19 topia Exp $
 # -----------------------------------------------------------------------------
 require 5.006;
 use strict;
@@ -19,9 +19,13 @@
 		    map{ File::Spec->catdir($path, $_); } qw(main module));
 	}
     };
-
-    $add_inc->(File::Spec->rel2abs(map dirname($_), (readlink($0), $0))) if (-l $0);
-    $add_inc->(dirname($0), ".");
+    # untaint
+    $0 =~ /^(.+)$/;
+    my $self = $1;
+
+    $add_inc->(File::Spec->rel2abs(map dirname($_), (readlink($self), $self)))
+	if (-l $self);
+    $add_inc->(dirname($self), ".");
 }
 use Configuration;
 use RunLoop;
