Shしか使えない web server での C/C++製CGIのコンパイル

ホームページ公開サービスを提供しているプロバイダのほとんどで、 ページ所有者が web server にログインすることが禁止されているので C/C++ソースをCGIとしてコンパイルすることができません。 なのでコンパイル不要なインタラプタ言語な perl でCGIを作ることに なってしまいます。C/C++プログラマとしては非常に残念です。 しかし、なんとかすることが可能なのです。 この章では、そのようなプロバイダでC/C++製CGIを動かす強行策を解説します。


● Web serverの構成が自分のコンピュータの構成と同じ場合

Web server の CPU と OS が自分が所有するコンピュータのそれらと全く同じなら、 実行ファイルに互換性があるので、自分のところでコンパイルしてアップロードする だけで済みます。OSのversionが serverの方が新しくても上位互換性が あるので大丈夫です。


● クロスコンパイラを持っている場合

Web server の環境用の実行ファイルを出力できる クロスコンパイラを持っているならそれを使えば問題解決です。


● Web serverでコンパイルする前に考えること

Web serverで動く実行ファイルを作成する一番確実な方法は やはりその web server でコンパイルすることです。しかし telnetで web serverにログインしたりコマンドを実行したりできないので コンパイルへの道は険しいです。あの手この手の方法を使うためには そのweb serverの環境を良く調べないとなりません。

Web server上でUNIXコマンドを実行する方法にSSIがあることを思い出して下さい。 それに CGIからUNIXコマンドを実行することもできます。 SSIでUNIXコマンドを実行することができないように設定されているかもしれません。 そもそも、その web server で Perl製のCGIを実行できるでしょうか? sh製のCGIを実行できるでしょうか?

ftpでファイルをアップロードしたり、ファイルを移動したりするのですが、 ftpで自分のディレクトリ以外を見ることができるでしょうか? /var/tmpディレクトリを見ることはできますか? 転送したファイルを実行ファイルにするためにはpermission等のファイルモード を変更しないとならないのですが、ftpで chmodを使えるでしょうか?

コマンドの実行権限は nobodyとして実行されるでしょう。 CGIがSuEXECで自分の権限で動くかも知れませんし、 CGIにsbitを立てることができるなら、それでも自分の権限を与えることができます。

我々の目標は sh製のCGIに C/C++ソースのコンパイルを行わせることです。 Perl製のCGIでも構いませんがsh製の方が簡単確実です。

gccなどのC/C++コンパイラが web serverにインストールされているでしょうか? gccはUNIXの標準コマンドではないので無いかも知れません。ccがUNIXの 標準コマンドですがこれはC++を扱えません。

CGIがnobodyとして実行されるなら、CGIから呼び出される gcc 等の コンパイラも nobodyとして実行されます。なので生成される実行ファイルも nobody所有のファイルになるのですが、自分のディレクトリには nobodyはファイルを新設できません。nobodyでもファイルを新設できる 専用のディレクトリを自分のディレクトリの下に用意しましょうか。 多少の security holeになりますが。/var/tmp ディレクトリに置くことも 考えられますが後始末が面倒でしょう。 どちらにせよ、後でftpでファイルを適切な位置にコピーしなければなりません。 ファイルをコピーするとその所有者は自分になります。

CGIがSuEXECやsbitによって自分の権限で実行されるなら、 生成される実行ファイルは自分所有なので自分のディレクトリに自由に 新設することができます。ただしsh scriptのsbitは無視されるのが 仕様かもしれません。Perl scriptでコンパイルしますか。

出来上がったC/C++製実行ファイルをCGIとして実行できるでしょうか? sh か perl 製の実行ファイルしかCGIとして 実行させないようになっているかもしれません。それでも その sh製CGIからそのC/C++製実行ファイルを実行することはできます。

以上いろいろ記したように、web serverでコンパイルを強行するには いろいろな知識が必要そうです。 以下に比較的恵まれた環境でのコンパイルの強行法を紹介しますが、 各自の環境での解決策は これらのヒントを参考にして各自で解決策を見つけて下さい。

それともケーブルテレビのインターネット常時接続 サービスを利用して自分のパソコンを web server にしてしまうことです。 月額5000円程度でできるそうです。


● Web server でのコンパイルの例

ここで紹介方法でコンパイルを行うプロバイダの web server は以下のような好条件を持っているとします。

将来 複数のCGIをコンパイルすることを考えると Makefile を用意した方が良さそうです。なのでまず、 makeコマンドを実行するためのsh製CGI scriptを用意します。 名前は make.cgi にしましょう。

#!/bin/sh
# make.cgi

echo "Content-type: text/plain"
echo ""
echo "Start make"
make all
echo "End make"
そしてそのMakefileは以下の通りです。
### Makefile

## コンパイルする CGI の名前を列挙する
CGI = cgitest1 cgitest2

## コンパイルのルール
.SUFFIXES:
.SUFFIXES: .cc

## 拡張子 cc のファイルの取扱の記述
.cc:
# コンパイルして拡張子無しの実行ファイルを生成する
	gcc -O2 $< -o $@ 2>&1
# 生成した実行ファイルのモードを適切に変更する
	chmod 0701 $@
# 実行ファイルを起動するための sh製のCGIを用意する
	@if [ ! -f $@.cgi ]; then \
	        echo -e "#!/bin/sh\nexec ./$@" '$$*' > $@.cgi; \
		chmod 0705 $@.cgi; \
	fi

## make all で全部コンパイルされる
all: $(CGI)
Makefile特有の表現が多くて何をしているのかわからないかもしれませんが、 要するに各ソースファイルを普通にコンパイルして、
gcc -O2 cgitest.cc -o cgitest
出来た実行ファイルを起動するための以下の内容のsh製CGI scriptを 作成するだけです。
#!/bin/sh
exec ./cgitest $*

そしてこれらのファイルをアップロードして、 ftpで make.cgi の permission を 0705 に変更します。 webからこの make.cgi を実行します。 うまく動けばコンパイル中のメッセージが browserに 表示されるでしょう。うまくコンパイルできてれば 各CGIの実行ファイルと、各CGIの起動用の sh script が作成されているはずです。 C/C++製CGIはみごと動くでしょうか?

make.cgi はweb経由で誰でも実行できるので、なんらかの対策を とるべきです。安直にはmakeが済んだら消すか、.htaccessで 色々アクセス制限しておくかです。


目次

Copyright(C) by Naoki Watanabe. Oct 21st, 1995.
渡辺尚貴 naoki@cms.phys.s.u-tokyo.ac.jp