新トップページ ...

旧トップページ

Linux 日記
  Linux日記08~
  Linux日記2006
  Linux日記2005
  Linux日記2004
  Linux日記2003
  Linux日記2002
  Linuxカーネル
  + メモ ... (3p)
  + 勉強会 ... (6p)

アートでいこう(笑)!
  イラスト日記08〜
  イラスト日記2005
  イラスト日記2004
  イラスト日記2003
  アイコン描こうぜ

UCC(梅丘自転車部)
  活動ログ2003
  活動ログ2001
  活動ログ2000
  その他
  ワシの愛車

自動車関連
  FD3S日記05~
  S202日記2004
  S202日記2003
  S202日記2002
  S202給油等記録
  S202掲示板

自宅前カメラ
EZweb/PCSV用
プロフィール
社会科ノート 2004
社会科ノート 2003
全角半角変換
自家用リンク
視聴予定表
メモ

W/O index
Linux 日記 2005

Python ←→ C インターフェイス (Fri Mar 18 2005)

Pyrex (Pyrex-0.9.2.1) をいじってる中。Python 風言語 → Python モジュール・ソース in C 言語コンバータです。

$ pyrexc primes.pyx
$ gcc -fPIC \
-I/usr/include/python`python -c "import sys; print sys.version[:3]"`/ \
-shared -o primes.so primes.c
$ python -c "import primes; print primes.primes(10)"
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

おもしろいアプローチですが、バインディング生成に特化した SWIG のほうが、素直だし、Python 専用ではないので潰しも効くと思います(sip は、私が KDE と疎遠なため、直接には使ったことがない)。でも、お気楽さでは Pyrex の方がガゼン上かな。汎用の C コードを吐いてくれれば使えるのに、おしいなあ。

そして、また別のアプローチとして ctypes。こっ、これ、今後大いに利用させてもらいそうな予感があるんですが。

$ cat test.py
import ctypes
glibc = ctypes.cdll.LoadLibrary("/lib/libc.so.6")
print "Value: %d" % (glibc.printf(ctypes.c_char_p("Hello World!\n")),)
$ python test.py
Hello World!
Value: 13
$

あわわ、インターフェイス・モジュールとかまどろっこしいこと言わずに、直接呼んじゃうのか。しかし、C のインターフェイス分からないまま呼んじゃってますが……いや、ヘッダ・ファイルのパース機能もあるらしい(要 GCC_XML。激しくメンドくさい)。初回呼び出しのオーバーヘッドはあるはずだけど、こりゃいいや。

でも、みんなでこれ使い始めたら大変なことになりそうな予感が……。それと、RPM のような、自動的にライブラリの依存関係を抽出する仕組みが働かなくなる。

# そういや以前、コマンドラインから Windows DLL の関数呼ぶツール書いたことがあったな


D-Bus ヨチヨチ歩き (Tue Mar 15 2005)

DBus (dbus-0.23) である。C-Bus とは何の関わりもない。新手の、IPC だか RPC だか、ORB だとかに類するフレームワークである。IBM dW の紹介記事原文中文(読めんて))を参考にテストを始めてみた。能書きを読むと、重すぎず、ショボすぎず、現実的で良い感じの IPC との印象。

サンプルのコードが若干古いらしい(記事は、たかだか半年前のものなのですが)。README 曰く、1.0 になるまでは、必要とあらば API はコロコロ変わる予定。 Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1386

--- dbus-ping-send.c.orig       2005-03-15 16:32:07.596858704 +0900
+++ dbus-ping-send.c 2005-03-15 16:33:02.578500224 +0900
@@ -1,4 +1,5 @@
#include <glib.h>
+#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>

static gboolean send_ping (DBusConnection *bus);
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1386

--- dbus-ping-listen.c.orig     2005-03-15 16:34:16.274296760 +0900
+++ dbus-ping-listen.c 2005-03-15 16:33:00.258852864 +0900
@@ -1,4 +1,5 @@
#include <glib.h>
+#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>

static DBusHandlerResult signal_filter
@@ -23,7 +24,7 @@
dbus_connection_setup_with_g_main (bus, NULL);

/* listening to messages from all objects as no path is specified */
- dbus_bus_add_match (bus, "type='signal',interface='com.burtonini.dbus.Signal'");
+ dbus_bus_add_match (bus, "type='signal',interface='com.burtonini.dbus.Signal'", &error);
dbus_connection_add_filter (bus, signal_filter, loop, NULL);

g_main_loop_run (loop);

$ gcc -DDBUS_API_SUBJECT_TO_CHANGE `pkg-config --cflags dbus-glib-1` \
`pkg-config --libs dbus-glib-1` dbus-ping-send.c -o dbus-ping-send
$ gcc -DDBUS_API_SUBJECT_TO_CHANGE `pkg-config --cflags dbus-glib-1` \
`pkg-config --libs dbus-glib-1` dbus-ping-listen.c -o dbus-ping-listen
$ sudo /etc/init.d/messagebus start
Starting system message bus: OK
$ export DBUS_SESSION_BUS_ADDRESS=unix:path=/var/run/dbus/system_bus_socket

