2007年7月25日水曜日

玄箱でIMAPメールサーバを構築 ~ fetchmailのインストール

fetchmailは、POPサーバやIMAPサーバから、メールをとってくるソフトウェアです。



ネットワークプロバイダなど、リモートのメールサーバ上にあるメールボックスから、fetchmailにより、POPプロトコルでメールをダウンロードして、玄箱のメールボックスに保存します。



そして、Windows上で実行するMozilla Thunderbirdなどのメールソフトで、玄箱のIMAPサーバにアクセスして、メールを読む、という使い方を想定しています。





■ いきなりつまづいた・・・



fetchmailのソースコードを展開します。



% tar zxvf fetchmail-6.3.8.tar.bz2



玄箱でコンパイルします。configureのオプションは、なんとなく直感で、「./configure --with-ssl --disable-nls --disable-dependency-tracking --enable-fallback=no」としてみました。



さて、やってみると・・・



root@KURO-BOX:/mnt/share/200707/fetchmail-6.3.8# ./configure --with-ssl --disable-nls --disable-dependency-tracking --enable-fallback=no
checking build system type... powerpc-unknown-linux-gnu
checking host system type... powerpc-unknown-linux-gnu
checking target system type... powerpc-unknown-linux-gnu
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... no
checking for mawk... no
checking for nawk... no
checking for awk... awk
checking whether make sets $(MAKE)... yes
configure: autobuild project... fetchmail
configure: autobuild revision... 6.3.8
configure: autobuild hostname... KURO-BOX
configure: autobuild timestamp... 20070722-055646
checking for a Python interpreter with version >= 2.0... none
configure: WARNING: Disabling fetchmailconf: python 2.0 or greater not found
checking for gawk... (cached) awk
checking for gcc... gcc



 省略



checking for inet_ntop... yes
checking if your getaddrinfo is async-signal-safe... yes
configure: Enabling OpenSSL support in /usr.
checking for additional library dependencies of SSL... (none)
checking number of arguments to gethostbyname_r... 6
./configure: sort: command not found
configure: creating ./config.status
./configure: uniq: command not found
config.status: creating Makefile
config.status: creating m4/Makefile
config.status: creating po/Makefile.in
config.status: WARNING:  po/Makefile.in.in seems to ignore the --datarootdir setting
config.status: creating genlsm.sh
config.status: creating config.h
config.status: executing depfiles commands
config.status: executing default-1 commands
config.status: creating po/POTFILES
config.status: creating po/Makefile
./configure: sort: command not found
./configure: sort: command not found



sortuniqというコマンドがないといてエラーがでてますね。
makeを実行してみるとエラーになるので、やっぱり、sortをuniqをインストールすることにしました。



sort、uniqは、GNUなツールの、coreutilsというやつに含まれます(昔は、fileutilsという名前だった)。



というわけで、coreutilsをインストールします。


■ coreutilsをコンパイルしようとして、また、つまづいた



ファイルを展開します。



% tar zxvf coreutils-6.9.tar.bz2



configureのオプションは、またしても直感で、「./configure --disable-nls --disable-dependency-tracking」として(笑・・・configure --helpで眺めて決めてます)、やってみますと・・・



root@KURO-BOX:/mnt/share/200707/coreutils-6.9# ./configure --disable-nls --disable-dependency-tracking
checking build system type... powerpc-unknown-linux-gnu
checking host system type... powerpc-unknown-linux-gnu
configure: autobuild project... GNU coreutils
configure: autobuild revision... 6.9
configure: autobuild hostname... KURO-BOX
configure: autobuild timestamp... 20070722-151720
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... no
checking for mawk... no
checking for nawk... no
checking for awk... awk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes



 (省略)



config.status: creating tests/touch/Makefile
config.status: creating tests/tr/Makefile
config.status: creating tests/tsort/Makefile
config.status: creating tests/unexpand/Makefile
config.status: creating tests/uniq/Makefile
config.status: creating tests/wc/Makefile
config.status: creating lib/config.h
config.status: executing depfiles commands
config.status: executing po-directories commands
config.status: creating po/POTFILES
config.status: creating po/Makefile
./configure: sort: command not found
./configure: sort: command not found
root@KURO-BOX:/mnt/share/200707/coreutils-6.9#



またですか、「sort: command not found」!!!



sortをコンパイルするのに、sortが必要みたいです?!



