2012年5月21日月曜日

strncat

http://www9.plala.or.jp/sgwr-t/lib/strncat.html

ライブラリ関数の細かいところで何があるのか忘れてるのでリファレンス的な何かが無いかと検索したところなにやらstrncatの使い方が気になりました。

strncat(buffer, index_file, sizeof(buffer));

となっている部分。
これってbufferのサイズを超えてセットされませんかねぇ…
検索して引っかかったページの仕様とgccのライブラリの仕様が違うのかな?

どんな解釈が一般的だったかとかもあやしいのですけど。

delphiの解説で引っかかったページでは
#include <stdio.h>
#include <string.h>

void main(void)
{
 char *buf1="Borland";
 char buf2[]=" Delphi";
 
 strncat(buf1,buf2,strlen(buf2));
 printf("連結後:%s\n",buf1);
 getchar();

}
とかサンプルコードが載ってますけど、これこんなことしちゃいかんような(笑)
思いっきりリテラル領域を壊してる気がしますけどねw

いや…やりたいことは違うことなんですが。

vi

テキスト編集をしようとしたら [i] キーで入力してカーソルキーを押したら動作が変態的なことに…
AとかDとか表示されて改行されたり(笑)

さっそく「ubuntu vi コマンド」とかで検索してみると…
Ubuntu日本語フォーラム
で
$ sudo apt-get install vim
で幸せになれるとかで早速入れてみました。

vimとviって別物なんですね。
siriuth@ubntu-VirtualBox:~/dev/openwrt/backfire_10.03.1/package/uhttpd/src$ sudo apt-get install vim
[sudo] password for siriuth:
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています               
状態情報を読み取っています... 完了
以下の特別パッケージがインストールされます:
  vim-common vim-runtime vim-tiny
提案パッケージ:
  ctags vim-doc vim-scripts indent
以下のパッケージが新たにインストールされます:
  vim vim-runtime
以下のパッケージはアップグレードされます:
  vim-common vim-tiny
アップグレード: 2 個、新規インストール: 2 個、削除: 0 個、保留: 439 個。
7,371 kB のアーカイブを取得する必要があります。
この操作後に追加で 28.6 MB のディスク容量が消費されます。
続行しますか [Y/n]? y
取得:1 http://jp.archive.ubuntu.com/ubuntu/ oneiric-updates/main vim-tiny i386 2:7.3.154+hg~74503f6ee649-2ubuntu3.1 [373 kB]
取得:2 http://jp.archive.ubuntu.com/ubuntu/ oneiric-updates/main vim-common i386 2:7.3.154+hg~74503f6ee649-2ubuntu3.1 [86.5 kB]
取得:3 http://jp.archive.ubuntu.com/ubuntu/ oneiric-updates/main vim-runtime all 2:7.3.154+hg~74503f6ee649-2ubuntu3.1 [5,944 kB]
取得:4 http://jp.archive.ubuntu.com/ubuntu/ oneiric-updates/main vim i386 2:7.3.154+hg~74503f6ee649-2ubuntu3.1 [967 kB]
7,371 kB を 14秒 で取得しました (510 kB/s)                                                                     
(データベースを読み込んでいます ... 現在 130514 個のファイルとディレクトリがインストールされています。)
vim-tiny 2:7.3.154+hg~74503f6ee649-2ubuntu3 を (.../vim-tiny_2%3a7.3.154+hg~74503f6ee649-2ubuntu3.1_i386.deb で) 置換するための準備をしています ...
vim-tiny を展開し、置換しています...
vim-common 2:7.3.154+hg~74503f6ee649-2ubuntu3 を (.../vim-common_2%3a7.3.154+hg~74503f6ee649-2ubuntu3.1_i386.deb で) 置換するための準備をしています ...
vim-common を展開し、置換しています...
未選択パッケージ vim-runtime を選択しています。
(.../vim-runtime_2%3a7.3.154+hg~74503f6ee649-2ubuntu3.1_all.deb から) vim-runtime を展開しています...
'vim-runtime による /usr/share/vim/vim73/doc/help.txt から /usr/share/vim/vim73/doc/help.txt.vim-tiny への退避 (divert)' を追加しています
'vim-runtime による /usr/share/vim/vim73/doc/tags から /usr/share/vim/vim73/doc/tags.vim-tiny への退避 (divert)' を追加しています
未選択パッケージ vim を選択しています。
(.../vim_2%3a7.3.154+hg~74503f6ee649-2ubuntu3.1_i386.deb から) vim を展開しています...
man-db のトリガを処理しています ...
vim-common (2:7.3.154+hg~74503f6ee649-2ubuntu3.1) を設定しています ...
vim-tiny (2:7.3.154+hg~74503f6ee649-2ubuntu3.1) を設定しています ...
vim-runtime (2:7.3.154+hg~74503f6ee649-2ubuntu3.1) を設定しています ...
Processing /usr/share/vim/addons/doc
vim (2:7.3.154+hg~74503f6ee649-2ubuntu3.1) を設定しています ...
update-alternatives: /usr/bin/vim (vim) を提供するために 自動モード で /usr/bin/vim.basic を使います。
update-alternatives: /usr/bin/vimdiff (vimdiff) を提供するために 自動モード で /usr/bin/vim.basic を使います。
update-alternatives: /usr/bin/rvim (rvim) を提供するために 自動モード で /usr/bin/vim.basic を使います。
update-alternatives: /usr/bin/rview (rview) を提供するために 自動モード で /usr/bin/vim.basic を使います。
update-alternatives: /usr/bin/vi (vi) を提供するために 自動モード で /usr/bin/vim.basic を使います。
update-alternatives: /usr/bin/view (view) を提供するために 自動モード で /usr/bin/vim.basic を使います。
update-alternatives: /usr/bin/ex (ex) を提供するために 自動モード で /usr/bin/vim.basic を使います。
siriuth@ubntu-VirtualBox:~/dev/openwrt/backfire_10.03.1/package/uhttpd/src$
 ということで無事に入れることができました。