うん、とりあえず送信・受信のプロセス間通信できたぞ、と。

次いで Python。Python モジュールのほうが C バインディングよりもチェックが厳しいらしく、まずはセキュリティでハネられるので、甘々にしてみる(実運用ではやめましょう)。 Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1386

--- /etc/dbus-1/system.conf.orig        2005-03-15 16:20:06.131538104 +0900
+++ /etc/dbus-1/system.conf 2005-03-15 17:25:13.463533352 +0900
@@ -34,10 +34,10 @@

<policy context="default">
<!-- Deny everything then punch holes -->
- <deny send_interface="*"/>
- <deny receive_interface="*"/>
- <deny own="*"/>
<!-- But allow all users to connect -->
+ <allow send_interface="*"/>
+ <allow receive_interface="*"/>
+ <allow own="*"/>
<allow user="*"/>
<!-- Allow anyone to talk to the message bus -->
<!-- FIXME I think currently these allow rules are always implicit

サービス上げなおして、スクリプトも一部変更。dW にも書いてあったけれど、Python バインディングは仕様変更が変更が激しいな。 Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1386

--- dbus-ping-send.py.orig      2005-03-15 17:16:30.088098512 +0900
+++ dbus-ping-send.py 2005-03-15 17:17:45.248672368 +0900
@@ -12,13 +12,13 @@
# Define a D-BUS object
class SignalObject(dbus.Object):
def __init__(self, service):
- dbus.Object.__init__(self, "/", [], service)
+ dbus.Object.__init__(self, "/com/burtonini/dbus/ping", service, [])

# Create an instance of the object, which is part of the service
signal_object = SignalObject(service)

def send_ping():
- signal_object.broadcast_signal("com.burtonini.dbus.Signal", "Ping")
+ signal_object.emit_signal("com.burtonini.dbus.Signal", "Ping", "Ping!")
print "Ping!"
return gtk.TRUE

以上で、C のコードと同様に動いた。


SMTP コネクション、中身ナシ (Mon Mar 14 2005)

sendmail-8.11.6 にて。 Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1386

NOQUEUE: [XXX.XXX.XXX.XXX] did not issue \
MAIL/EXPN/VRFY/ETRN during connection to MTA

普通は、サーバが動いているかどうか確認する SMTP ping 的なアクセスや、DoS アタックで出るようなのですが、今回は普通の MUA(Mozilla)らしいので、謎。"relay-domains" にも記述されているので、リレーの問題ではなさげ。逆引きできないクライアントからのアクセスなのと関係あるかな?


php-4.3.8 の symlink() (Mon Mar 07 2005)

以下、php-4.3.3 で実行。

$ pwd
/tmp
$ cat test.php
<? symlink("hoge", "fuga") ?>
$ php test.php
$ readlink fuga
hoge
$

まあ普通の symlink() の挙動だ。ところが、以下、php-4.3.8 で実行。

$ php test.php
$ readlink fuga
/tmp/hoge
$

余計なことを……。勝手に相対パスに $PWD をつけてくれるんですが、どうしたこと?

こうして、php スクリプト内に system() がどんどん増えて行くのであった。

追記(Tue Mar 08 2005): symlink() まわりのコード(ext/standard/link.c:PHP_FUNCTION(symlink) や main/fopen_wrappers.c:expand_filepath())は大して変わっていないので、どうにも解せない。下まわりの挙動が変わったとしても、パス解決の関数の呼びだしは同じだし……なんでだろう?

スクリプトに suid (Sat Mar 05 2005)

……をしても無効なんですけど?

$ cat test.py
#!/usr/bin/python
import os
print "d:", os.getuid(), os.geteuid()
$ cat test.c
#include <stdio.h>
#include <unistd.h>
int main (int argc, char * * argv) {
printf("d: %d, %d\n", getuid(), geteuid());
return (0);
}
$ gcc test.c -o test.bin
$ sudo chmod 4755 test.py test.bin ; sudo chown root test.py test.bin
$ id
uid=501(knaka) gid=100(users) 所属グループ=100(users)
$ ./test.bin
d: 501, 0
$ ./test.py
d: 501, 501

追記(Sun Mar 06 2005): execve(2) の man に、できないと書いてありました……(Linux の実装では、exec(2) ではなく execve(2) なんですね、それ以外は 3。そもそも、"exec()" なんて無いし)

参考: "[debian-users:31409] setuid shell script (Re: Re: [Q]I chmod u+s が使えない )"。何も考えんとスクリプトを書くと、「任意の引数を渡せてしまう」、「インタプリタの実行開始とスクリプトの読み込みがアトミックではないため、任意のスクリプトを実行できてしまう」――といったあたりが危険。今回は「バイナリ・ラッパー」で逃げました

以下、kernel-2.6.10。euid がセットされるのは fs/exec.c:prepare_binprm()。bprm->file が、参照先となるファイル。 Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1386