きっと、coreutilsのドキュメントをじっくりと読めば、正しい対処方法があるかと思いますが、もういい、とやけになって、FreeBSD上でクロスコンパイルすることにしました。



以前、FreeBSD上に、玄箱のクロス開発環境を、作りましたから・・・

参考



FreeBSDに玄箱のクロス開発環境を構築






■ coreutilsをクロスコンパイル



なんだか、大げさなことになってきました(笑)。



クロスコンパイルするので、「--host」オプションを指定します。



./configure --disable-nls --disable-dependency-tracking --host=powerpc-hardhat-linux



でよさげです。


参考



FreeBSD上で玄箱用tcshをクロスコンパイル


以下のように、FreeBSD上で実行します。



FreeBSD % ./configure --disable-nls --disable-dependency-tracking --host=powerpc-hardhat-linux
configure: WARNING: If you wanted to set the --build type, don't use --host.
    If a cross compiler is detected then cross compile mode will be used.
checking build system type... i386-unknown-freebsd6.2
checking host system type... powerpc-hardhat-linux-gnu
configure: autobuild project... GNU coreutils
configure: autobuild revision... 6.9
configure: autobuild hostname... freebsd.local
configure: autobuild timestamp... 20070722-153657
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... build-aux/install-sh -c -d
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for powerpc-hardhat-linux-strip... powerpc-hardhat-linux-strip
checking for style of include used by make... GNU
checking for powerpc-hardhat-linux-gcc... powerpc-hardhat-linux-gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... yes
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether powerpc-hardhat-linux-gcc accepts -g... yes
checking for powerpc-hardhat-linux-gcc option to accept ISO C89... none needed
checking dependency style of powerpc-hardhat-linux-gcc... none
checking for powerpc-hardhat-linux-gcc option to accept ISO C99... unsupported
checking for powerpc-hardhat-linux-gcc option to accept ISO C89... (cached) none needed



(以下略)



configureは正常に完了しました。
つづいて、gmakeを実行します。



すると・・・なんだかコンパイルエラー。



powerpc-hardhat-linux-gcc  -I. -I../lib  -I../lib   -g -O2 -c remove.c
remove.c: In function `pop_dir':
remove.c:241: parse error before `top_len'
remove.c:242: `top_len' undeclared (first use in this function)
remove.c:242: (Each undeclared identifier is reported only once
remove.c:242: for each function it appears in.)
remove.c: In function `AD_stack_pop':
remove.c:376: parse error before `struct'
remove.c:377: `top' undeclared (first use in this function)
remove.c: In function `prompt':
remove.c:835: parse error before `char'
remove.c:839: `quoted_name' undeclared (first use in this function)
remove.c: In function `rm_1':
remove.c:1490: parse error before `struct'
remove.c:1491: `st' undeclared (first use in this function)
remove.c:1512: parse error before `enum'
remove.c:1513: `status' undeclared (first use in this function)
gmake[2]: *** [remove.o] Error 1
gmake[2]: Leaving directory `/.amd_mnt/kuro/host/mnt/share/200707/X/coreutils-6.9/src'
gmake[1]: *** [all] Error 2
gmake[1]: Leaving directory `/.amd_mnt/kuro/host/mnt/share/200707/X/coreutils-6.9/src'
gmake: *** [all-recursive] エラー 1



ソースコードをのぞいてみますと・・・



