[目次に戻る] [入門CVSのサポートページに戻る] [みかままのページに戻る]
[前へ] [次へ]

Last-updated: $Date: 2001/05/28 06:54:55 $ GMT

@旧4章
@あと一カ所調整します。しばし、まて。

第5章 CVSコマンドの少し賢い使い方 ---サーバ編---

この章では、CVSの管理機構の部分をカスタマイズして自分の目的に合わせるということについて説明します。ここでは、個人の場合でも複数人の場合でも共通なカスタマイズについて述べます。複数人での共同作業に必要な設定については次章で説明します。


管理ファイルを設定してみよう

CVS の管理ファイルを設定すると、色々なことができます。 個人で使う場合にも便利ですが、他人数で共同作業をしたり する場合には必須であったりします。 例えば、コマンド実行時に行う操作を自動化する時には、 管理ファイルを設定しておこないます。

管理ファイルってどこにあるの?

管理ファイルは、リポジトリの直下にある CVSROOT ディレクトリの中にあります。この本では、リポジトリを /home/cvsroot に作って話をしていますので、/home/cvsroot/CVSROOTの中にあるはずです。 前の方の章でも見てみましたが、ちょっと中身を覗いてみましょう【図5.1】。

図 5.1 CVSROOT の中身

ls -a /home/cvsroot/CVSROOT

.               .#notify        commitinfo     history    rcsinfo,v

.#checkoutlist  .#rcsinfo       commitinfo,v   loginfo    taginfo

.#commitinfo    .#taginfo       config         loginfo,v  taginfo,v

.#config        .#verifymsg     config,v       modules    verifymsg

.#cvswrappers   ..              cvswrappers    modules,v  verifymsg,v

.#editinfo      Emptydir        cvswrappers,v  notify

.#loginfo       checkoutlist    editinfo       notify,v

.#modules       checkoutlist,v  editinfo,v     rcsinfo

ここで頭に.#のついたファイルはバックアップファイルですので気にしないでください。 checkoutlistとcheckoutlist,vのように、 ,v のついたファイル(RCSファイルとも言います)とペアになったファイルが管理者が設定を行うための管理ファイルです。 ここで、historyというファイルには,vのついたペアのファイルが存在しません。 実はこのファイルはユーザのおこなった動作をCVSが逐次記録するためのファイルなのです。 add, commitなどの実行のたびに、このファイルにその情報が追加されていきます。history コマンドでこのファイルの内容を抽出・整形して表示することができます。 自動的に書き換えられるものですから、 管理者が編集する必要はありません。 基本的にこのファイルはこのままそっとしておいてください。

なお、この最初の状態では含まれていない管理ファイルに、 passwd、readers、writers、users、cvsignoreファイルがあります。 passwd、readers、writersファイルは、pserverの設定の時に追加して使うようにします。passwdファイルについては、後の「CVSを遠隔から使おう」の項目で説明します。readers、writers、usersについては、第6章で説明します。cvsignoreの使い方および設定の仕方は、「個人環境を設定しよう」の項目で.cvsignoreに記述したものと同じです。パターンを書いておくと、updateの時にパターンにマッチしたファイルを無視するようになります。影響範囲が、個人および作業コピー内だったのが、リポジトリ利用者全員に拡大されるというだけです。

実行されるコマンドの種類によって影響する管理ファイルが違います。 管理ファイルとその影響するコマンドと用途をおおまかに表 5.1にまとめてみました。

表 5.1

管理ファイル名 関連するコマンド 使用目的 備考
config   リポジトリ全体に影響する設定をおこなう  
passwd 遠隔から実行するコマンド全て pserver で使用するパスワードを格納する 自動的には再構築されない
checkoutlist checkout 新規に追加する管理ファイルを記述する  
modules commit, checkout, export, rtag, update モジュールに別名をつけ、コマンド実行時に外部プログラムを実行する  
commitinfo commit コミット前のチェックプログラムを指定する 共通構文
loginfo commit コミット後のログメッセージの処理をおこなう 共通構文
rcsinfo commit ログメッセージのフォーマットを指定する 共通構文
verifymsg commit rcsinfo と組み合わせてログの書式を検証する 継続
editinfo commit コミットのログを編集したり、評価したりするプログラムを指定する もう使わない
taginfo tag, rtag タグ操作時に外部プログラムを実行する 共通構文
cvsignore update CVS で管理しないファイルを見えなくする .cvsignore
cvswrappers checkout, commit, update 出し入れ時に特定のファイルに対してフィルタをかける 将来的には使わない。.cvswrapper
notify watch, edit, unedit watch 指定されたファイルに変更があったときの通知を制御する  
readers 遠隔から実行するコマンド全て pserver経由のアクセスについて読み取りしか許可しないユーザを指定する。 writersより優先。
writers 遠隔から実行するコマンド全て pserver経由のアクセスについて読み書きのできるユーザを指定する。 readersの方が優先。
users notify notifyでメール通知を行う場合のユーザ名にメールアドレスを対応させる。

管理ファイルはどうやって編集するの

