サルではできない、自宅で手軽に、なんちゃってニュースサーバ(perl版)

※ コメントは、適当なニュースグループか、乾燥板メールで。(2007年4月07日)

このページで解説してる改造やスクリプトは、自由に使っていただいてかまいま せんし、自由に改変していただいてかまいません。その際、特に私に断わる必要 はありません。でも、ナイスな改良を思いついたら、教えてくれるとうれしいか も。

更新履歴

基本方針

  1. NNTPサーバには、perlモジュールのNNMLを使う。
  2. 配送には、NNML附属のnnmirrorを使う。
  3. 非固定IPでドメイン名が必要なら、ダイナミックDNSを使う。

という方針ですが、Windowsの場合はexe版の方がずっ と簡単です。が、他のOS使ってるとか、プログラム改造したいとかなら、そっち じゃ無理です。こっちを見てください。

インストール

perlのインストール

perlがなければ、perlをインストールしてください。WindowsだとActivePerlが 使えます。方法は例えば、「ActivePerlのインストール方 法 - Windows で perl を使おう!」とか。Cygwin環境やMingw環境のperlで も大丈夫なはず。parでexe化したい人はActivePerlの方がよいかも。

Windows以外なら、大抵は入ってるんじゃないかな? 入ってなかったら何か探し てインストールしてください。

NNMLのインストール

cpanを使って、NNML::Serverをインストールしてください。質問には、好みで答 えればよし。ActivePerl +CPANによるモジュールインストール方法は、まあ探せば何かあります。それ以外のperlで のcpanの使い方も、まあ、探せばあ るはず。

どこに何がインストールされたのかは、インストール画面の最後のあたりで分か ります。後で必要になるのでチェックしといてください。まあ、忘れてても大体 の見当はつきますが。ActivePerlの場合、perlをインストールしたディレクトリ をc:\perlとすると、c:\perl\site\lib\NNMLあたりの下に*.pmが入って、 c:\perl\binあたりにnnmirror.batが入ってるはず。ドキュメントは、 c:\perl\html\site\lib\NNMLとかc:\perl\html\binとか。普通のperlだとhtmlま では作ってくれないかも。perldoc使えってか?

「ActivePerlならcpanじゃなくてPPMでどうだ?」って意見もあるかもしれません が、PPMだと附属のnnmirrorをインストールしてくれないっぽいので、cpanの方 がよさげ。

つぎに、ニュースの記事を収める場所(base)を用意します。NNMLのインストール 時にbaseの設定をデフォルトのままにした人は、homeの下にMailというディレク トリ(フォルダ)を作ってください。ただし、ActivePerlの場合は、homeという概 念がないので、次の項を参考にして作ってください。baseの設定をいじった人は、 それに合わせて作ってください。(exe版では~/newsにしている。)

つぎに上で作ったbaseのディレクトリの下に「active」という名前の空のファイ ルを作ってください。Windowsの場合は、例えば、「右クリック→新規作成→テ キスト ドキュメント」でファイルを作って、名前を変更するとか。

ちなみに、baseのデフォルト値が「~/Mail」になってるのは、NNMLの作成動機と からんですようです。

スクリプトのダウンロードと展開

exe版と同じ、nnml+0.03をダウンロードして、適 当なディレクトリに展開するだけです。複数の人が使うコンピュータだったり、 公開サーバや相互配送を考えていたりするのなら、セキュリティ的に安全な場所 に置いてください。(nntpサーバ用のパスワードを生書きしたりするから。)

exeファイルは、使わないなら消してよいです。でかいし。parで作ったexeファ イルは、perlインタプリタを内蔵してるので非常に大きいんだわ。

スクリプトの設定

exe版設定の 項目で、hoge.batをhoge.plに、hoge.exeをperl hoge.plに読み換えればOK。 USERとHOMEが既に設定されてるような環境なら、該当する行を削ってよし。(っ てゆうか、start_server.pl使わずに直接server.pl使ってもいいし。)

ActivePerlのためのハック

ActivePerlの場合、未実装の関数(getpwnamとgetpwuid)が引っかかるので、NNML のConfig.pmに手を入れる必要があります。

まず、c:\perl\html\site\lib\NNMLみたいなところにConfig.pmというファイル があることを確認してください。実際にいじる前にコピーを作っておくこと。バッ クアップ用です。つぎに、Config.pmを書き込み可能にしてください。Windowsだ とConfig.pmのプロパティ開いて読み取り専用のチェックボックスを外し、セキュ リティ・タブでEveryoneにフルコントロールを許可するとか、そんな感じ。

