Cで書いてクロスコンパイルしたバイナリをAndroidで実行する

備忘録です。ホストOSは x86 な WIndowsXP で、Android SDK を導入済み、Android 端末とUSB 接続で通信ができる状態です。

  1. こちらより、ARM用GCCのクロスコンパイラ環境(IA32 Windows TAR)をダウンロードして適当な場所に解凍。
  2. helloworldソース(hello.c)を用意し、
#include <stdio.h>
int main(int argc, char** argv)
{
  printf("Hello, world.\n");
  return 0;
}

コマンドプロンプトにて、

> (GCC-ARM)\bin\arm-none-linux-gnueabi-gcc -o hello -static hello.c
> (AndroidSDK)\tools\adb push hello /data/bin
> (AndroidSDK)\tools\adb shell
$ chmod 755 /data/bin/hello
# /data/bin/busybox chmod 755 /data/bin/hello
$ /data/bin/hello
Hello,world.
$

よし動く。

IS01の端末エミュレータやSSHクライアントでCtrlや ESCなどの特殊キーを使う

多くのスマートフォンでは、キー数を抑える為に特殊キーが搭載されていない場合がある。IS01 も例に漏れず、CtrlやESCといったキーがない。UNIXコマンドを使おうとすると、なかなか致命的である。

Android Terminal Emulator で特殊キーを使う

Android Terminal Emulator には、それを補う為に特殊キーを入力する方法が別途用意してある。

まず、Android Terminal Emulator を起動し、Menu キーを押下すると”Special Keys”というメニューが出てくる。このメニューをクリックすると Ctrl や ESC といった特殊キーの入力方法の早見が表示される。それによると、以下のようになる。

効果入力方法
Control-@(NULL)Ball-Space
Control-A..ZBall-A..Z
Control-[(ESC)Ball-1
Control-_Ball-5
Control-\Ball-.
Control-]Ball-0
Control-^Ball-6

表での Ball とは、スクロール時などにコロコロまわすトラックボールを押し込む事。例えば、トラックボールを押し込みつつ、数字の1を押すと、ESCキーが押された事になる。

これで、Busybox 版の vi や、C-c(シェルコマンドの中止)などを利用する事が出来る。

ConnectBot (SSHクライアント) で特殊キーを使う

こちらは Android Terminal Emulator よりもシンプル。

効果入力方法
ControlBall(1回押す)
ESCBall Ball(2回押す)

これで、tscreen をかました nethack でいつでも遊ぶ事が出来る。

# ところで、パイプ(|)はどうやって入力するんだろう?

追記

標準の Connectbot では、パイプに加え、その他の特殊キーも(物理的に)入力する事が出来ない。自力でビルドし直すか、クリップボードからのペーストで代用する他無かったが、この記事で、キーマップを変更したバイナリ(apk)が配布され始めた模様。

わーい後で試してみよう。

IS01 に Busybox をインストール

9月4日に購入したシャープの IS01 は、既に最新のファームウェアになっているようで、”/data/busybox”がパスから外されていた。それでも、Android Terminal Emulator 上で使う分には支障がないので、こちらを参考に、Android 用 Busybox を導入してみる。

WindowsXP における手順

IS01とホストマシンの通信環境を整える

  1. ホストマシンにて、IS01用USBドライバをインストールする。
  2. IS01 にて、設定 > アプリケーション > 開発 > USBデバッグ を有効にする。
  3. IS01 とホストマシンをUSBで接続する。
  4. ホストマシンにて、ドライバの設定画面が表示されるので、IS01用ADBドライバを解凍したフォルダを指定する。

IS01の開発環境を用意し、Busybox を転送する

  1. ホストマシンにて、Android SDK をダウンロードし、解凍、SDK Manager.exe を使って必要な環境をセットアップする。
  2. ホストマシンにて、Busybox for Android のバイナリをダウンロードし、Android SDK の Tools フォルダに入れる。
  3. IS01 とホストマシンをUSBで接続する。
  4. ホストマシンにて、コマンドプロンプトを起動し、以下のように Android SDK の Tools フォルダに移動してコマンドを実行する。