気がつかれたと思いますが、,v が各管理ファイルについていたということは、 これらの管理ファイルはバージョン管理されているということです。 他のモジュールと違って、CVSROOTはそのディレクトリの中に、 バージョン管理用の,vファイルと最新コピーが入っていることに なります。このため、管理ファイルを編集する場合には、 直接 /home/cvsroot/CVSROOT内のコピーをいじって、 RCSコマンドを介してバージョン管理をするか、 チェックアウトして編集を行い、 コミットするというCVSの普通の作業でバージョン管理するかする必要があります。 「チェックアウトして編集・コミット」というCVSの通常の操作だけで、 管理ファイルへの反映もおこなう仕組みがCVSには組み込まれていますので、 それを使うのが楽です。 ひとまず、CVSROOTの作業コピーをチェックアウトしてみましょう【図5.2】。上であげた16個のファイルのうちpasswd、readers、writers、users、cvsignoreをのぞく11個がコピーされてきたことがわかります。

図5.2 CVSROOTを手元に取ってくる

% cvs checkout CVSROOT

cvs checkout: Updating CVSROOT

U CVSROOT/checkoutlist

U CVSROOT/commitinfo

U CVSROOT/config

U CVSROOT/cvswrappers

U CVSROOT/editinfo

U CVSROOT/loginfo

U CVSROOT/modules

U CVSROOT/notify

U CVSROOT/rcsinfo

U CVSROOT/taginfo

U CVSROOT/verifymsg

このうち、試しに configファイルを編集してみましょう。configファイルの中に設定できるパラメータは、現在のところ、SystemAuth、TopLevelAdmin、PreservePermissions、LockDirの4つです。このうち、SystemAuthは「CVSを遠隔から使えるようにしよう」の項目で説明します。TopLevelAdminは、モジュールを取ってきたとき、モジュールの内部だけでなくその上のディレクトリにもCVSディレクトリを作るようにするためのパラメータです。何が嬉しいかといいと、細々としたモジュールをまとめて扱うときに便利なようです。あと、リポジトリを沢山使い分けている人も、同じリポジトリを同じディレクトリにまとめるのに役に立つかもしれません。でも、あまり使い道がない気がするので、設定しなくても構いません。PreservePermissionsはファイル属性を保持したい場合に設定しておきます。前章の特殊ファイルのところで説明したように、シンボリックリンクも取り扱えるようになります。複数人での共同作業の場合にはあまり意味がありませんが、個人のバックアップ用に利用するような場合には設定するメリットがあるでしょう。LockDirは、作業中にロックファイルを作るディレクトリを指定するためのパラメータです。リポジトリに書き込み許可を持たないユーザがリポジトリを利用できるようにするために設定します。WWWでの公開などで、httpdの実行ユーザが利用する必要があるようなときには、設定することを考えるといいでしょう。

ここでは、他では紹介しないTopLevelAdminについて設定してみて、その挙動をみてみます。まず、CVSの1.10.8についてくるconfigファイルについてみてみましょう。

図5.3 1.10.8 についてくるconfig ファイル

# Set this to "no" if pserver shouldn't check system users/passwords

#SystemAuth=no



# Set `PreservePermissions' to `yes' to save file status information

# in the repository.

#PreservePermissions=no



# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top

# level of the new working directory when using the `cvs checkout'

# command.

#TopLevelAdmin=no

最初configファイルには、SystemAuthとPreservePermissions、TopLevelAdminの3つのパラメータがコメントとして書かれています。LogDirについては書かれていません。ここでは、実験的に最終行の先頭の#を外して有効にし、かつTopLevelAdmin=yesに書き換えます。そして、これを、コミットします【図5.4】。

図5.4 config ファイルをコミットする
% cvs commit -m "TopLevelAdmin Test On" config

Checking in config;

/home/cvsroot/CVSROOT/config,v  <--  config

new revision: 1.10; previous revision: 1.9

done

cvs commit: Rebuilding administrative file database

コミットの手順自体は、通常のモジュールと変わりませんが、最後にリポジトリ側の管理ファイルを作りなおしているところがちょっと違います【図5.4 6行目】。

図5.5 別の場所に作業コピーを取ってみる
% cvs -d /home/cvsroot checkout cvstest

cvs checkout: Updating cvstest

U cvstest/fish.jpg

(中略)

U cvstest/test2.txt

% ls -F

CVS/  cvstest/



% ls -F CVS

Entries  Entries.Log  Entries.Static  Repository  Root



% cat CVS/Entries.Log

A D/cvstest////

% cat CVS/Root

/home/cvsroot

% cat CVS/Repository

.

ここで、他の場所にちょっと作業コピー(なんでもいいです)を作ってみる【図5.5 1行目】と、今までできなかった、CVSというディレクトリがモジュールと同じ場所にできていることを確認できます【図5.5 6行目】。中身があるのはひとまず、Entries.LogとRoot、Repositoryです。これで、CVSROOT環境変数や-dを使ってリポジトリを切り替えなくても、このディレクトリに入れば、同じリポジトリに対する操作が可能となりました。


CVS を遠隔から使えるようにしよう

CVS を遠隔から使うにはどうすればいいの?

cvs コマンドを使って遠隔のリポジトリにアクセスするには、CVSROOT 環境変数もしくは -d オプションで、リポジトリを「接続に必要な情報を含んだ形で」指定するだけです。その指定形式は、図5.6のようになります。