つぎに、Config.pmを編集します。これはテキストファイルなので、適当なテキ ストエディタ(メモ帳とか)で開いてください。80行目あたりに「sub home」で始 まる関数定義があって、その中に「my $home = (getpwnam($user))[7];」という 行があるんで、これを「my $home = $ENV{'HOME'} || $ENV{'LOGDIR'} || (getpwuid($user))[7];」に書きかえます。

これで、関数homeの定義は、

sub home {
  my $self = shift;

  return $self->{_home} if exists $self->{_home};
  my $user = $ENV{'USER'} || $ENV{'LOGNAME'} || getpwuid($<);
  my $home = (getpwnam($user))[7];
  $self->{_home} = $home;
}

から、

sub home {
  my $self = shift;

  return $self->{_home} if exists $self->{_home};
  my $user = $ENV{'USER'} || $ENV{'LOGNAME'} || getpwuid($<);
  my $home = $ENV{'HOME'} || $ENV{'LOGDIR'} || (getpwuid($user))[7];
  $self->{_home} = $home;
}

になります。

これで、保存して、エディタを終了すれば、ここでの作業は取り敢えず終わりで す。

Pathを付加するためのハック

NNMLは、Path:ヘッダをいじってくれないので、自分のサイトをPath:に加えたけ れば、Connection.pmに手を入れる必要があります。必須ではないですが、普通 のサーバとの連携を考えるとやっといた方がよいでしょう。

Config.pmと同じディレクトリにある、Connection.pmを編集します。エディタで開 くまでの要領は、Config.pmのときと同じ。

577行目あたりの「sub NNML::Server::unspool」で始まる関数定義の中身をいじ ります。588行目あたりから、

    while (defined ($ent = <$sf>)) {
      chomp($ent);
      next unless $ent;
      my($ctl, $art) = split /\n/, $ent, 2;
      my ($msgid, $extra_group, $create) = split /\t/, $ctl;
なんて部分があるんですが、この直後に「 $art = add_path($art);」とい う行を加えて、
    while (defined ($ent = <$sf>)) {
      chomp($ent);
      next unless $ent;
      my($ctl, $art) = split /\n/, $ent, 2;
      my ($msgid, $extra_group, $create) = split /\t/, $ctl;
      $art = add_path($art);

とします。つぎに、609行目あたりの「sub inject_article {」という行の前に、

sub add_path {
    my $art = shift;

    my ($head, $body) = split /^$/m, $art, 2;
    my @header = split /\n/, $head;
    for (0 .. $#header) {
	if ($header[$_] =~ /^Path:\s/) {
	    $header[$_] =~ s/^Path:\s+(\S)/Path: $Config->{pathhost}!$1/
		if $header[$_] !~ /$Config->{pathhost}!/;
	    last;
	}
    }

    return join("\n", @header) . "\n" . $body;
}

という関数定義を加えます。

認証関係のバグフィクス

どうも、認証関係でバグがあるみたいなので、また、Connection.pmをハックし ます。

528行目あたりに「sub accept_article」で始まる関数定義があるんですが、そ の中の(539行目あたり)、

  my $create = NNML::Auth::perm($self,'create');

という行を、

  my $create = NNML::Auth::perm($self,'create') ? 1 : 0;

とします。

あとは、保存してエディタを終わるだけ。ファイルのパーミッションは、元に戻 しといた方がいいかも。

nnmirrorのパッケージ化

parを使ってexe版で作る都合上、nnmirrorをパッケージ化してます。perl版では 不要なんですが、exe版とソースが別になるのもあれなんで。NNmirror.pmという 名前で置いてますので、どこをどういじったかは、自分で確かめてください。

parによるexe化

perlスクリプトをexeファイルにする方法はいくつかあるんですが、ここではpar を使います。exeファイルが不要な方は、この項は要りません。

parのインストールは適当に探せば何かあると思います。この辺のページだと最 新版のActivePerlじゃ駄目なようなことを書いてるけど、5.8.8.816ではちゃん と動いてます。以前に入れようとしたときは、cygwinやmingwのperlじゃ駄目で、 ActivePerlでppm使って入れたら大丈夫だったような記憶がある。

server.plとnn_users.plをexe化するには、それぞれ、pps.batとppu.batを実行 してください。何やってるかは、中見れば分かるはず。「-M attributes.pm」は、 threads使ったから必要になったのかな?

使う

以降は、exe版の該当する項目で、hoge.batを hoge.plに、hoge.exeをperl hoge.plに読み換えればOK。

おわり