static inline void
pop_dir (Dirstack_state *ds)
{
  size_t n_lengths = obstack_object_size (&ds->len_stack) / sizeof (size_t);
  size_t *length = obstack_base (&ds->len_stack);

 

assert (n_lengths > 0);
  size_t top_len = length[n_lengths - 1];
  assert (top_len >= 2);



assertを実行したあとに、top_lenという変数宣言がされています。こういう書き方は、昔のコンパイラではエラーになっちゃうんです。変数宣言は、ブロックの先頭にまとめて書かないとダメなのでした。昔のC言語の規格では・・・
以前用意したクロスコンパイラは、gcc-2.95なので、ダメみたいです。gcc-3.xだときっと大丈夫だと思います。



というわけで、ソースを書き換えて、コンパイル。すると、また似たようなエラー。
また、ソースを書き換えて、コンパイル。すると、また似たようなエラー。
う~ん、いやんなってくるな・・・



で、とりあえず一通り、ソースの修正が終わって、コンパイルが完了しました。



ようやく、そのときになって気がついたのですが、「c99-to-c89.diff」という、なんかそのものずばりな名前のパッチがcoreutilsの中にはいってました。そのパッチをあてれば、自分でソースを変更する必要なんかないようでした。あーあ、無駄骨。



なお、サブディレクトリのmanで、makeがエラーになってしまうようです。



Making all in man
gmake[1]: Entering directory `/.amd_mnt/kuro/host/mnt/share/200707/X/coreutils-6.9/man'
Updating man page rm.1
help2man: can't get `--help' info from rm.td/rm
gmake[1]: *** [rm.1] Error 2
gmake[1]: Leaving directory `/.amd_mnt/kuro/host/mnt/share/200707/X/coreutils-6.9/man'
gmake: *** [all-recursive] エラー 1



これは、どうやら、「rm --help」コマンドを実行して、その出力結果を使って、マニュアルのテキストを反映させているっぽいです。クロス開発環境ではrmコマンドを実行できないですから、これは無理。manは、無視することにしました。



最上位ディレクトリ(topdir)のMakefileを書き換えて、manをSUBDIRSから抜いてもいいでしょう。まあ、エラーを無視すればいいだけのことですけど。



sysconfdir = ${prefix}/etc
target_alias =
top_builddir = .
top_srcdir = .
#SUBDIRS = lib src doc man po tests
SUBDIRS = lib src doc po tests



coreutilsには、数多くのコマンドが含まれているのですが、今は、sortとuniqだけがあればよさそうなので、sortとuniqだけを、玄箱の/usr/binにコピーしました。



参考までに。



root@KURO-BOX:/mnt/share/200707/X/coreutils-6.9/src# ldd sort uniq
sort:
        libm.so.6 => /lib/libm.so.6 (0x0ff68000)
        libc.so.6 => /lib/libc.so.6 (0x0fe18000)
        /lib/ld.so.1 => /lib/ld.so.1 (0x30000000)
uniq:
        libc.so.6 => /lib/libc.so.6 (0x0feb0000)
        /lib/ld.so.1 => /lib/ld.so.1 (0x30000000)



暇なら、これらを使って、クロスコンパイラではなく、玄箱でcoreutilsをビルドしなおしてもいいかもしれません。


■ ようやくfetchmailをビルドできた



クロスコンパイルして作ったsortとuniqのおかげで、fetchmailのconfigureは正常に完了し、makeも正常に完了しました。



root@KURO-BOX:/mnt/share/200707/fetchmail-6.3.8# ldd fetchmail
        libcrypt.so.1 => /lib/libcrypt.so.1 (0x0ffb3000)
        libresolv.so.2 => /lib/libresolv.so.2 (0x0ff80000)
        libssl.so.0.9.6 => /usr/lib/libssl.so.0.9.6 (0x0ff2d000)
        libcrypto.so.0.9.6 => /usr/lib/libcrypto.so.0.9.6 (0x0fe23000)
        libc.so.6 => /lib/libc.so.6 (0x0fcd3000)
        libdl.so.2 => /lib/libdl.so.2 (0x0fcb0000)
        /lib/ld.so.1 => /lib/ld.so.1 (0x30000000)


■ そういや玄箱にはsendmailがない



fetchmailは、デフォルトでは、リモート環境のメールサーバからダウンロードしてきたメールを、SMTPプロトコルで、ローカル環境のメールサーバに流しこむみたいです。



FreeBSDの場合、sendmailが動いているので、そのsendmailを通じて、/var/mail/ユーザー名に、保存されているみたいです。メールReceivedヘッダをみると、こんなかんじになるのでわかります。



Received: from freebsd.local (localhost [127.0.0.1])
    by freebsd.local (8.14.1/8.13.4) with ESMTP id うんたら
    for <ユーザー@localhost>; Tue, 24 Jul 2007 09:21:59 +0900 (JST)
    (envelope-from なんと@かんとか)
Received: from プロバイダのPOP3メールサーバ [IPアドレス]
    by freebsd.local with POP3 (fetchmail-6.3.8)
    for <ユーザー名@localhost> (single-drop); Tue, 24 Jul 2007 09:21:59 +0900 (JST)



sendmailがないときは、ローカル配送メーラと呼ばれる類のツールで代用することができます(通常、/bin/mailなどがそうです)。



さて、玄箱では、sendmailはおろか、mail関係のツールはなにも入ってませんでした。どうしようかな、と思っていたら、imap-umのなかに、tmailというコマンドが入ってました。これが、バッチリ使えました。



先日ビルドしたimap-uwの中から、tmailコマンドを、/usr/bin/tmailとしてコピーしました。



試しているときに、なんかrootでsetuidしとけ、ってメッセージがでたので、やってみたのですが、実は、setuidはいらなさそうです(/var/mailなどのメールボックスに書き込むためだと思われる)。



root@KURO-BOX:/# chmod 4755 /usr/bin/tmail
root@KURO-BOX:/# ls -l /usr/bin/tmail
-rwsr-xr-x    1 root     root      1533452 Jul 22 17:21 /usr/bin/tmail



fetchmailの--mdaオプションで、/usr/bin/tmailを使え、と指定できます。



たとえば --mda "/usr/bin/tmail -D nhh"  となります。-Dは、デバッグ用のメッセージを表示するオプション、nhhは、配送先のユーザー名です。ユーザー名を明示指定するかわりに、置換パターンを使うこともできるみたいですが、よくわかんなかったので、やめておきました。どうせ使うのは、自分ひとりだけですから。



なお、MDAは、mail delivery agentの意味らしいです。ローカル配送メーラーとか言うやつかな(あんまり詳しいことはわかりません)。


■ 玄箱上にメールボックスを用意する



たとえば、ユーザー名nhhなら、こんなかんじ。



root@KURO-BOX:/# mkdir /var/spool/mail
root@KURO-BOX:/# touch /var/spool/mail/nhh
root@KURO-BOX:/# chown nhh /var/spool/mail/nhh
root@KURO-BOX:/# chmod 600 /var/spool/mail/nhh



tmailを実行するとき、自分がオーナーのファイルに自分の権限で書き込むので、root setuidはいらないね、ってことです。



■ fetchmailの動作テスト



fetchmailは、リモートのメールサーバからメールを読み出すときのプロトコル(POP3、IMAPなど)を自動的に選択してくれるのですが、ときどきうまくいかないときがあるので、そのときは--protocolオプションで指定したほうがいいかもしれません。



--keepオプションは、メールサーバ上にメールを残すオプションです。動作テストでメールを失ってしまわないように、念のため指定しましょう。



--fetchallオプションは、既読のメールも、もう一度ダウンロードするためのオプションです。このオプションを指定しない場合、fetchmailは、既読状態のメールはダウンロードしません。一度fetchmailでメールをダウンロードしてしまうと、既読状態になってしまいますので、動作テストの場合は、つけておいたほうがいいかもしれせん。。



こんな感じで、fetchmailを玄箱上で実行します。なお、nhhはユーザー名です。「--user nhh」は、リモートメールサーバにアクセスするときのユーザー名で、「-D nhh」は玄箱でのユーザー名です。必ずしもユーザー名が一致するわけではないので、誤解なきよう・・・



nhh@KURO-BOX:~$ fetchmail --keep --user nhh --mda "/usr/bin/tmail -D nhh" --fetchall リモートのメールサーバ
Enter password for nhh@リモートのメールサーバ: パスワードを入力
157 messages for nhh at リモートのメールサーバ.
reading message nhh@リモートのメールサーバ:1 of 157 (1191 header octets).tmail called with LF-only newlines
delivering to nhh+INBOX
Verifying safe delivery to /var/spool/mail/nhh by UID 1001
unix appending to INBOX (file /var/spool/mail/nhh)
delivered to /var/spool/mail/nhh
Verifying safe delivery to /var/spool/mail/nhh by UID 1001
all recipients delivered
(539 body octets) not flushed
reading message nhh@リモートのメールサーバ:2 of 157 (1239 header octets).tmail called with LF-only newlines
delivering to nhh+INBOX
Verifying safe delivery to /var/spool/mail/nhh by UID 1001
unix appending to INBOX (file /var/spool/mail/nhh)
delivered to /var/spool/mail/nhh
Verifying safe delivery to /var/spool/mail/nhh by UID 1001
all recipients delivered
(499 body octets) not flushed



以下省略





つづく・・・



次回の予定としては、Mozilla Thunderbirdなどメールソフトのセットアップなど。



実は、日曜日からずっと、SpamAssassinを動かそうとして、悪戦苦闘してます。CPANで、なんかうまくインストールされなくて。


■ 前回の記事





0 件のコメント:

コメントを投稿