図5.6 遠隔リポジトリの指定形式
:接続方法:ユーザ名@サーバ名:サーバ上でのリポジトリパス

例えば、mika というユーザが pserver という接続方法で cvs.mydomain.com というサーバ上の /home/cvsroot というリポジトリからcvstestというモジュールをチェックアウトしたい場合には、

cvs -d :pserver:mika@cvs.mydomain.com:/home/cvsroot checkout cvstest

というように指定します。ここで、接続方法には、ext, server, pserver, gserver, kserver, fork の6つがあります。また、これとは別に、明示的にローカルであることを示すために、local という接続方法も指定できます。この場合にはユーザ名とサーバ名は必要ありません。nserverという方式もあるそうですが、CVSの本流にまだ取り込まれていないということなので触れません。

どの接続方法を使えばいいの?

これらの接続方法は、ユーザの環境や用途によって使い分ける必要があります。どんなサーバでもそうですが、 使い勝手とセキュリティのトレードオフを考慮する必要があります。 つまり、簡単な方法は一般にセキュリティが低く、 セキュリティの高い方法は初期設定や使い方が難しいです。 一般的に使用される ext と pserver の設定例を分類すると表5.2のようになります。

表5.2

サーバタイプ 外部プログラム 認証 データの暗号化 必要設定 用途
ext(server) rch (なし) rhosts 認証 なし rhosts の設定 イントラネットでの共有
ext ssh ssh の認証 ssh により暗号化 環境変数 CVS_RSH に ssh を設定 インターネットでの共有
pserver なし 独自 passwd ファイル なし pserver の設定 インターネットでの公開

gserver, kserver, fork は、一般的でないのと、私も良く知らないので簡単に説明するだけにします。 gserver と kserver は Kerberos という認証システムを使用していて、 サーバクライアントともに Kerberos が組み込まれていないといけません。 Kerberosは暗号方式の輸出問題にからんで日本では一般的ではありません。gserver は Kerberos 5, kserver はKerberos 4 いう Kerberos のバージョンにそれぞれ対応しています。fork は実行すると、クライアントとサーバの2つのプロセスに分かれて、通信をしてデータのやり取りをします。これは、デバッグのための機能ですので、プログラマ以外の普通の人は気にしなくていいです。 普通に cvs をサーバにするには、ext と pserver のどちらかの接続方法を使 います。

ext って何?

ext とは、external か何かの意味で、 接続するために外部プログラムを呼び、そのプログラムを介してシステムに登録されたユーザでの認証を 行います。 接続に利用する外部プログラムは環境変数 CVS_RSH に設定します。 CVS_RSH が設定されないと、rsh を呼びます。 しかし、rsh はパスワードも素のまま流れますし .rhosts や /etc/rhosts などではかなり安易に相手ホストを信用するような設定をおこなうため、 よほど信頼のおけるイントラネットでないと実際には使えません。 一般に、通信が暗号化されていないようなログイン方法だと、 パスワードもデータもそのまま流れてとても危険です。 インターネットでの利用はもちろん、イントラネットでもなるべく避けた方がよいでしょう。 お勧めは、外部プログラムとして ssh を利用する方法です。

ssh を使えば、ユーザ認証もデータ転送も暗号化されます。ssh の設定法や利用法はこの本の範囲を超えていますので、書きません。検索すれば情報は沢山でてきますので、参考にしてください。現在2000年12月時点では OpenSSH が評判がいいです。OpenSSH は RHL 7 には標準で入っていますので、man ssh などして利用法を確認してください。RHL 6.x 以前では、別途インストールが必要です。sshが入っていれば、CVS_RSHにsshを設定すれば、少なくともいちいちパスワードやパスフレーズの入力を行うことで接続できるようになります。

CVS_RSHの設定は以下のようになります。

csh 系シェル

setenv CVS_RSH ssh
sh シェル系 CVS_RSH=ssh; export CVS_RSH

 

この設定を行ったとしてextでのリポジトリの指定でコマンドを実行してみると図5.7のようになります。この例では、sshの個人環境設定は特に行っていないので、システムパスワードを聞いてきます【2行目】。これに正しく入力すると接続が行われ、接続先でcvsのコマンドがサーバモードで実行されます。その結果の出力がネットワークを介して送られてきて、それをクライアント側で処理することで、遠隔でも同じように使えるということになります。

図5.7 SSHを使ってコマンドを実行してみる(プレーンパスワード)
% cvs -d :ext:mika@localhost:/home/cvsroot checkout cvstest

mika@cvs.mydomain.com's password:

cvs server: Updating cvstest

U cvstest/test.pl

U cvstest/test.tex

通常はシステムのパスワードをそのまま使うのではなく、RSA公開鍵暗号による認証をおこないます。手順は結構複雑ですので、SSH関係の説明ホームページなどで調べて下さい。

※「簡単SSH」
http://www.netlab.is.tsukuba.ac.jp/~one/ssh/

なお、server という接続方法は、cvs 内部に実装された rsh を利用して接続する方法で、cvs の種類によっては使えなくなっています。筆者はこれが使える実装に出会ったことがありません。

pserver って何?