コンパイル環境

やはりバイナリイメージを動かしていたのでは限界が見えてきたのでコンパイル環境をなんとかならないかと右往左往していましたが最終的にVirtualBoxとUbuntu11.10で落ち着いた感じです。

ただVirtualBoxが悪いのかUbuntuが悪いのかわかりませんがどうもmake中で各サイトから必要なリソースを引っ張ってくるところで何度もVM自体がフリーズしていました。

makeするときにV=99をつけると細かいメッセージまで表示されるのである程度は判断がつくようになり判断がつく限り直接ダウンロードしたものをdlフォルダに入れて対応したところまともにコンパイルが通るようになりました。

色々躓きはしましたが…。

直接的な部分ではuhttpdを手直しして使いたいだけなのでパッケージだけでもコンパイルできればとおもって始めたのですが最終的には全コンパイルをかけていました。

VMなのでコンパイルにはかなり時間がかかりました。
ざっとデフォルトで2,3時間。そこから全パッケージがまた2,3時間。
CPUを半分以上ほかのものが使用していたとは思いますが(笑)

Ubuntuはかなり今風のつくりになっていてターミナルを開くのにも一苦労です。
[ALT]+[F2]でファイル名を指定して実行できるのでそれが救いでした。(最初はどうしようかと(笑))

失敗談としてはCygwinでできるかな?と頑張っては見たのですがOpenWrtのHowToにもかいてありますが無理でした。svnでソースは持ってこれるのですが、makeをしようとするとroot権限を持っているといろいろダメみたいでした。FORCE=1をつけてやったりもしましたが…

ただ最初はfeedとかもいれてなかったし色々足りなかったのは確か。

2012年5月18日金曜日

uhttpd: index_pageの指定は一つしかできない

昨日uhttpdでindex_pageの指定で複数のファイル名を設定できたと勘違いして記事を書いてみたのですが後から見直すとどうもやはり一つしか対応できないようで、本格的にソースを見てみました。

まずソースは/package/uhttpd/srcの中にあり適当に見てみます。
$ grep "index.html" *
uhttpd-utils.c: "index.html",
コンスタントで定義されているのはuhttpd-utils.cの中ということがわかります。
static char *uh_index_files[] = {
    "index.html",
    "index.htm",
    "default.html",
    "default.htm"
};
と定義されています。確かに4つデフォルト値が配列として定義されているようです。
次にuh_index_filesはどこで使われているかというと、
 $ grep "uh_index_files" *
