ルーターにDD-WRTを入れました。WZR-HP-AG300Hに米Buffalo謹製のProfessional Firmwareです。ルーター自身でMyDNS.jpを更新させるただそれだけのために。
ちなみに無線LANは社外ファームでは法令に触れるので使ってはダメだとか。送信出力を10dBmにすると同等らしいですが、法律がそうなっているとかで。
さてMyDNS更新ですが、先人の知恵により、サービス名を手動設定にした上でURLに"/login.html?"と記述すれば通りました。
ところがRC_IP_CONNECT_FAILEDが発生してダメになる場合がありました。色々調べていくと、どうもWAN IPアドレスの確認に失敗した場合のエラーメッセージのようでした。
DDNSクライアントinadynはデフォルトでcheckip.dyndns.org使っていました。これはリモートホストのIPアドレスを表示するだけのサービスで、DDNS更新のために用意されている物のようです。DynDNS以外で使われるのは迷惑だろうになあ、と思わなくもありません。
一つのホスト名に複数のIPアドレスが割り当てられている(DNSラウンドロビンとか呼ぶらしい)のですが、inadynは立ち上がるとDNSを一度しか引かないため、落ちていても余所に回りません。こうして接続できない場合にRC_IP_CONNECT_FAILEDが記録されます。
inadynを更新すれば回避できるらしいですが、せっかく米Buffaloが動作確認してくれたバージョンからずらすのも嫌ですし、inadynだけ更新も怖いので、外から何とかすることにしました。
そもそもルーター自身がWAN IPアドレスを把握しているのに、わざわざ外のCGIに調べてもらうなんておかしいだルルォ!?
というわけで、設定画面のInfo.htmからPerlでWANのIPアドレスを取り出して表示するcgiを設置しました。Perlなんて自分で書くのは初めてですが、こんな感じ(後述)で良いのでしょうか。
後は、これをDDNS設定画面の追加オプションで
--ip_server_name サーバーのLAN IPアドレス cgiへの絶対パス
とすればWAN IPアドレスの確認に使ってくれます。詳細はDD-WRT公式のこちらを。
DD-WRTにPerlを入れてしまえば1台で完結できますが、今のところはこのWebサーバーに設置しています。ルーターで完結していませんが、WAN IP確認はローカルで行なわなければならないものでもないので、おまけです。
クラスCプライベートIPアドレスを判別して上記仕組みを動作させ、それ以外なら相手のリモートIPアドレスを表示します(つまりcheckip.dyndns.org等と同じ動作)。
#!/usr/bin/perl
use utf8;
use LWP::UserAgent;
use HTML::TreeBuilder;
print "Content-type: text/plain\n\n";
my $ip = $ENV{'REMOTE_ADDR'};
if ($ip =~ /^(192\.168)/) {
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => 'http://ルーターのLAN IPアドレス/Info.htm');
$req->authorization_basic('ユーザー', 'パスワード');
my $res = $ua->request($req);
if ($res->is_success) {
$tree = HTML::TreeBuilder->new;
$tree->parse($res->content);
$tree->eof();
my $ipaddr = $tree->look_down(_tag => "span", id => "wan_ipaddr")->as_text;
print $ipaddr, "\n";
} else {
print "ERROR.\n";
print $res->status_line, "\n";
}
} else {
print $ip, "\n";
}
プログラミングの最近のブログ記事
自動入力時に"@"から後が全角になる現象対策として、WshShellを使用した修正版をビルドしました。GPLなので修正ソースも添付。署名してありますが、用途が用途なので心配な方は使用しないでください。
KeePass223mod.zip
Windows Script Host Object Modelを使いますが、yamamotoWorks様の記事を参考にInteropのDLLが生成されないようにしています。
さすがに某所のようにセキュリティコードごとカード番号が漏れたらどうにもなりませんが、パスワード漏洩は対策しなきゃしなきゃと思っていたところでした。
あの巨大掲示板の●と呼ばれる有料サービスは購入していたことがあります。専門ジャンルの過去ログがどうしても見たくて。今ほど過去ログサイトがなかった頃の話です。
私の個人情報は漏洩していなかったようですが、仮にしていてもカードは何年も前に解約してありますし、メールも捨てアドレスにしていました。ヤクザな場所にはそれなりの用心を。
PlayStation Networkの大規模漏洩の時は、パスワードは使い回しのものではありませんでしたし、カードも登録していませんでした。
今のところ被害はニアミスで済んできましたが、もたもたしていたお陰でKeePassという良ソフトに出会えました。クラウドに依らずMac版KyPass CompanionやiOS版MiniKeePassとデータベースファイルを共有しています。
そういうわけでKeePassを導入し、メールを引っかき回してアカウントを調べ上げ、パスワードを作り直して変更したのでした。
さてこの変更、本家にかけ合うべきでしょうが、経緯の確認もしなくちゃですね。
KeePass223mod.zip
Windows Script Host Object Modelを使いますが、yamamotoWorks様の記事を参考にInteropのDLLが生成されないようにしています。
さすがに某所のようにセキュリティコードごとカード番号が漏れたらどうにもなりませんが、パスワード漏洩は対策しなきゃしなきゃと思っていたところでした。
あの巨大掲示板の●と呼ばれる有料サービスは購入していたことがあります。専門ジャンルの過去ログがどうしても見たくて。今ほど過去ログサイトがなかった頃の話です。
私の個人情報は漏洩していなかったようですが、仮にしていてもカードは何年も前に解約してありますし、メールも捨てアドレスにしていました。ヤクザな場所にはそれなりの用心を。
PlayStation Networkの大規模漏洩の時は、パスワードは使い回しのものではありませんでしたし、カードも登録していませんでした。
今のところ被害はニアミスで済んできましたが、もたもたしていたお陰でKeePassという良ソフトに出会えました。クラウドに依らずMac版KyPass CompanionやiOS版MiniKeePassとデータベースファイルを共有しています。
そういうわけでKeePassを導入し、メールを引っかき回してアカウントを調べ上げ、パスワードを作り直して変更したのでした。
さてこの変更、本家にかけ合うべきでしょうが、経緯の確認もしなくちゃですね。
Windows版KeePassでアカウント名などに"@"が含まれていると、つまりメールアドレスだったりすると、自動入力時に"@"でIMEがONにされ、以後全角になってしまいます。2.18以上で発生しているとか。
そもそもの発端は、SendInputでKEYEVENTF_UNICODEを指定すると、OSが気を利かせてIMEをONにすることのようです。未確認ですが内部でIMM経由だとか何とか(そのためIME依存?)。
KeePassのフォーラムでは当時、@に対してAlt+@が発行されるためにIMEがONになっているんだ、なんてことが書かれているのですが、全くそうは思えません。私の環境でAlt+@を押してもIMEはONになりませんが発生しています。
現実に最新2.23でも発生し続けていますし、Alt+@になっていたなら文字として"@"が入力されるはずがありません。
C#なのにKEYEVENTF_UNICODEなSendInputを使っている理由は、SendKeys.Sendが間違ったキーを発行する場合があるのを回避するためで、例えばキャレット(いわゆるべき乗記号"^")を送ろうとするとアンパサンド(アンド記号"&")になります。
言語或いはキーボード依存なのか、他にもあるのでしょう、きっと。それで8種類の文字を決め打ちでSendInput送りにしています。判別しているのはKeePass.Util.SendInputEx.OSSendKeysWindowsで、そこに2.18から"@"が追加されています。
簡単な回避法としてWshShellオブジェクトのSendKeysを使う手があるそうな。本気でやるにはVkKeyScanExとSendInputですが、元々KeePassはDirectInput対応などは考慮していないソフトですから、WshShellでいいのでしょう。
そもそもの発端は、SendInputでKEYEVENTF_UNICODEを指定すると、OSが気を利かせてIMEをONにすることのようです。未確認ですが内部でIMM経由だとか何とか(そのためIME依存?)。
KeePassのフォーラムでは当時、@に対してAlt+@が発行されるためにIMEがONになっているんだ、なんてことが書かれているのですが、全くそうは思えません。私の環境でAlt+@を押してもIMEはONになりませんが発生しています。
現実に最新2.23でも発生し続けていますし、Alt+@になっていたなら文字として"@"が入力されるはずがありません。
C#なのにKEYEVENTF_UNICODEなSendInputを使っている理由は、SendKeys.Sendが間違ったキーを発行する場合があるのを回避するためで、例えばキャレット(いわゆるべき乗記号"^")を送ろうとするとアンパサンド(アンド記号"&")になります。
言語或いはキーボード依存なのか、他にもあるのでしょう、きっと。それで8種類の文字を決め打ちでSendInput送りにしています。判別しているのはKeePass.Util.SendInputEx.OSSendKeysWindowsで、そこに2.18から"@"が追加されています。
簡単な回避法としてWshShellオブジェクトのSendKeysを使う手があるそうな。本気でやるにはVkKeyScanExとSendInputですが、元々KeePassはDirectInput対応などは考慮していないソフトですから、WshShellでいいのでしょう。
OleLoadPictureが失敗するWindowsビットマップ形式ファイルがありました。
Photoshop Elements 7で作成した16bpp/RGB565のもので、プレビューはできていますが、フリーソフトのGVでも失敗。
どうやらBITMAPINFOHEADERのbiSizeが間違っているためと判明。40でなく56になっていました。
BI_BITFIELDSのマスクはbiSizeに含まれませんから、これはバグでしょう。biSizeを40に修正すると、色も含めて正常に読み込むことができました。果たして最新はCS6とかCCとかはどうなのか。
そもそも16bppのカラーマスクはRGBの3つ分なので、56でなくせめて52だろうとか、他にもツッコミどころがありますが...。
Photoshop Elements 7で作成した16bpp/RGB565のもので、プレビューはできていますが、フリーソフトのGVでも失敗。
どうやらBITMAPINFOHEADERのbiSizeが間違っているためと判明。40でなく56になっていました。
BI_BITFIELDSのマスクはbiSizeに含まれませんから、これはバグでしょう。biSizeを40に修正すると、色も含めて正常に読み込むことができました。果たして最新はCS6とかCCとかはどうなのか。
そもそも16bppのカラーマスクはRGBの3つ分なので、56でなくせめて52だろうとか、他にもツッコミどころがありますが...。
バージョンの付け方が不揃いすぎるというのは置いておき。
DeltaEndの0.61を公開しました。通知領域から昨日の変更ができていなかった酷いバグの修正と、内部動作の改良。DLL開放でメッセージ専用ウィンドウを、列挙とWM_NULLのポストによる通常の方法で対処できるようになりました。
gnyaclockも2.0.2になりました。機能的にはGDI描画とGDI+描画の切り替えができるようになったぐらいですが、内部は別物です。PostScriptベースのOpenTypeフォントをGDI+で描画するためのQGraphicsText.dllが含まれています。
DeltaEndの0.61を公開しました。通知領域から昨日の変更ができていなかった酷いバグの修正と、内部動作の改良。DLL開放でメッセージ専用ウィンドウを、列挙とWM_NULLのポストによる通常の方法で対処できるようになりました。
gnyaclockも2.0.2になりました。機能的にはGDI描画とGDI+描画の切り替えができるようになったぐらいですが、内部は別物です。PostScriptベースのOpenTypeフォントをGDI+で描画するためのQGraphicsText.dllが含まれています。
リスタートマーカーがどの程度実用になっているかと試してみました。
0FFDxhの下位3ビットが番号を表してRST0~RST7の8種類ですから、7連続で破損しても回復できるはずです。つまり例えばRST2の次が同じRST2の場合。
8連続以上を判別できないのは桁数の問題ですからどうにもなりません。MPEG-2 TSのcontinuity_counter(4ビット)も16連続以上は無理です。
そのJPEGですが、3連続の破損でずれました。ずれるつまり想定されるMCUの位置に進めなかったことを意味します。
私の実装だと回復できるのですが...IJGの実装のようですね。djpeg.exeでも確認しました。WindowsプレビューやFirefox等々。
jdmarker.cのjpeg_resync_to_restart()の中で再同期を処理していて、なるほど確かに2連続までしか復帰処理をしないようです。
そんなに派手に吹っ飛んだら表示し続けることの意味も薄いでしょうが、なぜ制限しているのでしょうね。
0FFDxhの下位3ビットが番号を表してRST0~RST7の8種類ですから、7連続で破損しても回復できるはずです。つまり例えばRST2の次が同じRST2の場合。
8連続以上を判別できないのは桁数の問題ですからどうにもなりません。MPEG-2 TSのcontinuity_counter(4ビット)も16連続以上は無理です。
そのJPEGですが、3連続の破損でずれました。ずれるつまり想定されるMCUの位置に進めなかったことを意味します。
私の実装だと回復できるのですが...IJGの実装のようですね。djpeg.exeでも確認しました。WindowsプレビューやFirefox等々。
jdmarker.cのjpeg_resync_to_restart()の中で再同期を処理していて、なるほど確かに2連続までしか復帰処理をしないようです。
そんなに派手に吹っ飛んだら表示し続けることの意味も薄いでしょうが、なぜ制限しているのでしょうね。
今の仕事に関係あるものの要求仕様にないところで、JPEG(ベースラインのみ)の実装をしてみました。
JPEG...夢でした。学生時代、まあ躁の気の迷いですから結局手つかずでしたが、「わかりやすいJPEG・MPEG2の実現法」なんて本を買ったりもしました。
ホストから短いパケット単位で送られてくるデータをその都度展開するという、能動的に読みに行く通常の動作と逆のものです。
マルチスレッドや割り込み優先度の差によって、データが必要サイズ揃うまで受信コールバックをブロックすればlibjpegの動作すら可能でしょうが、ちょっと作ってみたのです。必要RAMは3KB弱となりました。
以前Zlib展開の実装をしたことがありハフマン符号の理解があったこと、難関である逆離散コサイン変換に既存の(ライセンス的にOKな)関数を使ったことから、1週間程度で実用レベルのものができてしまいました。
ちなみに量子化テーブルやハフマンテーブルが一つのマーカーになっているもの、Y/C、DC/ACそれぞれ別々のマーカーになっているもの、と個性があるようでした。YCrCb 4:2:2のサンプルはImageMagickで作りましたが、出力できるソフトはあるのでしょうかね。
わかってしまえば至ってシンプルだなあ、というのが感想です。「非可逆」という割り切り、劇的な圧縮率。20年を越えて現役であり続けるのは凄いものです。
(追記2013/7/24)
YCrCb 4:2:2対応ソフトは少なくないようですが、GIFアニメ大学校様のこちらによると、Paint Shop Pro 8が色々設定できたようです。最新X5は不明ですが、さすがに4x2:2x2:2x2みたいなのは異常と言わざるを得ないような...。
JPEG...夢でした。学生時代、まあ躁の気の迷いですから結局手つかずでしたが、「わかりやすいJPEG・MPEG2の実現法」なんて本を買ったりもしました。
ホストから短いパケット単位で送られてくるデータをその都度展開するという、能動的に読みに行く通常の動作と逆のものです。
マルチスレッドや割り込み優先度の差によって、データが必要サイズ揃うまで受信コールバックをブロックすればlibjpegの動作すら可能でしょうが、ちょっと作ってみたのです。必要RAMは3KB弱となりました。
以前Zlib展開の実装をしたことがありハフマン符号の理解があったこと、難関である逆離散コサイン変換に既存の(ライセンス的にOKな)関数を使ったことから、1週間程度で実用レベルのものができてしまいました。
ちなみに量子化テーブルやハフマンテーブルが一つのマーカーになっているもの、Y/C、DC/ACそれぞれ別々のマーカーになっているもの、と個性があるようでした。YCrCb 4:2:2のサンプルはImageMagickで作りましたが、出力できるソフトはあるのでしょうかね。
わかってしまえば至ってシンプルだなあ、というのが感想です。「非可逆」という割り切り、劇的な圧縮率。20年を越えて現役であり続けるのは凄いものです。
(追記2013/7/24)
YCrCb 4:2:2対応ソフトは少なくないようですが、GIFアニメ大学校様のこちらによると、Paint Shop Pro 8が色々設定できたようです。最新X5は不明ですが、さすがに4x2:2x2:2x2みたいなのは異常と言わざるを得ないような...。
勤務先でTortoiseSVNの1.5系が使われているのですが、最終バージョン1.5.10に対し言語パックは1.5.9のままです。インストールしても選択できません。
英語で困るUIでもありませんが、言語パックのDLLのバージョンを本体と同じに書き換えたところ、選択できるようになりました。以下の4ファイルですが、チェックしているのは全てではないかもしれません。
さて、64ビット版Windowsでは64ビット版TortoiseSVNでないと、Explorerの右クリックメニューに出てきませんが、リリースされているのは1.6系以降のみです。
1.6系でもクライアントとしては問題ありませんが、リポジトリを1.5互換で作ることができません。
1.5系のコマンドライン版svnを使うか、1.6以降の場合だと以下の操作で作ることができました。
svnadmin create --fs-type fsfs --pre-1.6-compatible <path>
英語で困るUIでもありませんが、言語パックのDLLのバージョンを本体と同じに書き換えたところ、選択できるようになりました。以下の4ファイルですが、チェックしているのは全てではないかもしれません。
- TortoiseBlame1041.dll
- TortoiseIDiff1041.dll
- TortoiseMerge1041.dll
- TortoiseProc1041.dll
さて、64ビット版Windowsでは64ビット版TortoiseSVNでないと、Explorerの右クリックメニューに出てきませんが、リリースされているのは1.6系以降のみです。
1.6系でもクライアントとしては問題ありませんが、リポジトリを1.5互換で作ることができません。
1.5系のコマンドライン版svnを使うか、1.6以降の場合だと以下の操作で作ることができました。
svnadmin create --fs-type fsfs --pre-1.6-compatible <path>
前回接続時に無効に設定したデバイスが接続されると、DBT_DEVNODES_CHANGED以外は何も来ないようです。
DBT_DEVICEARRIVALは発行できませんし、いきなりDBT_DEVICEREMOVECOMPLETEというのも不自然ですから、仕方ないのでしょうが。
というわけで、列挙してVendorIDやDeviceID/ProductIDで絞って、CM_Get_DevNode_StatusのpulProblemNumberがCM_PROB_DISABLEDになっているのを見つけたら、という地道な作業をするしかないようです。
DBT_DEVICEARRIVALは発行できませんし、いきなりDBT_DEVICEREMOVECOMPLETEというのも不自然ですから、仕方ないのでしょうが。
というわけで、列挙してVendorIDやDeviceID/ProductIDで絞って、CM_Get_DevNode_StatusのpulProblemNumberがCM_PROB_DISABLEDになっているのを見つけたら、という地道な作業をするしかないようです。
iPhoneが普及させた「バッジ」というものがあります。ホーム画面のアイコン上に赤丸の数字を重ねるものです。Mac OS XでもLionからサポートされました。
よくできていまして、桁数が増えると横長になって4桁まで表示可能。欠点は自然数以外を一切受け付けないことで、プラスもマイナスもゼロもダメです。
最近は気温の表示など、0以下になり得るアプリが出ていまして、改善を望みたいところです。実は文字の表示ができる非公開APIもあるのですが...。
さて一方のWindowsはというと、Windows 7でタスクバーにオーバーレイアイコンを表示できるようになりました。
こちらは"!"や"?"等、アイコンなら何でも表示できます。欠点は、逆に文字や数字を簡単に表示する方法がなく、大きさも16×16に固定されていることです。
大きさが固定なのが痛いですが、アルファチャンネル付きのアイコンを生成する方法が公開されているので、これを使ってバッジ的に使うサンプルを作ってみました。
SetOverlayIcon.zip
位置合わせは一桁の数字で行なったので、"W"のような大柄な文字ははみ出気味です。日本語も受け付けますが同様。
一応、2文字以上も縮小しますが、何しろ16x16の赤丸のさらに内側ですから、数字でも2桁が判読できる限界だと思います。
文字数を節約するため、先頭の"-"は特別に処理するので、負の数も1文字扱いから始まります。
また正負記号を右上に重ねることで、例えば"9+"とすれば、数字そのものは1桁だけで「10以上」を知らせることができます。
内部の描画にGDI+を使っており、フォントはFranklin Gothicです。主に"1"の配置が綺麗という理由によります。Arialは何だかバランスが悪くなりました。
バッジの他に進捗表示と点滅の機能があります。点滅はFlashWindowExなのでVista以下でも使えます。
余談ですが高さ16で幅16以上のアイコンをオーバーレイさせたところ、見事に横を縮小されました。
よくできていまして、桁数が増えると横長になって4桁まで表示可能。欠点は自然数以外を一切受け付けないことで、プラスもマイナスもゼロもダメです。
最近は気温の表示など、0以下になり得るアプリが出ていまして、改善を望みたいところです。実は文字の表示ができる非公開APIもあるのですが...。
さて一方のWindowsはというと、Windows 7でタスクバーにオーバーレイアイコンを表示できるようになりました。
こちらは"!"や"?"等、アイコンなら何でも表示できます。欠点は、逆に文字や数字を簡単に表示する方法がなく、大きさも16×16に固定されていることです。
大きさが固定なのが痛いですが、アルファチャンネル付きのアイコンを生成する方法が公開されているので、これを使ってバッジ的に使うサンプルを作ってみました。
SetOverlayIcon.zip
位置合わせは一桁の数字で行なったので、"W"のような大柄な文字ははみ出気味です。日本語も受け付けますが同様。
一応、2文字以上も縮小しますが、何しろ16x16の赤丸のさらに内側ですから、数字でも2桁が判読できる限界だと思います。
文字数を節約するため、先頭の"-"は特別に処理するので、負の数も1文字扱いから始まります。
また正負記号を右上に重ねることで、例えば"9+"とすれば、数字そのものは1桁だけで「10以上」を知らせることができます。
内部の描画にGDI+を使っており、フォントはFranklin Gothicです。主に"1"の配置が綺麗という理由によります。Arialは何だかバランスが悪くなりました。
バッジの他に進捗表示と点滅の機能があります。点滅はFlashWindowExなのでVista以下でも使えます。
余談ですが高さ16で幅16以上のアイコンをオーバーレイさせたところ、見事に横を縮小されました。