pserver は password server の意味です。 システムのパスワードファイルとは別のパスワードファイルを作成することができ、 そのファイルに書かれたユーザ名とパスワードに基づき認証を行います。 この方法の良いところは、システムに普通にログインするための ユーザ名とパスワードとは別に pserver 用のユーザ名とパスワードが設定で きるので、外部からシステムのユーザ情報が隠せるということです。 しかし、パスワードやデータは暗号化されませんので、機密性を要する用途にはこのままでは使えません。インターネット上でデータを公開するためには使えます。これにさらに通信路を暗号化したいという場合は、SSL 認証を使った stunnel などを利用するといいと思われますが、実際に運用したことはありません。

ここでは、pserver の設定法について説明します。pserver の設定は、「管理ファイルの設定」と「サーバとしての設定」という2つの手順からなります。

管理ファイルの設定って何?

CVSがpserverとして働くときは、 ユーザ認証を行いアクセスが許されたユーザかどうかチェックします。 この認証をちゃんと設定しておかないと、 思わぬ人がアクセスできたりして、危険です。 特に、自分が何をしているのかよくわからない場合には、 きつめに設定しておきましょう。 pserverの認証に関わる管理ファイルは、configとpasswdです。 passwdは、最初の状態では存在しませんから、 自分で作成して追加するということをします。

  1. configファイルの設定

    まず、管理ファイルconfigでの設定ですが、設定項目は1つだけです。 SystemAuthというパラメータを設定できるのですが、 それをnoにしておきます【図5.8】。 このパラメータは、 認証要求のあったユーザがpasswdファイルに登録されたユーザでなかった場合に、 システムのユーザとして認証するかどうかというものです。 つまりmikaというユーザ認証の要求があって、且つ このユーザがpasswdファイルに登録されていなかったときに、 システムのユーザにmikaがいるか調べるかということです。

    yesに設定するとシステムのユーザまで対象にします。 noにしておけば、passwdファイルのユーザしか対象にしません。 なるべく、対象をしぼっておくためにnoにしておきましょう。 システムのユーザを対象とする危険性は、主にネットワークを そのパスワードが流れることです。 なお、passwdファイルでのユーザ名とパスワードを システムのものと同じにしてしまったら意味がありません。 違うものを使うようにしましょう。

    図5.8 config ファイルの変更部分
    SystemAuth=no

  2. passwdファイルの作成と登録

    ユーザの制限が終わったら、 アクセスできるユーザを設定しないと誰も使えません。 ということで、 passwdファイルにアクセスできるユーザを登録していきます。 passwdファイルは、他の管理ファイルと違って、まずバージョン管理下にはおかれていません。CVSROOT直下のpasswdファイルを編集するという形になります。バージョン管理下に置くと、読み取りのみのアクセスでもパスワードファイルが取得できて危険です。その危険に目をつぶってバージョン管理下においても、自動的に再構築されるようにはなりません。これは、アクセス制限が緩かったりすると、他の人がCVSROOTに書き込むことができるからです。passwdファイルが再構築されるように設定されていると、簡単にpasswdファイルにユーザを追加できてしまいますね。とはいえ、chekoutlistにpasswdを登録してしまえば、再構築されるようにすることは可能なわけで、気休め程度ではあります。pserverを使う場合には、他のユーザがCVSROOTへ書き込めないようにしておくのが第一であり、その上でpasswdファイルを読みとられないようバージョン管理下には置かない、というのが良いと思います。CVSROOTのアクセス権の制御については、6章に詳しいので見ておいて下さい。以下では、リポジトリにあるCVSROOTの中のpasswdファイルを直接編集することを仮定しています。

    この手法の最大の問題点は、 ユーザのパスワードを暗号化してpasswdファイルに書かなければならないのに、 暗号化の手段をCVSが提供していないということです。 つまり、どこからかパスワードを暗号化するツールを取ってくるか、 自分でごりごり作るかしないといけません。 あるいは、passwdコマンドでユーザのパスワードを変更して、 /etc/passwd(もしくは/etc/shadow)に生成されたパスワードを カットアンドペーストしてくるという手もあります。 しかし、これはroot権限がないと難しいかもしれません。 筆者はWWWサーバであるapache httpdについてくる、 htpasswdを流用して使っています。

    自力でがんばる場合には、 スクリプト言語であるperlのcrypt関数を利用するのが最も簡単だと思われます。 基本は、crypt("pass phrase", "xx")という形で、 暗号化したい文字列を第1引数に、 それにちょっと味付けをするための塩(salt)を第2引数に加えます。 saltに渡せるのは、[a-zA-Z0-9./]の任意の2文字です。 例えば、図5.9のように、パスワードを"^Hi-h0&="に、saltを".0"にした場合【1行目】、 ".0mE4ugRRj9r."という文字列が生成されます【2行目】。 saltを考えるのが面倒だったら、 それをランダムに生成するためのコードをつけてスクリプトとして用意しておくと良いでしょう。

図5.9 暗号化された文字列を得る
% perl -e 'print crypt("^Hi-h0&=", ".0"), "\n";' 

.0mE4ugRRj9r.

どんな方法でも良いですが、パスワードが暗号化できたら、 passwdファイルを作成します。 passwdファイルには1行に一人のユーザを設定します。 1行の書式は以下のようになります。

