![日記 日記](https://srad.jp/static/topics/journal_64.png)
mishimaの日記: ajaxterm より shellinabox
緊急時用の端末として ajaxterm を用意していたのだが、気がついたら最近の firefox ではちゃんと表示できないみたい。
ajaxterm は、固定のHTMLの中に AJAX で端末画面を埋め込むような動きになっていて、正常稼働の場合、DOMはこんな階層構造になるはず。
div id="term" 要素 ← 静的なHTML中に記載
div style="cursor: auto;" 要素 ← AJAX で挿入
pre class="term" 要素 ← AJAX で挿入
ところが、最近の firefox ではDOMの構造はこうなる。
div id="term" 要素 ← これは変更なし
div style="cursor: auto;" 要素 ← これも変更なし
div class="term" 要素 ← 階層が違うし、pre のはずが div になってる
HTML要素の挿入がミスってるぽい。JavaScriptは専門じゃないし、これを修正するのはめんどくせーなーと思ってしらべてたら ajaxterm と同じようなツールで shellinabox というのが最近の Debian に入ったらしい。
早速使ってみた。
…うわ、ちょうすごい!
うごきがいい!
しかも、ajaxterm みたいに、いじってないとすぐセッションが切断されちゃったりすることもない。
UTF-8 への対応もバッチリ。
こっちに乗り換えるぜ!
…と思ったのもつかの間、いくつかの記号が入力できないことに気がついた。「@」とか「:」とか。
ソフトウェアキーボードがあるにしても、これは常用するには辛い。
バグ報告にはイタリア語レイアウトのキーボードでも記号が入力できない事例が登録されていたので、たぶん日本語キーボードの問題だ。
こういうのは開発側で再現できないので、単にバグ報告を出しても修正されないことが多い。
もっと調べて見ることにする。
サーバ側で strace してみると、「ふつうの記号はキーを押すとサーバにリクエストが来る」
「入力されない記号の場合、キーを押してもサーバにリクエストがこない」ということが分かった。
ブラウザ側、JavaScript の実装に問題があるという事だ。
幸い firefox には開発者向けのデバッグ機能が載ってるので、そのまま JavaScript をデバッグする。
ちょっと調べた結果、次のようなことが分かった。
- keyDown, keyPress, keyUp あたりのイベントで面倒くさい処理をしている。
- 一文字のキーを押した時に、「keyDown/keyUp」の1組イベントが発生する場合と「keyPress」のイベント一つが発生する場合がある。どちらか一方だけが発生するはずだが、世の中のブラウザ実装では両方発生してしまうことも多いらしい。
- そのためshellinaboxでは「keyDownイベントでキー入力を処理した場合、keyPressイベントの処理は無視する」という実装をとっている。
- keyDownイベントは、通常のキー(ASCII文字=数字、アルファベット、記号など)以外に、シフトキー押下などでも発生する。そのため、keyDown時にこれを判定して、通常のキーの場合だけキー入力処理をおこなう。
- ところが、USキーボードでは、@ や : はシフトキーを押しながらでないと入力できないので、shellinaboxでは keyDown 時のチェック範囲から漏れている。
- そのため、JPキーボードでは、 - ^ @ : の4つのキーは「通常キーでもないけど特殊キーでもない」ものとして扱われてしまい、入力が無効になる
- シフトキーを押しながら - ^ @ : を入力した時に発生するはずの = ~ ` * も同様に入力が無効になる。
これに対して、次のようにパッチを作成した。
- apt-get source shellinabox でソースを取得し、 debuild でコンパイルできることを確認する。
- dch で適当に changelog を書く。
- dquilt new fix-keycode.patch でパッチを作成する。(dquiltはDebianのNew Mainteiner Guideを参照)
- dquilt add shellinabox/vt100.js
- vt100.jsを修正する。
add ascii keycode.
--- a/shellinabox/vt100.js
+++ b/shellinabox/vt100.js
@@ -2933,8 +2933,10 @@
// } 107
var asciiKey =
event.keyCode == 32 ||
- event.keyCode >= 48 && event.keyCode <= 57 ||
- event.keyCode >= 65 && event.keyCode <= 90;
+ event.keyCode == 160 ||
+ event.keyCode == 173 ||
+ event.keyCode >= 48 && event.keyCode <= 58 ||
+ event.keyCode >= 64 && event.keyCode <= 90;
var alphNumKey =
asciiKey ||
event.keyCode == 59 || - dquilt refresh
- dquilt header -e
- 再度 debuild で完成!
これで @ も * も入力できる。パスワード入力時に「なんでパスワード間違いになっちゃうんだろう」とか悩まなくても良くなるわけです。
ということで、みなさん安心して shellinabox に乗り換えればいいと思うよ!
ajaxterm より shellinabox More ログイン