int prepare_binprm(struct linux_binprm *bprm)
{
int mode;
struct inode * inode = bprm->file->f_dentry->d_inode;

mode = inode->i_mode;

... snip ...

if(!(bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)) {
/* Set-uid? */
if (mode & S_ISUID) {
current->personality &= ~PER_CLEAR_ON_SETID;
bprm->e_uid = inode->i_uid;
}

ところが、fs/binfmt_script.c:load_script() を見ると、parepare_binprm() を呼ぶ前に、bprm->file は、スクリプトのファイルからインタプリタのファイルに置き換わっているのです。 Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1386

static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
{

... snip ...

/*
* OK, now restart the process with the interpreter's dentry.
*/
file = open_exec(interp);
if (IS_ERR(file))
return PTR_ERR(file);

bprm->file = file;
retval = prepare_binprm(bprm);

つまり、suid が有効なのはインタプリタであって、スクリプト自体ではないということ。ここの順番変えればできそうですけどね、セキュリティ的観点から、できないようにしてあるそうな。


terminfo (Thu Mar 03 2005)

式年遷宮と車輪の再発明について(ぉ。


gpm-1.20.1 のエラー (Tue Mar 01 2005)

Notice: Use of undefined constant align - assumed 'align' in /home/knaka/public_html/code.php on line 1448 Notice: Undefined index: href in /home/knaka/public_html/code.php on line 1452 GPM すずか。やはりストッキングを履いたゲーム版設定に限る

激しく GPM 違い。

# って、すまん、このネタいっぺんやってみたかったんだ……。プレステ版は大傑作です。とても万人受けするとは思えないけど、超オススメ!

さてと、w3m-0.5.1 + gpm-1.20.1 on rxvt で、以下のようなエラーメッセージが画面を壊すので、うっとうしいです。画面切替えれば消えて行くから、いいっちゃいいんだけど。 Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1386

*** err [lib/liblow.c(267)]:
strncmp/isdigit/option.consolename failed
*** err [lib/liblow.c(376)]:
Oh, oh, it's an error! possibly I die!

w3m-0.4.1 でも出ますね、gpm-1.19.6 では出ません。てことは GPM のせいか。gpm-1.19.6/src/liblow.c:Gpm_Open() と gpm-1.20.1/src/lib/liblow.c:Gpm_Open() を比較すると、そもそも 1.19.6 ではエラー出力が無かったのもあるのですが、本質的には tty のチェックが厳しくなったことが原因のようです。$TERM が "xterm" なら X 上のターミナルと判断するし、tty が "/dev/tty[0-9]+" or "/dev/vc/[0-9]+" だったら全画面コンソールとするのですが、それ以外では、たとえ GPM デーモンが動いていても、ゲロゲロと警告が出ます、と。よって、$TERM が "xterm" になる mlterm だと出ないんですわ。xterm の仲間たちにも同様の処理をしてやれば大丈夫そうだから、"xterm" のとなりに "rxvt", "kterm", "konsole" を追加しておきました。うん、良いみたい。

gpm-1.20.1-more_xterm.patch
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
--- src/lib/liblow.c.orig	2005-03-01 23:37:58.455813320 +0900
+++ src/lib/liblow.c 2005-03-01 23:55:08.112281744 +0900
@@ -206,7 +206,9 @@

/*....................................... First of all, check xterm */

- if ((term=(char *)getenv("TERM")) && !strncmp(term,"xterm",5)) {
+ if ((term=(char *)getenv("TERM")) && (!strncmp(term,"xterm",5) ||
+ strncmp(term, "rxvt", 4) == 0 || strncmp(term, "kterm", 5) == 0 ||
+ strncmp(term, "konsole", 7) == 0 )) {
if(gpm_tried) return gpm_fd; /* no stack */
gpm_fd=-2;
GPM_XTERM_ON;

情報 Thanks でした > yuki さん。

screen(1) 上だと、$TERM は "screen" なので相変わらず出ますが、これは正しい。w3m に "-no-mouse" オプションをつけるべし。

# うん、いいペースだ、「日記」になってきた(w


Mozilla でダイヤモンド・カーソル♪ (Mon Feb 28 2005)

Mozilla のテキストエントリや textarea でダイヤモンドカーソル できました。/usr/lib/mozilla/res/builtin/platformHTMLBindings.xml を以下のように改変(うちの Mozilla は 1.7.5)。

'binding id="textAreas"' の 'handlers' 内です。 Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1386

<!--
<handler event="keypress" key="y" modifiers="accel" command="cmd_redo"/>
<handler event="keypress" key="z" modifiers="accel" command="cmd_undo"/>
<handler event="keypress" key="z" modifiers="accel,shift"
command="cmd_redo"/>
-->

<handler event="keypress" key="g" modifiers="accel"
command="cmd_deleteCharForward"/>
<handler event="keypress" key="h" modifiers="accel"
command="cmd_deleteCharBackward"/>
<handler event="keypress" key="s" modifiers="accel"
command="cmd_charPrevious"/>
<handler event="keypress" key="d" modifiers="accel"
command="cmd_charNext"/>
<handler event="keypress" key="a" modifiers="accel"
command="cmd_wordPrevious"/>
<handler event="keypress" key="f" modifiers="accel"
command="cmd_wordNext"/>

<handler event="keypress" key="e" modifiers="accel"
command="cmd_linePrevious"/>
<handler event="keypress" key="x" modifiers="accel"
command="cmd_lineNext"/>
<handler event="keypress" key="r" modifiers="accel"
command="cmd_scrollPageUp"/>
<handler event="keypress" key="c" modifiers="accel"
command="cmd_scrollPageDown"/>
<handler event="keypress" key="w" modifiers="accel"
command="cmd_scrollLineUp"/>
<handler event="keypress" key="z" modifiers="accel"
command="cmd_scrollLineDown"/>

<handler event="keypress" key="u" modifiers="accel" command="cmd_undo"/>
<handler event="keypress" key="v" modifiers="accel" command="cmd_paste"/>
<handler event="keypress" key="\\" modifiers="accel" command=""/>

一般ユーザ権限でもできるようなので調べておこう。あと Ctrl-M と 2 ストローク・カスタマイズができたら、エディタ捨ててもいい!(早まるな)

追記(Tue Mar 01 2005): 以下のように "action" を記述すれば、ここで "this" は HTMLTextAreaElement のインスタンスですので、やろうと思えば何でもできるようなのですが……、ECMA script (aka. JavaScript) にハマれと仰るのですか? んー、気が乗らない……(移植性を考えなくて良い ECMA は、ある意味楽かも知れないが) Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1386

<handler event="keypress" key="m" modifiers="accel" command=""/>
<handler event="keypress" key="m" modifiers="accel"
action="this.value = 'hoge';"/>

追記(Tue Mar 01 2005): 改行の挿入、できました。データが大きくなると猛烈に重くなる上に、挿入後の画面位置がズレて使いづらく、undo も効かないものの、まあ、無いよりはマシくらいの気持ちで。上記 "action" の部分に以下を入れれば動きます。 Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1386

action="i = this.selectionStart; this.value = this.value.substr(0, i) +
'\n' + this.value.substr(i, this.value.length - i);
this.setSelectionRange(i + 1, i + 1); this.focus();"

時間があったら見ておくとしますか、XULPlanet.com

メモ:

input の実装: mozilla/content/html/content/src/nsHTMLInputElement.cpp
textarea の実装?: mozilla/content/html/content/src/nsHTMLTextAreaElement.cpp
ecma textarea の実装: mozilla/xpfe/global/resources/content/bindings/textbox.xml
XPToolkit (XP ツールキット)

Example.com について (Mon Feb 28 2005)

ドメイン名 "example.com", "example.net", "example.org" は RFC 2606 で予約されているので、好き勝手にドキュメント等で使って OK です → Example.com へ

追記(yuki さん情報): 汎用 jp ドメイン名における予約名。"example" や ICANN の TLD は予約ですって。属性型の規約に準じているようです。

Gettextize、何か変? (Sun Feb 27 2005)

gettext せりか

言葉の問題は根が深いですねえ、ボディランゲージではどうともなりません。がんばれ Celica。

それはともかく、何やら素直に動かないものの(使い方が悪いのかもしれんが)、gettext-0.11.5 由来の gettextize(1) を使ってみた。ひとまずは動いたし、どういうものであるかは分かった。実際に使うときは、何とか構築できれば OK なので、とりあえず良しとしよう。

#ifdef は、これで良いのかどうか、微妙に自信ない (^-^;。
Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

hello.c
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
#include <config.h>

#include <stdio.h>
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#ifdef HAVE_GETTEXT
#include <libintl.h>
#define _(s) gettext(s)
#else
#define _(s) (s)
#endif

int
main (
int argc,
char * * argv ) {
#ifdef HAVE_LOCALE_H
setlocale(LC_ALL, "");
#endif
#ifdef HAVE_GETTEXT
bindtextdomain("hello", datadir "/locale");
textdomain("hello");
#endif
printf(_("Hello, World!\n"));
return (0);
}

Gettext のビルドシステムが管理するソースを、プロジェクトのルートからの相対パスで羅列。 Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

POTFILES.in
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
hello.c
Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

ja.po
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
#, no-wrap
msgid ""
msgstr ""
"Project-Id-Version: 1.3.24\n"
"POT-Creation-Date: 2005-02-27 19:08+0900\n"
"PO-Revision-Date: 2001-12-03 10:47+0900\n"
"Last-Translator: Kiichiro NAKA <knaka@example.com>\n"
"Language-Team: Kiichiro NAKA <knaka@example.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: hello.c:25
msgid "Hello, World!\n"
msgstr "こんにちは、世界!\n"

SUBDIRS が増えました。実装依存で、あまり奇麗でないと思います。 Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

Makefile.am
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
bin_PROGRAMS = hello
hello_SOURCES = hello.c

SUBDIRS=po intl m4
CFLAGS=-Ddatadir='"$(datadir)"'

GETTEXTIZE_GENERATED=ABOUT-NLS intl m4 ChangeLog config.rpath \
po mkinstalldirs
ACLOCAL_GENERATED=aclocal.m4
AUTOHEADER_GENERATED=config.h.in autom4te.cache
AUTOCONF_GENERATED=configure
AUTOMAKE_GENERATED=Makefile.in depcomp install-sh missing mkinstalldirs \
stamp-h.in config.guess config.sub

spotless: distclean
rm -fr $(ACLOCAL_GENERATED) $(AUTOHEADER_GENERATED) \
$(AUTOCONF_GENERATED) $(LIBTOOLIZE_GENERATED) \
$(AUTOMAKE_GENERATED) $(GETTEXTIZE_GENERATED)

ALL_LINGUAS="ja", AM_GNU_GETTEXT を追加です。gettextize(1) すると AC_CONFIG_FILES が増えます。困ったもんだ。 Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

configure.in
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
AC_INIT
AM_INIT_AUTOMAKE(hello, 1.0)
AC_CONFIG_HEADERS([config.h])
AC_CHECK_HEADERS(stdio.h)
AC_PROG_CC
ALL_LINGUAS="ja"
AM_GNU_GETTEXT
AC_CONFIG_FILES([Makefile m4/Makefile])
AC_OUTPUT

実行結果。gettextize(1) すると configure.in と Makefile.in を書き換えてくれて、再度 gettextize(1) するとおかしくなるので、オリジナルはとっておいたほうが良いかも……。とにかく、何だかそのままじゃ動かなくて……弱ったな。 Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

$ ls
Makefile.am POTFILES.in configure.in hello.c ja.po
$ gettextize --copy --force --intl --no-changelog
Creating intl/ subdirectory
Creating po/ subdirectory
Copying file ABOUT-NLS
Copying file config.rpath
Copying file mkinstalldirs
Copying file intl/ChangeLog
Copying file intl/Makefile.in

... (snip) ...

Copying file m4/lib-prefix.m4
Copying file m4/progtest.m4
Copying file m4/stdint_h.m4
Copying file m4/uintmax_t.m4
Copying file m4/ulonglong.m4
Creating m4/Makefile.am
Updating Makefile.am (backup is in Makefile.am~)
Updating configure.in (backup is in configure.in~)

Please create po/Makevars from the template in po/Makevars.template.
You can then remove po/Makevars.template.

Please run 'aclocal -I m4' to regenerate the aclocal.m4 file.
You need aclocal from GNU automake 1.5 (or newer) to do this.
Then run 'autoconf' to regenerate the configure file.

You will also need config.guess and config.sub, which you can get from
ftp://ftp.gnu.org/pub/gnu/config/.

You might also want to copy the convenience header file gettext.h
from the /usr/share/gettext directory into your package.
It is a wrapper around <libintl.h> that implements the configure --disable-nls
option.

Press Return to acknowledge the previous four paragraphs.
$ chmod 0755 mkinstalldirs # 何でやねん?
$ glib-gettextize -f --copy # gettext-0.11.5 から出るものでは通らなかった…
Copying file po/Makefile.in.in

Please add the files
codeset.m4 gettext.m4 glibc21.m4 iconv.m4 isc-posix.m4 lcmessage.m4
progtest.m4
from the /usr/share/aclocal directory to your autoconf macro directory
or directly to your aclocal.m4 file.
You will also need config.guess and config.sub, which you can get from
ftp://ftp.gnu.org/pub/gnu/config/.
$ sed -i -e 's/@GETTEXT_PACKAGE@/@PACKAGE@/' po/Makefile.in.in # …
$ cp -f POTFILES.in ja.po po/
$ aclocal -I m4
$ autoheader
$ autoconf
$ automake --copy --add-missing --foreign
configure.in:7: installing `./config.guess'
configure.in:7: installing `./config.sub'
Makefile.am: installing `./depcomp'
$ ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU

... (snip) ...

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
$ make
make all-recursive
make[1]: Entering directory `/home/knaka/gettextize_test'
Making all in po
make[2]: Entering directory `/home/knaka/gettextize_test/po'
make[2]: Nothing to be done for `all'.
make[2]: Leaving directory `/home/knaka/gettextize_test/po'
Making all in intl
make[2]: Entering directory `/home/knaka/gettextize_test/intl'
make[2]: Nothing to be done for `all'.
make[2]: Leaving directory `/home/knaka/gettextize_test/intl'
Making all in m4
make[2]: Entering directory `/home/knaka/gettextize_test/m4'
make[2]: Nothing to be done for `all'.
make[2]: Leaving directory `/home/knaka/gettextize_test/m4'
make[2]: Entering directory `/home/knaka/gettextize_test'
make[2]: Leaving directory `/home/knaka/gettextize_test'
make[1]: Leaving directory `/home/knaka/gettextize_test'
$ su
Password:
# make install
Making install in po
make[1]: Entering directory `/home/knaka/gettextize_test/po'
if test -r ".././mkinstalldirs"; then \
.././mkinstalldirs /usr/local/share; \
else \

... (snip) ...

/bin/sh ./mkinstalldirs /usr/local/bin
/usr/bin/install -c hello /usr/local/bin/hello
make[2]: Nothing to be done for `install-data-am'.
make[2]: Leaving directory `/home/knaka/gettextize_test'
make[1]: Leaving directory `/home/knaka/gettextize_test'
$ LC_ALL=ja_JP.eucJP hello
こんにちは、世界!
$


Libtoolize で楽ちん (Sun Feb 27 2005)

Automake + Libtoolize の力を借りて、共有ライブラリを作ってみます。

ライブラリ本体は、以下の二つのファイルからなります。 Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

hello.h
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
#ifndef HELLO_H
#define HELLO_H

void hello();

#endif /* HELLO_H */
Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

hello.c
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
#include <config.h>

void hello () {
printf("Hello, World!\n");
}

今度の Makefile.am は、実質三行! "hello.h" は、ライブラリのビルドに用いると同時に、呼び出し側のインターフェイスの宣言にも用いられるので、"SOURCES" プライマリと "HEADERS" プライマリの両方に含まれます。また、"spotless" で、元の木阿弥になるように。 Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

Makefile.am
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
lib_LTLIBRARIES=libhello.la
libhello_la_SOURCES=hello.h hello.c
include_HEADERS=hello.h

ACLOCAL_GENERATED=aclocal.m4
AUTOHEADER_GENERATED=config.h.in autom4te.cache
AUTOCONF_GENERATED=configure
LIBTOOLIZE_GENERATED=config.guess config.sub ltmain.sh ltconfig
AUTOMAKE_GENERATED=Makefile.in depcomp install-sh missing mkinstalldirs \
stamp-h.in

spotless: distclean
rm -fr $(ACLOCAL_GENERATED) $(AUTOHEADER_GENERATED) \
$(AUTOCONF_GENERATED) $(LIBTOOLIZE_GENERATED) $(AUTOMAKE_GENERATED)

AC_PROG_LIBTOOL を指定しているので、automake(1) の前に libtoolize(1) で必要なファイルをコピーもしくはリンクしておかないと、文句を言われます。 Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

configure.in
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
AC_INIT()
AM_INIT_AUTOMAKE(libhello, 1.0)
AM_CONFIG_HEADER(config.h)
AC_PROG_CC
AC_PROG_LIBTOOL
AC_OUTPUT(Makefile)

そして、簡単なテスト・プログラム。 Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

test.c
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
#include <stdio.h>

#include <hello.h>

int
main (
int argc,
char * * argv ) {
hello();
return (0);
}

以下、実行の結果(自分、80 桁志向なので、適宜改行してある)。 Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

$ ls
Makefile.am configure.in hello.c hello.h test.c
$ aclocal
$ autoheader
$ autoconf
$ libtoolize --copy --force
$ automake --copy --add-missing --foreign
automake: configure.in: installing `./install-sh'
automake: configure.in: installing `./mkinstalldirs'
automake: configure.in: installing `./missing'
$ ./configure
creating cache ./config.cache
checking for a BSD compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking whether make sets ${MAKE}... yes
checking for working aclocal... found
checking for working autoconf... found
checking for working automake... found
checking for working autoheader... found
checking for working makeinfo... found
checking for gcc... gcc
checking whether the C compiler (gcc ) works... yes
checking whether the C compiler (gcc ) is a cross-compiler... no
checking whether we are using GNU C... yes
checking whether gcc accepts -g... yes
checking host system type... i686-pc-linux-gnu
checking build system type... i686-pc-linux-gnu
checking for ranlib... ranlib
checking for ld used by GCC... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD-compatible nm... /usr/bin/nm -B
checking whether ln -s works... yes
updating cache ./config.cache
checking for object suffix... o
checking for executable suffix... no
checking for gcc option to produce PIC... -fPIC
checking if gcc PIC flag -fPIC works... yes
checking if gcc supports -c -o file.o... yes
checking if gcc supports -c -o file.lo... yes
checking if gcc supports -fno-rtti -fno-exceptions ... yes
checking if gcc static flag -static works... -static
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking whether the linker (/usr/bin/ld) supports shared libraries... yes
checking command to parse /usr/bin/nm -B output... ok
checking how to hardcode library paths into programs... immediate
checking for /usr/bin/ld option to reload object files... -r
checking dynamic linker characteristics... Linux ld.so
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... yes
checking for objdir... .libs
creating libtool
loading cache ./config.cache
creating ./config.status
creating Makefile
creating config.h
$ make
/bin/sh ./libtool --mode=compile gcc -DHAVE_CONFIG_H -I. -I. -I. \
-g -O2 -c hello.c
mkdir .libs
gcc -DHAVE_CONFIG_H -I. -I. -I. -g -O2 -Wp,-MD,.deps/hello.pp -c hello.c \
-fPIC -DPIC -o .libs/hello.lo
gcc -DHAVE_CONFIG_H -I. -I. -I. -g -O2 -Wp,-MD,.deps/hello.pp -c hello.c \
-o hello.o >/dev/null 2>&1
mv -f .libs/hello.lo hello.lo
/bin/sh ./libtool --mode=link gcc -g -O2 -o libhello.la \
-rpath /usr/local/lib hello.lo
rm -fr .libs/libhello.la .libs/libhello.* .libs/libhello.*
gcc -shared hello.lo -lc -Wl,-soname -Wl,libhello.so.0 -o \
.libs/libhello.so.0.0.0
(cd .libs && rm -f libhello.so.0 && ln -s libhello.so.0.0.0 libhello.so.0)
(cd .libs && rm -f libhello.so && ln -s libhello.so.0.0.0 libhello.so)
ar cru .libs/libhello.a hello.o
ranlib .libs/libhello.a
creating libhello.la
(cd .libs && rm -f libhello.la && ln -s ../libhello.la libhello.la)
$ su
Passwd:
# make install
make[1]: Entering directory `/home/knaka/libtool_test'
/bin/sh ./mkinstalldirs /usr/local/lib
/bin/sh ./libtool --mode=install /usr/bin/install -c libhello.la \
/usr/local/lib/libhello.la
/usr/bin/install -c .libs/libhello.so.0.0.0 /usr/local/lib/libhello.so.0.0.0
(cd /usr/local/lib && rm -f libhello.so.0 && ln -s libhello.so.0.0.0 \
libhello.so.0)
(cd /usr/local/lib && rm -f libhello.so && ln -s libhello.so.0.0.0 \
libhello.so)
/usr/bin/install -c .libs/libhello.lai /usr/local/lib/libhello.la
/usr/bin/install -c .libs/libhello.a /usr/local/lib/libhello.a
ranlib /usr/local/lib/libhello.a
chmod 644 /usr/local/lib/libhello.a
PATH="$PATH:/sbin" ldconfig -n /usr/local/lib
----------------------------------------------------------------------
Libraries have been installed in:
/usr/local/lib

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use `-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
- use the `-Wl,--rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
/bin/sh ./mkinstalldirs /usr/local/include
/usr/bin/install -c -m 644 hello.h /usr/local/include/hello.h
make[1]: Leaving directory `/home/knaka/libtool_test'
# ldconfig
# exit
$ gcc -lhello test.c
$ ldd ./a.out
libhello.so.0 => /usr/local/lib/libhello.so.0 (0x4002d000)
libc.so.6 => /lib/libc.so.6 (0x4002f000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
$ ./a.out
Hello, World!
$


Automake 復習 (Sat Feb 26 2005)

autoconf すずか

♪開発だいすきー、どんどんゆこうー(Suzuka さん、髪型変えたそうです)。

前回の Autoconf に続いて、最低限の Automake の入力ファイルを作成して、実行してみた。見事に Makefile.in を書く手間が省略されますね、実質、たったの二行! それでいて、アーカイブ・ファイル作成("dist")や、仮想インストール機能("$DESTDIR")までサポートされているのですから、これはオイシイ!

hello.c は、Autoconf の時のそれと全く同じ。
Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

Makefile.am
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
bin_PROGRAMS = hello
hello_SOURCES = hello.c

# automake 実行以前の状態まで戻せなきゃ(`Д´ヤダヤダヤダ
spotless: distclean
rm -f Makefile.in aclocal.m4 configure
rm -fr install-sh missing mkinstalldirs stamp-h.in \
COPYING INSTALL autom4te.cache/ depcomp config.guess config.sub
rm -f config.h.in

Automake 固有の configure.in マクロについては、こことか参照。 Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

configure.in
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
AC_INIT()
AM_INIT_AUTOMAKE(hello, 1.0)
AM_CONFIG_HEADER(config.h)
AC_CHECK_HEADERS(stdio.h)
AC_PROG_CC
AC_OUTPUT(Makefile)

実行の結果(automake(1) までは、autoreconf(1) 一発、でも大体は代替可)。 Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

$ ls
Makefile.am configure.in hello.c
$ aclocal # AM 用 configure.in を AC が読むための aclocal.m4 を生成
$ autoheader
$ autoconf
$ automake --add-missing --foreign # "--foreign" は、非 GNU 度高し、の意
automake: configure.in: installing `./install-sh'
automake: configure.in: installing `./mkinstalldirs'
automake: configure.in: installing `./missing'
$ ./configure
creating cache ./config.cache
checking for a BSD compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking whether make sets ${MAKE}... yes
checking for working aclocal... found
checking for working autoconf... found
checking for working automake... found
checking for working autoheader... found
checking for working makeinfo... found
checking how to run the C preprocessor... cc -E
checking for stdio.h... yes
checking for gcc... gcc
checking whether the C compiler (gcc ) works... yes
checking whether the C compiler (gcc ) is a cross-compiler... no
checking whether we are using GNU C... yes
checking whether gcc accepts -g... yes
updating cache ./config.cache
creating ./config.status
creating Makefile
creating config.h
$ make
gcc -DHAVE_CONFIG_H -I. -I. -I. -g -O2 -c hello.c
gcc -g -O2 -o hello hello.o
$ ./hello
Hello, World!
$


Autoconf 復習 (Sat Feb 26 2005)

Automake の本質が「Makefile.in 書くの ('A`) マンドクセ」なのに対して、Autoconf は、「オレのソフトウェアを遍く全ての UN*X 環境上でビルドさせるべく、調停者たる configure スクリプトを、共に送り込むぜ!」という熱く気高い理想(?)に基づいているのだ。

まあそれはともかく、Autotools (Automake, Autoconf, Libtool) を使った開発はしたことがあるのですが、コピペだったため、基礎がなっていません。原理が分かっていないと、不具合が起きたときに何を参照してよいのか分からないので、今一度復習してみようと思います。

てなわけで、最低限の Autoconf の入力ファイルを作成して、実行してみた。 Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

hello.c
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
#include <config.h>

#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif

int
main (
int argc,
char * * argv ) {
#ifdef HAVE_STDIO_H
printf("Hello, World!\n");
return (0);
#else
return (1);
#endif
}
Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

Makefile.in
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
CPPFLAGS=-I. @CPPFLAGS@

all: hello

hello: hello.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $^ -o $@

clean:
rm -f hello

distclean: clean
rm -f config.h config.status config.cache config.log Makefile

# autoheader/autoconf 実行以前の状態まで戻せなきゃ(`Д´ヤダヤダヤダ
spotless: distclean
rm -fr config.h.in configure autom4te.cache

configure.in は手で書きましたが、autoscan(1) をすると、雛形までは作ってくれます。configure.in で使えるマクロに関してはこことか参照。一覧性に欠くのですが、良いページありませんかね? Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

configure.in
Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
AC_INIT()
AC_CONFIG_HEADER(config.h)
AC_CHECK_HEADERS(stdio.h)
AC_OUTPUT(Makefile)

で、実行の結果。 Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

$ ls
Makefile.in configure.in hello.c
$ autoheader # configure.in から config.h.in を生成
$ autoconf
$ ./configure
creating cache ./config.cache
checking how to run the C preprocessor... cc -E
checking for stdio.h... yes
updating cache ./config.cache
creating ./config.status
creating Makefile
creating config.h
$ make
cc -I. hello.c -o hello
$ ./hello
Hello, World!
$

なお、Autoconf のバージョンが上がると、configure.in の記述の仕方も若干変わるようなのですが、おもむろに autoupdate(1) を実行すると、最新の記述に修正してくれます。以下、autoconf-2.57 の autoupdate(1) による添削例。 Notice: Undefined index: link in /home/knaka/public_html/code.php on line 1411

Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1418
-AC_INIT()
+AC_INIT
AC_CONFIG_HEADER(config.h)
AC_CHECK_HEADERS(stdio.h)
-AC_OUTPUT(Makefile)
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT


PHP とコンテントネゴシエーション (Fri Feb 25 2005)

とある URI 考「クールな URI は変わらない(英語原文: Cool URIs don't change)」を読んで、「うんうん、拡張子で実装を晒すなんて愚の骨頂、スクリプト言語の変更もままならないじゃないの」とすっかり影響され、当サイトもそれに習って各部書き換えたのでした("knaka" と "Ayutaya.com" は一蓮托生なので、そこはそれで良しとしよう)。PHP も、Apache のコンテントネゴシエーションの機能を使って、拡張子が省略できたかのように思えたのですが、一寸問題が……。

Apache(2.0.51) + php(4.3.8) で試したのですが、Apache が、php のスクリプト・ファイルに関するコンテント・ネゴシエーションをする場合に用いる MIME タイプは、php.ini の default_mimetype でもなければ、個々の php スクリプトが送出する HTTP ヘッダの "Content-type" レコードでもなく、Apache 内部における MIME タイプである "application/x-httpd-php" なのです。これで何が問題かと言うと、HTTP のリクエストヘッダの "Accept:" レコードに "application/x-httpd-php"(あるいは "application/*" や "*/*" でも良いのですが)が入っていないと、Apache は PHP ファイルを正しくマッチさせてくれないのです("406 Not Acceptable" が返される)。w3m("Accpet: text/* image/*" を送出)でリクエストしてみて気づきました。Mozilla や IE でうまく行くのは、"Accept: */*"、何でも可、だからのようです。

弱ったな、何か良い手は無いものか。PHP が、MIME タイプを用いるのではなく、CGI のように "AddHandler" で使えれば良いのに……とか思いつつ "PHP AddHandler" で Google ったらこんな投稿が。あー、全く同じこと考えてる人がいたよ。ちなみに、PHP5 からは "AddHandler" で使えるらしい……移行すべきか?

……さらに見て行くと、スレッドは切れているけれど、ずっと先にこんな投稿が……。 Notice: Undefined index: shell in /home/knaka/public_html/code.php on line 1386

#AddType application/x-httpd-php .php
AddType text/html php
AddHandler application/x-httpd-php .php

ありゃ、動いちゃったよ、w3m でも "200 OK"、バンザイ。何でだ?

結果良しとする?(ぉ

# 結局は、"php-handler" ハンドラを加えてビルドした PHP4 を使っています

- ご意見・ご要望は、サイト管理者(那賀樹一郎 (Kiichiro NAKA) <knaka@ayutaya.com>)までお願いします。
- このサイトは、Turbolinux 上の Mozilla w3m でテストされています。Internet Explorer では未確認です
- 言うまでもありませんが、当サイトはリンクフリーです
- W3C の HTML チェックをかけたところ、ズタボロでした。頑張ったけど、ダメだこりゃ……