図5.10 passwdファイルの1行の書式
CVSのユーザ名:パスワード:システムのユーザ名

ここで、第1項目のユーザ名と第2項目のパスワードが pserverにアクセスするためのユーザ名とパスワードです。 第3項目のユーザは、第1項目のユーザ名でアクセスした場合に、 実際にどのシステム側ユーザとしてコマンドが実行されるのかを 設定する部分です。 例えば、bmikaとanonymousというユーザを設定してみると、 図5.11のようになります。 bmikaとanonymousはシステム内では実際には、 mikaとanonというユーザにあたります。

図5.11 完成したpasswd ファイル
bmika:ROHNP9.5MUyIs:mika

anonymous:gB/FnBTDLRODw:anon
@追加部分削除

サーバの設定って何?

CVS は独立したサーバとしては動きません。つまり、起動するとバックグラウンドに入り、待ち受け、通信などの全ての処理を自力で行うようなサーバではない、ということです。そのかわりに、UNIX で通信の待ち受けを肩代わりしてくれるシステムである inetd (RHL 7 では xinetd) を利用します。telnet や ftp もこの inetd を利用しています。 inetdはそういったプログラムのかわりに、あらかじめ指定されたポートを見張って通信の要求がくるのを待ち受けてくれます。指定のポートに接続要求が来たら、接続を確立してポートに割り当てられたプログラムを呼び出してくれます。この、どのポートがどのプログラムに対応していて、どのように呼び出せばいいかという設定は、/etc/inetd.confというファイルに書いておきます。CVSのpserverを設定するためには、inetd.confに図5.12のような行を追加します。

図5.12 /etc/inetd.confへの追加(tcpdを挟む場合)
# CVS pserver

cvspserver stream tcp   nowait  root /usr/sbin/tcpd /usr/bin/cvs -f --allow-root=/home/cvsroot pserver

ここで、第1項目のcvspserverはポート番号です。次の第2,3,4項目のstream, tcp, nowait というのは通信方法で、第5項目rootがプログラムの実行ユーザを指定しています。第6項目が呼び出すプログラムのパスを指定する場所ですが、通信の制限を行うために、cvsを直接書くのではなく、一旦tcpdというプログラムを間に挟む設定をしています。次の第6項目以降が実際に呼び出されるプログラムと、その引数(--allow-root=/home/cvsrootとpserver)になります。引数のうち、pserverというのがcvsをサーバとして動作させるためのcvsのコマンドです。全体にかかるオプションである-fはユーザ毎のホームディレクトリに初期設定ファイルを読みにいくようにするためのオプションです。-fがないとrootのホームをみにいくようです。また、--allow-rootオプションはアクセスできるリポジトリを制限するためのものです。つまり、このサーバを介した状態では/home/cvsrootというリポジトリにしかアクセスできないということです。

ちなみに複数のリポジトリにアクセスできるように--allow-rootを複数設定しようとすると、inetd.confの一行に設定可能な文字数を越えてしまいます。そういう時は、シェルスクリプトでcvsコマンドをくるんで、そのシェルスクリプトを呼び出すということをするといいでしょう。

tcpdは、/etc/hosts.deny, /etc/hosts.allowといったファイルで接続の制限をします。その設定法などは本書の範囲を超えているので、各自で調べてください。自マシンと自ドメインのみの接続許可を出す設定例だけ図5.13と図5.14に示しおきます。ドメイン名(mydomain.com)とネットワーク/ネットマスク(192.168.0.0/255.255.255.0)はそれぞれの環境にあったものを設定してください。

図5.13 /etc/hosts.deny
ALL: ALL

図5.14 /etc/hosts.allow
ALL: localhost 127.0.0.1 .mydomain.com 192.168.0.0/255.255.255.0

tcpdはインターネットに直接つなぐ計算機の自衛方法としては基本的なプログラムですので、なるべく使えるようにしておいた方が良いと思います。パッケージ名はtcpwrapperといいます。最近のRedHatLinuxには最初から入っていますが、入ってなくて入れ方もわからないという場合は、危険ですがcvsを直接呼び出すように設定することはできます【図5.15】。また、公開サーバでとくに制限する必要がないという場合もこのように設定すれば良いでしょう。

図5.15 /etc/inetd.confへの追加(tcpdを挟まない場合)
# CVS pserver

cvspserver stream tcp   nowait  root /usr/bin/cvs cvs -f --allow-root=/home/cvsroot pserver

なお、/etc/inetd.confで最初のポート番号の指定で、cvspserverという文字列を指定しましたが、これはあらかじめ/etc/servicesの中にポート番号の別名として登録されていなければなりません。最近のRedHatLinuxではあらかじめ入っていますが、他のOSの人は入っているか確認して、なかったら図5.16のような行を追加しておいてください。

図5.16 /etc/servicesの設定部分
cvspserver      2401/tcp                        # CVS client/server operations

cvspserver      2401/udp                        # CVS client/server operations

このように/etc/inetd.confおよび/etc/servicesの設定が完了したら、inetdにその変更を反映してやらなければなりません。変更の通知は再起動でもいいですし、killコマンドでHUP(ハングアップ)信号を送りつけ(kill -HUP)ても構いません。