2010/12/16追記:最近の SDK では、adb コマンドは platform-tools フォルダに入っている模様。以下、tools フォルダと読み替えてください。

> cd c:\androidsdk\tools
> adb shell mkdir /data/local/bin
> adb push busybox /data/local/bin/busybox
> adb shell
$ cd /data/local/bin
# このBusyboxバイナリは、/data/busybox 配下にリンクを吐くようになっているので、
# インストール前に、あらかじめディレクトリを掘っておいてやる必要がある。
$ mkdir /data/busybox
$ chmod 755 busybox
$ ./busybox --install
# 吐いたリンクを ATE で追加されるパスの位置へ移動。
$ ./busybox mv /data/busybox/* /data/local/bin/
# 例にならって ls と su はオリジナルのを使用。
$ ./busybox mv ./ls ./ls0
$ ./busybox mv ./su ./su0
# 不要なディレクトリは削除。
$ ./busybox rm -r /data/busybox

Android Terminal Emulator を入れる

IS01 にて、Android マーケットより Android Terminal Emulator をインストールする。

このターミナルは起動時に、

export PATH=/data/local/bin:$PATH

してくれるので、各コマンドのシンボリックリンクの詰まったディレクトリがパスに入り、以後、Busybox コマンドを優先的に利用する事が出来る。また、Busybox の組み込みシェルである sh、ash を起動すると、コマンド履歴など、一般的なシェルの機能を利用する事が出来る。

# adb shell 接続時には毎回PATHを再設定してやらないといけないのでメドい。*rcファイルみたいなものがあればいいんだけど、調べてみよう。

オープンソースの.NET実装”mono”を使ってみた

週末に大学へ出張に行く為、ネットブック上のUbuntu上のVirtualBox上のWindowsXPに開発環境を作っておこうと思いVisualStudio.NETのインストーラと一日中闘っていた。なかなか上手く行かず、エラーダイアログが出るもMicrosoftへのコアダンプレポートばかり。バイナリインストーラなのでお手上げ状態だった。そんなこんなで、かねてから噂に聞いていたmonoを使ってみた。以下、自分の感想文だから有用な情報はない。

mono/vb.net on windows

monoの公式サイトに行って、Windowsバイナリを落としてくる。インストールウィザードに従い、フルインストール。スタートメニューに登録されるmono用のシェル(多分コンパイラ等にパスを通しただけのもの)を起動しワークディレクトリに移動する。

test.vbを下記のように作成。

test.vb

Module a
  Sub Main()
    System.Console.Write("Hello,mono")
  End Sub
End Module

コマンドプロンプトから、

> vbnc /nologo /codepage:65001 test.vb 

を実行するとビルドを行い、成功すると

> test
Hello,mono

が出力される。/codepage:65001はUTF-8なソースをコンパイルするオプション。省略すると、932(ShiftJIS)として解釈されるようだ。/target:winexeを指定すると、System.Windows.Forms.*も問題なく動いた。

今のところ.NET Framework 2.0ベースで、3.5や4.0に依存していない開発ばかりだから、入力補助さえ準備出来たら、VisualStudioは不要な気がする*1

System.Data.*でMS-Accessファイルを扱う事も出来た。GUIはGtk#が入ってたけど、特に指定しない限り、Windowsネイティブのコントロールを使うみたい。.NET Framework2.0相当の環境が入っている別のWindows上でいくつかテストしてみても、ちゃんと動いている。すごく楽しい。

mono/vb.net on ubuntu

$ sudo aptitude update$ sudo aptitude mono-devel mono-vbnc

で入る。上記と同じくtest.vbを用意し、

$ vbnc /nologo /codepage:65001 test.vb && ./test.exe

でビルド&実行出来た。Ubuntu側でビルドしたtest.exeを恐る恐るWindowsXPに持っていき、コマンドプロンプトから実行してみると

> test
Hello,mono

おおっ。ちゃんと動いたー!

これは本当に楽しい。本格的に調べてみよう。

*1:.NETを使い始めた頃、VisualStudioのデザイナーを多用してしまいすごく手間取った事がある。以来、レイアウトにデザイナーを使う事はなくなった。

腰痛

先週の月曜日(21日)に大手病院に行き、整形外科の先生に診てもらった。

近所の整形外科にて、「上司に『大手病院に移ってちゃんと直して来い』と言われたので、大手病院向けに紹介状を書いてください」と(オブラートに包んで)言った時もいい顔はされなかったが、こちらでの対応もあまり良くなかった。

「○○(近所の整形外科)さんでそういう診断だったら、うちに来たところで行う治療は変わらんよ。手術はする必要ない、安静にしておきなさい。」

ちゃんとした設備で検査をして会社に報告する義務がある。そう事情を説明しているのに話が通じてないみたいだった。相手は30代くらいの外科医師。免許を取ったところで、常日頃ゆるい診察業務ばかりしていると、こういう考えと態度が直結してしまうんだろうな、と冷めつつ思った。

「は?MRI?まあ、別の撮ってもいいけど、診断が変わる事はまずないよ」

全ての医師という訳ではないが、必ずしも愛想の良い先生ばかりとは限らない。ただ、診察料や保険料をちゃんと納めている患者に対して、もうちょっと労りがあってもいいんじゃないかなあ。足が痛い中遠出して尋ねて来て、何時間も待たされた挙句これなんだから。と、不満を強く言うのも、この発言が一週間後に、医師本人の口から覆されるからだった。

f:id:dyama:20100630161028j:image:right

今週の月曜日、午前10時半に、MRIで精密検査をする予約を取り付けていた。

本来ならば、初診の当日にでも検査してもらい、手早く会社に報告したかったが、大病院が故に”予約がいっぱい”だとの事。患者は胡座をかいててもやってくるもんだと思ってるかもしれないが、そんなポンポン会社を休む訳にもいかないんだよ。

放射線科でMRIを撮影し終え、現像されたフィルムを受け取ったのは昼過ぎた頃だった。整形外科に着いた時は、外来診察時間が過ぎた頃だったので、ほとんど待たずに診察を受ける事が出来た。

「痺れは大丈夫かい?ヘルニアが結構大きいね。しかも、ココとココ、二箇所もある」

前回は外来診察時間で忙しかったのかなあ、と思わせるほど対応が違っていた。ちゃんと患者扱いしてくれそうだ。

MRIフィルムをトレス台みたいなのにかざして指を差す。確かに尾骨の上らへんの椎間板がハミデント。

すると医師はこう言った。

「医者が10人居たら、まず8人は手術を勧める。まあ、最後は本人の意思だけどね」

うわあ、診断を覆しやがった!

前回の日記にも書いたとおり、自然治癒で直していく治療法が基本だが、ヘルニアの具合が酷い場合は手術した方が良いらしい。その手術の必要性という面で、初診と今回、正反対の事をおっしゃっている。患者にとっては一番重要なところなんですが・・・。やっぱり、嫌々押しながらも MRI を受けて正解だった。

骨にひびが入った程度の骨折ならギプスで固定してほっておけば、自然治癒でくっつく。手術が必要な場合は、ギプスではどうにもならない程、骨が砕けている場合やズレている場合。直すのは自然治癒の力であっても、ほっておいたら元どおりにならない場合と想像出来る。

では、今回の手術は何の為に行うんだろう?ほおっておいたらヤバいのか。それとも、単に(自然治癒より)早く直す為のものだろうか。そこのところを医師に聞きそびれたが、自分では後者だと思っている(自己診断は危険だけど、手術は本人の意思次第って話だし)。大至急手術をしろというニュアンスでもなかった。現に、「会社と相談させてください」と言い、会社宛に診断書を書いてもらっている。

この診断書を持って会社に報告しに行った。社長と相談した結果、「1~2ヶ月ほどそのまま様子を見て、仕事のタイミングが合えば手術する」という方向になった。

手術をしても完治する保証はない、お金もかかる。しかし腰痛を持病にはしたくない。

困ったなあー。

我が家がやっと地デジ対応

先日、DELLのオンラインショップで新しい液晶ディスプレイを購入した。24インチワイドで、HDMI対応モデルだ。送付してきた時の梱包材にハングルがあったので、きっと中身はLGかヒュンダイ製。安かったワケだ。

これで光映像表示デバイスは携帯電話の有機ELディスプレイを含めて14台となった我が家だが、引っ越してきてから”マトモに映るテレビ”は持っていなかった。

というのも、ビルの屋上にさらにプレハブ小屋が積んである隣家*の関係で電波を上手く受信出来ないのだ。どう見ても違法改築物件です。本当にありがとうございました。

一番マトモに受信するのは、携帯電話のワンセグ放送。それでも民放3、4局くらいしかちゃんと映らず、NHK教育に至っては音声すら聞き取れない。

  • PS3を去年の年末に買ったが、数日間FF13で遊んだ程度で、そのまま電源を入れる事がなかった。これは折角買ったんだから活用したい。
  • 24インチワイド液晶を買った。これも折角HDMI対応を選んだんだから活用したい。
  • 以前、6980円も出して購入してアナログ放送を見ようとしていた日本アンテナ製室内アンテナ(ブースター付)も埃をかぶっていた。活用しないとなあ。

ワンセグ画質や画面の小ささにもいい加減飽きて来たところで思い出したのが、数ヶ月前発売され話題になった、Playstation3用地デジチューナ&レコーダ「torne(トルネ)」だった。

受信感度劣悪の環境下で、コイツを購入するのは多少不安だったが、ほぼ杞憂だったと言っても過言はないだろう。

設置とインストールを終え、おそるおそる起動してみると、早速1080pのフルHD放送が飛び込んで来た。やった!これで勝つる!

これまで携帯電話の画面だったので、面積比は数百倍! 家に居ない時でもざくざく録画し放題!ヒャッハー!

その直後、サッカーワールドカップ南アフリカ大会決勝トーナメント「日本対パラグアイ」のキックオフから延長前後半&PK戦までを、これまでに見た事もないような高画質で目の当たりにするとは思いもしなかった。

なお、到着&設置したその日に torne の Ver2.0 とシステムソフトウェア v3.40 がリリースされたみたい。インストール直後にアップデートが始まったので、まさかその日に公開された最新機能とは気付かなかった。

IRCのDCCファイル送信は簡単に”横取り”する事が可能

IRC(Internet Reray Chat)には、DCCというファイル送受信や個人チャット用途に設けられた機能がある。Direct Crient-to-Crient という名前のとおり、IRCサーバを介しない通信に用いられる。これには、以下の2つの利点と目的がある。

  • ファイル送受信など、大量のデータをやり取りする際、IRCサーバを経由するよりもクライアント同士が直接通信した方が転送効率が良い。また、サーバに負荷をかける事がない。
  • IRCサーバは他人が管理している為、そこを経由した会話は絶対安全だという保証はない。クライアント同士が直接通信する事によって、ある程度のセキュリティを保つ事が出来る。

DCCは、ファイル送受信を例に挙げると、以下のような仕組みで実現されている。

  1. ファイルの送信元がIRCサーバを経由して、以下の情報(DCCファイル受信リクエスト)を送信先に伝達する。
    送信元nick ファイル名 送信元IPアドレス:ポート番号 ファイルサイズ
  2. リクエストを送信後、その情報どおりにファイル送信の待機状態(Listen)に入る。
  3. リクエストを受け取った送信先は、ユーザにその旨を通知し、ファイルを受信するか否かを決定してもらう。
  4. ファイルを受信する場合、送信先はリクエストの情報を元に通信経路を確立。ファイルを受信した後に切断する。

昨今のIRCクライアントは洗練されたものが多く、Windows Live メッセンジャーのようにサーバを経由しない為、快適にファイルを送受信する事が出来る。

さらにIRCプロトコルは非常にシンプルに出来ており、RFCなどを参考にIRCコマンドを直打ちすれば、telnetコマンドでもチャットに参加し会話する事が出来る。DCCも同様に、IPアドレスとポート番号が分かっているならば、telnetでも接続は可能なはず。

という事で以前、DCCの設定を行っていた際にこんな実験をしてみた。

telnet でファイル受信

上の表の2番までを行った状態で、シェルより以下のコマンドを実行する。

$ telnet 送信元IPアドレス ポート番号

すると、送信するファイルのデータが一気に流れてくる。プロトコルも何もない本当の生データが流れてくる。

送信するファイルをテキストにし、キャラクタセットを送信先のシェルに合わせれば、テキストファイルの中身がそのまま表示される事となる。

Windowsのコマンドプロンプトを例にすると、以下のとおり。

  1. ShiftJIS/CR+LF改行のテキストファイルを準備し、IRCクライアントから送信先にDCCファイル受信リクエストを送る。
  2. IRCクライアントは、接続待機状態に入る。
  3. 送信先に表示されたリクエストを参考に、送信先ホスト上で、コマンドプロンプトから上のコマンドを実行する。
  4. コマンドプロンプトにテキストファイルの情報が表示される。

ここであれっと思ったのは、IRCクライアント側がどうも実際に受信をしているホストをチェックしていない点だ。

リクエストを送っていない人が勝手に受信

実際に受信をしているホストをチェックしない、とはどういう事だろうか。

以下に分かりやすく、例を示す。

ファイルの送信元をAlice、送信先(つまり受信者)のBob、同じIRCサーバに居る第三者をEveとする。

  1. Alice「ねえBob、ファイルを送るから後で読んでね」
  2. AliceがBobに対して、テキストファイルを送ろうとして、DCCファイル受信リクエストを送った。
  3. ( Bobは離席しているようだ。一向に受信する様子はない。 )
  4. Alice「あれ、居ないのかな?」
  5. それを同じチャンネルで見ていたEveは、IRCサーバに問い合わせ、AliceのIPアドレスを調べた。
  6. Eve「AliceのIPアドレスは、XXX.XXX.XXX.XXXか。彼女は確かLimeChat2を使っていたはず。」
  7. Eve「LimeChat2のデフォルトのDCCファイル送信用ポート番号は1096~1195。ポート開放程度は出来ても、ネットワークには疎いあの子の事だからデフォルト値のままのはず。」
  8. Eve「さらに彼女のログイン時刻はつい数分前だから、ファイル送信にListenしているポートはきっと、1096ね。」
  9. そう呟いたEveは、シェルを起動し、「$ telnet XXX.XXX.XXX.XXX 1096」を実行した。
  10. Alice「あ、Bobがファイルを受信してくれたっ」
  11. シェルに映し出された赤裸々なメッセージ。Eveは一人ほくそ笑んだ。
  12. Eve「アラアラウフフ」

この場合、もちろんBobにはAliceのテキストファイルは届いていない。Eveが横取りをして、受信してしまったからだ。

検証したのはLimeChat2だけだが、現在のIRCクライアントのほとんどが、「DCCファイル受信リクエストを出した相手(本来の受信者)」と「ファイルの受信をしに来た相手(本来の受信者かどうか不明)」が同一であるかどうか、チェックしていないと思われる。つまり、リクエストを送信しListenした状態は、誰が接続して来ようがファイルを送信してしまうのだ。

Eveが本気で悪意を持った場合

上の例では、どこぞやのバーロー名探偵の事件のように希望的観測に基づいた推論が都合良く成立している。これではあまり現実味がないし、悪意がある側の効率だって悪い。Eveが本気で悪意を持った場合、次のようなツールを書くだろう。

  • IRCサーバからターゲットのIPアドレスを取得。
  • 効率を上げる為に、ターゲットに対してポートスキャンを実行。LimeChat2のようにある程度ポートの範囲が絞れている場合は、やらなくても可*1
  • DCC送信ポートを監視。接続可能になるまでくりかえす。
  • コネクションが成立したら、あとは送信してきたデータを受信し、保存する*2

このようなツールは、数時間もかからずに出来てしまいそう*3。上のやりとりの例のように手間暇をかけずとも、ツールを起動しておくだけでターゲットの送信ファイルを横取り出来るのだ。

横取りされたAliceにとって、彼女のクライアントには「Bobに対するDCCファイル送信が完了した」と表示され、Bobには「AliceがDCCファイル受信を要求している」という表示になっているまま。Eveに横取りされているとも知らず、戻ってきたBobが受信を開始しようとしてもエラーが起きて受信は出来ない。さらに、AliceやBobがDCC送信ポートの設定もやっとな知識のユーザであったら、「ポートの調子が悪いのかな」程度に思い、横取りされた事実さえ気が付かないかもしれない。

対策

LimeChat2には、DCCファイル受信リクエストが来たら自動的にファイルを受信する機能がある。もしも送信先がそのような設定になっていれば、ツールによる横取りも100%ではないがある程度防げると思う。ただし自動受信自体、セキュリティ的にはあまりオススメできる手段でも無い為、根本的な解決にはならないと思われる。

ホストチェックの仕組みは、RFCを弄らずとも各クライアントの対応でなんとかなりそうなので、各クライアントレベルでの対応が望ましい。

なお、今回検証はしていないが、DCCチャットも同じ事が言えるかもしれない。

以上、知っている人にとっては今更な情報かもしれないが、知らなさそうなユーザがたくさん居る事についての警鐘の意味も兼ねて、ここに記載した。

細かな事は知らなくてもいいと思うが、「横取りされ得る」という事実だけは、しっかりとユーザの間で認知されるべきではないだろうか。

ちなみに今回は、多くのWindowsユーザが利用しているLimeChat2を中心に検討を行ったが、LimeChat2が悪いソフトと言う訳ではない。むしろGUIクライアントとしては最高のものだと思っている。

*1:CTCPでクライアントの種類を取得可能な場合がある

*2:ファイルの種類は file filename

*3:while :;do nc -w 1 -o tmp XXX.XXX.XXX.XXX:1096; sleep 1; done

シェルスクリプトでジョイスティックを使う

シェル芸

ふと思い立って調べてみたので、備忘用に書いておきます。利用ハードウェアはエレコムのJC-U2312FSV。12ボタン、十字キー、アナログ2軸のゲームコントローラーです。

# 検証方法(信号を16進数8バイトずつ表示)
cat /dev/input/js0 | od -tx1 -Ax -w8

js0デバイスを開くと、必ず以下のようなバイナリが流れて停止します。

000000 bc e7 8f 00 00 00 81 00
000008 bc e7 8f 00 00 00 81 01
000010 bc e7 8f 00 00 00 81 02
000018 bc e7 8f 00 00 00 81 03
000020 bc e7 8f 00 00 00 81 04
000028 bc e7 8f 00 00 00 81 05
000030 bc e7 8f 00 00 00 81 06
000038 bc e7 8f 00 00 00 81 07
000040 bc e7 8f 00 00 00 81 08
000048 bc e7 8f 00 00 00 81 09
000050 bc e7 8f 00 00 00 81 0a
000058 bc e7 8f 00 00 00 81 0b
000060 bc e7 8f 00 00 00 82 00
000068 bc e7 8f 00 00 00 82 01
000070 bc e7 8f 00 00 00 82 02
000078 bc e7 8f 00 00 00 82 03
000080 bc e7 8f 00 00 00 82 04
000088 bc e7 8f 00 00 00 82 05

このヘッダ信号は、有効なボタン/軸情報の申告かな。最初の4バイトが全て同じ値なので、メーカーまたは型番番号or以下に続くキーイベントのカウンタと区別するものかもしれない。

続けて、0番、1番ボタンを順に押下すると

000090 30 b1 91 00 01 00 01 00 ← 0番ボタン押下
000098 a0 b1 91 00 00 00 01 00 ← 0番ボタン離す
0000a0 70 b6 91 00 01 00 01 01 ← 1番ボタン押下
0000a8 e0 b6 91 00 00 00 01 01 ← 1番ボタン離す

と分かりやすい結果が出てきました。さらにいくつか押下してみると、以下の事が分かりました。

  • キーイベントは8バイト構成
  • それぞれの内容は以下のとおり
バイト順内容
1~4バイト目同期用カウンタ?初期値不明。
5~6バイト目ボタン(押=1/離=0) or 方向(座標情報)
7バイト目ボタンイベント時=1/方向イベント時=2
8バイト目ボタン番号(0~c) or 軸情報(LX=0/LY=1/RX=2/RY=3/CX=4/CY=5)

※ 複数バイト値はリトルエディアン

7バイト目がフラグになっており、このイベントが通常ボタン押下なのか方向操作なのかを通知しているようです。

7バイト目が1、つまり通常ボタン押下の場合、5~6バイト目が unsigned short で押した(1)か離した(0)かの情報、8バイト目が char でキー番号(0~c)となります。

また、7バイト目が2、つまり方向操作の場合、5~6バイト目が signed short のずれ量(アナログスティック時)、8バイト目が軸情報となる。十字ボタンの5~6バイト目は以下のとおり。

キー方向情報軸情報
80014
7fff4
80015
7fff5

※リトルエディアンなので、下位8ビットが5バイト目にあたります。

十字ボタンの値は、固定値のようだ。また、十字ボタンが離された際には、5~6バイト目はヌル(0)となります。

1~4バイト目は、キューが混乱した場合にちゃんとソート出来るようにした目印カウンタかな。

歴史的背景のあるキーボードの信号より、すごくシンプルで分かりやすいと思いました。きっと似たようなフォーマットで軸や強度、モーター情報を拵えて js0 に write してやると、振動してくれそうだー。

これを元に、ジョイスティックキー検知を行うシェルスクリプト関数を書きたいと思います。

VB6プロジェクト内で利用されていないクラスファイルをリストアップするスクリプト

他人から引き継いだ古いVB6プロジェクトが、使っていないライブラリまみれで見通しが悪かったので書いた。目的も使用方法が限定されているので、得する人は居ないと思う。

#!/bin/bash
# find up the not required classes for msvb6proj
# usage: `bash nrc.sh srcdir | xargs rm`
dir=$@;
dir=${$@:-"."};
# if [ $# -lt 1 ]; then
#     dir=".";
# else
#     dir=$@;
# fi
classes=`find $dir -name '*.cls'`;
files=`find $dir -name '*.bas' -or -name '*.frm'`;
for filename in $classes ; do
  classname=`grep "VB_Name =" "$filename" | sed -e 's/Attribute VB_Name = "//i' -e 's/"//gi'`;
  flag=0;
  for target in $files $classes; do
    [ $target == $filename ] && continue;
    m=`grep -e " As $classname\>" -e " New $classname\>" -e "Implements $classname\>" "$target" | wc -l`;
    echo Found $m $classname in $target 1>&2;
    if [ $m -gt 0 ]; then
      echo "---next-->" 1>&2;
      flag=1;
      break;
    fi
  done
  if [ $flag -eq 0 ] ; then
    echo "*** HIT ***" 1>&2;
    echo $filename;
  fi
done
exit;

品質無保証。

fortuneコマンドについての雑記

UNIXのおみくじコマンド

fortuneコマンドは、実行すると、あらかじめ用意された気の利いた文句や冗談、偉人の名言などの中から一文をランダムに表示するコマンドだ。オリジナルのfortuneコマンドは、ランダムで面白い文章を結果として出力する事から、昔からUNIXユーザの間で親しまれてきた「おみくじ」、最近の流行で言うと、組み合わせた文章を表示させる事こそ出来ないが「診断メーカー」のような存在と言ってもよさそうだ。

特に利用目的に制限はないのだが、通常、fortune コマンドはシステムへのログイン時に実行される。以下は、私の Debian サーバにログインした時の出力例である。

Using username "user".
user@example.com's password:
Linux alice 2.6.25.1-kuroboxHG #9 Sun May 4 21:29:57 JST 2008 ppc GNU/Linux
Last login: Fri Apr 23 09:01:54 2010 from 210.226.XXX.XXX
「再帰」を定義するには、我々は最初に「再帰」を定義しなければならない。
user@alice:~$

MOTD の次に fortuneコ マンドによるメッセージが表示される。表示させるメッセージ集は、様々なところで公開・配布されている。大半が英語なので、自分の場合は「コンピュータ・ジョーク」や「真・コンピュータ用語辞典」の冗談を中心に借用している。

フォーチュン・クッキー

f:id:dyama:20100423105010j:image:right

このコマンドに関する海外の文献では、「fortuneコマンドの元となったのは中華料理店で出されているフォーチュン・クッキーである」と、書かれている事が多い。それらの邦訳であっても、大抵の場合直訳であって、それ以上の事は書いていない為、我々日本人も「フォーチュン・クッキーとは、中国の焼き菓子なのかあ・・・」なんて考えてしまいそうだ。しかし、そのルーツは中国ではなく日本にあった。Wikipedia のフォーチュン・クッキーの項目には以下のような記述がある。

フォーチュン・クッキー (fortune cookie) とは、中に運勢の書かれた紙片の入った菓子である。アメリカ合衆国・カナダの中華料理店では殆どの店で食後に出される。

日本の北陸地方の神社で新年の祝いとして配られていた辻占煎餅に由来するもので、形は辻占煎餅そのままである。

1894年、サンフランシスコのゴールデン・ゲート・パークで開催された国際見本市(California Midwinter International Exposition)で、日本庭園を設計し、運営していた萩原は、煎餅(英語ではJapanese cookieという)を二つ折りにしてその中に言葉を書いた紙を入れたものを、店を訪れる客にお茶請けとして出した。幾つかの中華料理店がこの煎餅を取り入れ、フォーチュン・クッキーは非常に一般的なものとなった。現在では多くの飲食店で、食事後の口直しとしてフォーチュン・クッキーが出されるようになった。

上記の様な経緯から、中国の習慣であると誤認しているアメリカ人も少なくない。しかし中国ではフォーチュン・クッキー自体知られていない。

https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A9%E3%83%BC%E3%83%81%E3%83%A5%E3%83%B3%E3%83%BB%E3%82%AF%E3%83%83%E3%82%AD%E3%83%BC

北陸のおみくじ煎餅が100年以上前に海を渡り、北米ローカルの中華料理店のメニューとなり、さらにはUNIXコマンドのひとつとなっていたのである。ちなみに日本国内でも、辻占煎餅よりも逆輸入されてきたフォーチュン・クッキーの方が流通しているようだ。面白いなあ。

シェルスクリプトで

そんな fortune コマンドだが、実行している内容は非常に単純で、「指定されたファイルからランダムに文章を選び、標準出力に表示する」だけであるため、わざわざパッケージマネージャの世話にならずとも、シェルスクリプトで自分で書くことができる。以下のスクリプトを書いた。

btune.sh

#!/bin/bash
sed -n $(( $RANDOM % $( wc -l < $1 ) + 1 ))p $1

RAMDOM 変数やシェル展開数式を利用している為、bash 専用のスクリプトとなる。sed でランダムな1行を抽出している。

実行は以下のようにメッセージファイルを指定するだけだ。

$ ./btune.sh ~/.btune
機械エンジニアは兵器を作るが、その他のエンジニアはターゲットを作る。

これを /etc/profile.d や .bashrc に実行するよう記載しておけば、 fortune と変わらな挙動をする。

メッセージの追加も

$ cat >> ~/.btune
ざわ・・・ ざわ・・・
$

で済む。さらに、スクリプトファイルを置くのもイヤだという方は、\!* を駆使して alias 化しておくのもいい。また、/dev/random を上手く使えば、シェルに依存しないスクリプトが書けると思う。