uhttpd-utils.c:static char *uh_index_files[] = {
uhttpd-utils.c:                         for( i = 0; i < array_size(uh_index_files); i++ )
uhttpd-utils.c:                                 strncat(buffer, uh_index_files[i], sizeof(buffer));
同ファイルの中で使用されているというのはわかります。
その部分を実際に見てみると
            else if( cl->server->conf->index_file )
            {
                strncat(buffer, cl->server->conf->index_file, sizeof(buffer));

                if( !stat(buffer, &s) && (s.st_mode & S_IFREG) )
                {
                    memcpy(path_phys, buffer, sizeof(path_phys));
                    memcpy(&p.stat, &s, sizeof(p.stat));
                }
            }
            else
            {
                for( i = 0; i < array_size(uh_index_files); i++ )
                {
                    strncat(buffer, uh_index_files[i], sizeof(buffer));

                    if( !stat(buffer, &s) && (s.st_mode & S_IFREG) )
                    {
                        memcpy(path_phys, buffer, sizeof(path_phys));
                        memcpy(&p.stat, &s, sizeof(p.stat));
                        break;
                    }

                    *pathptr = 0;
                }
            }
ここで残念なことが発覚します。
定義されているものは配列でcl->server->conf->index_fileが定義されている場合はどうやら一つしか対応できないようです。

必死に複数の指定をしていたのですが残念な結果となりました。
蛇足ですがこの index_fileは2箇所で設定されていてコマンドラインの引数と/etc/httpd.confなどの設定ファイルから取得するようになっているようでした。(細かくは見ていませんが)

やはりソースを見るのが一番早いですね。

2012年5月16日水曜日

proftp: 起動時にエラー

rebootしたときにftpがつながらなかったので気になっていたのですが、システムログに
May 16 20:56:22 mzkw04nu user.info sysinit:  - Fatal: error processing configuration file '/etc/proftpd.conf'
とエラーと表示されていました。

/etc/init.d/proftp start

として起動するので細かい点は気にしていませんでしたが、rebootで起動しないのは問題があるので少し調べてみましょう。

まず原因がわからないのでとりあえず openwrt proftp で検索してみると
OpenWrt / proftpd not work
で、「DefaultAddress  127.0.0.1」を追加すれば良いということなので/etc/proftpd.confに追加して再起動してみました。
May 16 21:06:20 mzkw04nu user.info sysinit: udhcpc: ifconfig wlan0 *.*.*.* netmask *.*.*.* broadcast +
May 16 21:06:21 mzkw04nu user.info sysinit:  - setting default address to 127.0.0.1
May 16 21:06:21 mzkw04nu user.info sysinit: udhcpc: setting default routers: *.*.*.*
May 16 21:06:21 mzkw04nu daemon.notice proftpd[1295]: localhost. - ProFTPD 1.3.3e (maint) (built Mon Nov 14 2011 19:08:02 CET) standalone mode STARTUP
May 16 21:06:21 mzkw04nu user.info sysinit: udhcpc: setting dns servers: *.*.*.*
確かに起動するようにはなりました。
が、気になるのはデフォルトアドレスをローカルとする理由はおそらく実行時にゲートウェイがあるネットワークのIPアドレスが確定していないということなので、単純に起動順序の調整で話は終わりそうです。

追加したDefaultAddressをコメントにして、/etc/init.d/proftpdのSTARTを50からntpdと同じ65に下げてみます。
その後 /etc/rc.dのリンクを再作成するためにluciのスタートアップから(/etc/init.dの変更を行うと無効になっていますがS50proftpdのリンクは存在したままです。)有効に変更します。
それから再起動。
May 16 22:00:24 mzkw04nu daemon.notice proftpd[1479]: mzkw04nu.lan - ProFTPD 1.3.3e (maint) (built Mon Nov 14 2011 19:08:02 CET) standalone mode STARTUP
問題なく起動しました。
解決方法としてデフォルトアドレスをconfに追加するか、udhcpcが起動したあと起動すればよいということでしょうね。