RedHatLinux6.xでは、起動スクリプトを利用するのが簡単です。図5.17のように/etc/rc.d/init.d/inetに引数restartを指定して、inetdを再起動しましょう。

図5.17 inetd の再起動(RHL6.x)
/etc/rc.d/init.d/inet restart

Solarisにも起動スクリプト(/etc/init.d/inetsvc)はあるのですが、余計なものも沢山動かしているようなので、私はもっぱらkill -HUPで再初期化を行っています。inetdのプロセス番号をpsで探し、そのプロセス番号にHUP信号をkillで送りつけます。SolarisのpsコマンドはSysV系で、BSD系とはオプションが異なります。詳しくは、manで見て下さい。それがいやな場合は、/usr/ucbの下にあるpsコマンドを使うようにするといいでしょう。

図5.18 inetd の再初期化(SolarisでHUP)
% ps -ef | grep inetd

root   120     1  0 04:01:21 ?        0:00 /usr/sbin/inetd -s

% kill -HUP 120

RedHatLinux7.xでは、inetdがxinetdに置き換わってしまっています。初期設定ファイルの書き方も大幅に変わってしまっています。とはいえ、書く内容自体はほとんど変わりません。上のtcpdを使用しない場合の設定と同じ設定を行うためのファイルを図Xに示します。これを、/etc/xinetd.dというディレクトリの下にcvspserverという名前で置きます。ファイル名はおそらくなんでも良いのだと思いますが、サービス名と一緒にしておきます。1行目serviceは/etc/servicesでの記述のポートの別名を書きます。次に、socket_type, wait, user といった項目に前と同じようにstream, no, rootを設定します。serverというのが実行されるプログラムであり、/usr/bin/cvsを設定します。このとき、cvsは引数を必要としますから、その引数-fと--allow-root=/home/cvsroot pserverをserver_argsに書きます。

tcpwrapper(tcpd)の動作は、serverに書こうと書くまいと同じでした。ですから、この場合は書かなくても、/etc/hosts.deny, /etc/hosts.allowで制御できるのだと思います。

図5.19 /etc/xinetd.d/cvspserver
service cvspserver

{

        socket_type             = stream

        wait                    = no

        user                    = root

        server                  = /usr/bin/cvs

        server_args             = -f --allow-root=/home/cvsroot pserver

}

このファイルを/etc/xinetd.d/cvspserverとして置いたら、xinetdを再起動します【図x】。kill -HUPではうまくいきませんでした。

図5.20 xinetd の再起動(RHL7.x)
/etc/init.d/xinetd restart

inetdを設定したあとは、通常telnetにポートを指定してテストをします。つまり、図Xのようにします。

図5.21 telnetでの接続テスト
% telnet localhost cvspserver

Trying 127.0.0.1...

Connected to xxx.xxx.xxx.

Escape character is '^]'.





cvs [pserver aborted]: bad auth protocol start:





Connection closed by foreign host.

接続できると、3行目にConnected to xxx.xxx.xxxというようなメッセージが出ます。これが出ずに、図XのようなConnection refused メッセージが出た場合にはうまく設定できていませんので、再度設定を見直してください。接続後はリターンでもなんでも入力すれば、手順と違うといってcvsから切断されます。もちろん、Cntl-]でいったんtelnetの対話モードに戻って、終了してもかまいません。

/etc/inetd.confの記述で間違いやすいのはコマンドのパスです。/etc/servicesを自分で書き換えた場合は別名の綴りもチェックした方がいいやもしれません。

図5.22 接続できないときのメッセージ
telnet localhost 2402

Trying 127.0.0.1...

telnet: Unable to connect to remote host: Connection refused

cvsクライアントからの接続テスト

inetdで接続できることを確認したら、cvsのクライアントから接続できるかサーバが動いているマシンで、テストしてみましょう。cvsでクライアントから接続するの手順は、次のようになります。同じマシンに接続する場合は、マシン名を指定しても良いのですが、localhostという名前を使う方が一般的です。

  1. cvs の loginコマンドを使って、認証し認証情報を保存する。

    cvsのloginコマンドは実行すると、指定されたリポジトリに接続し、パスワード入力を促します。 パスワードを入力すると、cvsサーバへ接続して、認証をおこないます。認証がうまくいくとユーザのクライアント側のホームにある .cvspass というファイルにその情報を格納します。

  2. 図5.23 loginしてpasswordを保存する
    % cvs -d :pserver:bmika@localhost:/home/cvsroot login
    
    (Logging in to bmika@localhost)
    
    CVS password:
    図5.24 ~/.cvspass
    :pserver:bmika@localhost:/home/cvsroot A:0=:0]0
  3. 任意のcvsのコマンドを実行する。

    いったん .cvspassに認証情報を保存してやれば、他のコマンドの実行をサーバに通知するときにはその情報を送るようになります。実は、コマンドの実行の度にこの.cvspassの情報を元に認証が行われています。これは、コマンド実行が一回一回独立しているためです。cvsには、前のコマンドの実行と次のコマンドの実行が同じ人物かどうかを知るすべがありません。そのため.cvspassの情報をもとに同一かどうかを判断するという機構になっています。

  4. cvs の logoutコマンドを使って、認証情報を除去する。

    .cvspassにずっと認証情報を保持していてもいいといえばいいのですが、他の人が同じ環境で作業する場合や、そもそも気持ち悪いという場合には、logoutコマンドを使って.cvspassの認証情報を削除しておきましょう。当然、次回cvsのコマンドを実行する場合にはloginで再び認証情報を格納するところからはじめなければいけません。

これがうまくいけば、外部から実際に同じようにして接続してみてください。外部から接続できない場合には、上でtcpdを介した場合の制限や外部のファイアーウォールなどの原因が考えられます。サーバの運用というのはいろいろと複雑な要因が絡んできますので、きちんと動かすまでには、ひとつひとつ原因と思われるものを確認して除いていくことが大事です。がんばって下さい。


漢字コード変換を設定してみよう

通常は Mule for Win やその他漢字コードに自動的に対応している エディタを使用していても、 例えば、TeX のファイルで作業しているような場合に、 UNIX の方では EUC しか通らないし、Windows の方は SJIS しか通らない ということがあります。 こんな時は、やはり少なくともTeXのファイルはそれぞれの環境に合わせて変換したいということになります。

cvswrappersを設定しよう

knjwrp patch を適用してコンパイルした場合には、管理ファイルのcvswappersに以下の記述が追加されているはずです。

図5.25 cvswappers に追加された漢字コード変換のための行
#*.c    -f '/usr/lib/cvs/contrib/wrapnkf -s %s' -t '/usr/lib/cvs/contrib/wrapnkf -e %s %s' -s

この行を説明してみましょう。まず、#はコメント行の意味で、この行は実際には機能していません。この行を元に自分の環境に合ったカスタマイズをするということになります。最初の*.cはファイルのパターンを意味します。このパターンに適合したファイルに対して、その行の残りの部分が適用されます。残りの部分は、-f, -t, -s というオプションとそれらの引数のならびになっています。-fはfromの意味でリポジトリから外部に出ていくファイルに対して適用されるフィルタの指定であり、-tはtoの意味で外部からリポジトリに入ってくるファイルに対して適用されるフィルタを指定しています【図5.25'】入ってくる場合というのはcommitです。出ていく場合というのは、主にcheckoutとupdateですが、実はcommit時にも入ったりしています。

図5.25' cvswappers の-fと-tのイメージ

-sはknjwrp patchで拡張された書式で、-sがついている場合にのみremote-clietについてcvswrappers処理を有効にするというものです。-sオプションは漢字コード変換をする場合は書いておいて下さい。-fオプションと-tオプションには/usr/lib/cvs/contrib/wrapnkf という同じフィルタが指定されていますが、その引数-sと-eで動作が切り替えられています。

漢字コード変換フィルタを作ろう

どのようになっているか、このファイルをのぞいてみましょう。このフィルタはknjwrp patchをあてた後、ソースツリーの中のcontribの下に作られます。

図5.26 wrapnkfの中身
#! /bin/sh

#

# wrappper nkf filter for cvs-server/windoze-clients

#

# Usage: wrapnkf kanji_code infile [outfile]

#



ACK=/usr/local/bin/ack

NKF=/usr/local/bin/nkf

opt=$1

infile=$2

outfile=$3



if [ $opt = "-e" ] ; then

        $ACK -u -e -z $infile > /tmp/ack-cvs$$

        mv -f /tmp/ack-cvs$$ $outfile

elif [ $opt = "-s" ] ; then

    $NKF -s $infile > /tmp/nkf-cvs$$

    mv -f /tmp/nkf-cvs$$ $infile

fi;

見てもらうとわかると思うのですが、wrapnkfの実体はシェルスクリプトで、内部でackとnkfという一般的な漢字コード変換プログラムを呼び出しています。これらのプログラムはGNUではないですが、フリーウェアとして配布されています。それぞれのホームページからダウンロードしてインストールして下さい。インストール方法はMakefileを自分の目的に合わせて修正し、makeし、適当な場所へ実行ファイル他をコピーするだけです。RedHatLinuxの日本語版にはnkfがついてきています。debianでは、ackもパッケージとして用意されているようです。なお、knjwrp patchをあてた場合には、ソースツリーの中にackのディレクトリも作成されます。使用する場合には、そのソースを利用して作ってもよいでしょう。

※ nkfのホームページ(琉球大学 河野 真治さま)
http://rananim.ie.u-ryukyu.ac.jp/~kono/software.html

※ ackのホームページ(VECTOR内 小笠原 博之さま)
http://www.vector.co.jp/soft/unix/util/se064384.html

おおまかに、UNIXとDOS/Windowsのファイルの形式には以下の違いがあります。また、DOS/Windowsのファイルには半角仮名が含まれていることがあり、これはUNIX環境では問題を引き起こすことが多いため、UNIXにファイルを転送する場合には変換しておくことが望ましいです。

  漢字コード 行末 ファイル終わり(EOF)
UNIX EUC LF (0x0a)  
DOS/Windows SJIS CR/LF (0x0d, 0x0a) 0x1a(Cntl-Z)がつくことがある
Mac(おまけ) SJIS CR (0x0d)  

ackではDOS/Windows環境からUNIX環境へファイルを適合させるために必要な変換を3つのオプションでおこなっています。

ack のオプションの意味

-e 出力コードをEUCにする
-u 入力の0x0d(CR)および0x1a(Cntl-Z)を取り除く
-z いわゆる半角仮名->全角仮名変換をおこなう

なお、同じ変換はnkf1.92でも行うことができます。0x1a(Cntl-Z)の削除は、nkfではできないようですので、UNIXの一般的な置換コマンドであるtrの削除オプション-dを使って削除するといいでしょう。0x1aは8進数では32になります。

nkf で同様の変換を行うためのオプション

-e 出力コードをEUCにする(半角仮名->全角仮名変換含む)
-Lu 行末を0x0a(LF)に変換する

 

一方、UNIX環境からDOS/Windows環境へファイルを適合させるために必要な変換は少なくとも2つあると思うのですが、wrapnkfではSJIS変換しかしていませんね。これは、cvsが自動的に変換してしまうからのようです。行末を0x0d,0x0a(CR/LF)に変換する-Lwというオプションがあるのですが、今回は使う必要がありません。

nkfでUNIXにファイルを適合させるためのオプション

-s シフトJISコードを出力する

これらの検討から、次のようにwrapnkfを作り直してwrapnkf2としてみました。自分の環境に合わせたフィルタを各自作られると良いかと思います。

図5.27 wrapnkf2
#! /bin/sh

#

# wrappper nkf filter for cvs-server/windoze-clients 2

#

# Usage: wrapnkf2 kanji_code infile [outfile]

#

NKF=/usr/bin/nkf

# Line Terminator: CR/LF->LF(-Lu), LF->CR/LF(-Lw): No use

# Kanji Code: SJIS(-s), EUC(-e) including hankaku->zenkaku

TR=/usr/bin/tr

# Cntl-Z=\032(0x1a)



opt=$1

infile=$2

outfile=$3



if [ ${opt} = "-e" ] ; then

    ${NKF} -eLu ${infile} | ${TR} -d '\032' > /tmp/unkf-cvs$$

    mv -f /tmp/unkf-cvs$$ ${outfile}

elif [ ${opt} = "-s" ] ; then

    ${NKF} -s ${infile} > /tmp/wnkf-cvs$$

    mv -f /tmp/wnkf-cvs$$ ${infile}

else

    echo "Usage: wrapnkf2 [-s|-e] infile [outfile]"

fi;

フィルタを管理しよう

このファイルもCVSの管理下に置きたいと思います。CVSROOTの下に管理ファイルとして追加してみましょう。そうすれば、ばらばらにならなくてすみます。通常の管理ファイル以外のものを、管理ファイルと同じように扱うには、checkoutlistファイルに追加する必要があります。

図5.28 checkoutlistファイル
# The "checkoutlist" file is used to support additional version controlled

# administrative files in $CVSROOT/CVSROOT, such as template files.

#

# The first entry on a line is a filename which will be checked out from

# the corresponding RCS file in the $CVSROOT/CVSROOT directory.

# The remainder of the line is an error message to use if the file cannot

# be checked out.

#

# File format:

#

#       [<whitespace>]<filename><whitespace><error message><end-of-line>

#

# comment lines begin with '#'

wrapnkf2 Kanji Wrapper checkout failed

checkoutlistファイルの書式は一行に一つのファイルの設定になっています。最初にファイルの名前がきて、次に空白が入りそのあと行末までがエラーメッセージとして取り扱われます。エラーメッセージはなんらかの理由でこのファイルが取り出せなかったときに出力されるメッセージです。適当で構いません。この設定が終わったら、wrapnkf2をaddして、同時にコミットしておきましょう。管理ファイルが再構築されて、/home/cvsroot/CVSROOT/wrapnkf2ができていれば成功です。

図5.29 wrapnkf2を管理ファイルとして追加する
% cvs add -m "Kanji Wrapper" wrapnkf2

cvs add: scheduling file `wrapnkf2' for addition

cvs add: use 'cvs commit' to add this file permanently

% cvs commit -m "New administerative file: wrapnkf2"

Checking in checkoutlist;

/home/cvsroot/CVSROOT/checkoutlist,v  <--  checkoutlist

new revision: 1.2; previous revision: 1.1

done

RCS file: /home/cvsroot/CVSROOT/wrapnkf2,v

done

Checking in wrapnkf2;

/home/cvsroot/CVSROOT/wrapnkf2,v  <--  wrapnkf2

initial revision: 1.1

done

cvs commit: Rebuilding administrative file database

cvswrappersに設定してみよう

そして、cvswrapprsに以下の行を追加します。

図5.30 cvswrappersに追加する行
*.tex   -f '/home/cvsroot/CVSROOT/wrapnkf2 -s %s' -t '/home/cvsroot/CVSROOT/wrap

nkf2 -e %s %s' -s

これをやはりコミットして、動作を確かめてみて下さい。つまり、test.texというようなおしりに.texのついたファイルを作って、UNIXとWindowsでやりとりをしてみて下さい。ちゃんと、変換できていることが確認できましたか?できたことを確認したら、他の実際に変換したいファイルについて設定をしてください。