読者です 読者をやめる 読者になる 読者になる

pixplus 1.15.2

pixplus (git / github)

Operaのみ対象のバグ修正. 前回更新したときにコメントにきてたやつの修正. Opera本体のバグと思われるけど, pixplus側で対応可能だったのでスタイルの処理を変えることで対応した.

変更点

  • [修正][Opera12] Opera12で矢印ボタンの動作がおかしかったのを修正.

pixplus 1.15.1

pixplus (git / github)

バグ修正のみ.

重大な問題が発生しないので放っておいたら一年もたってしまったため, 最新バージョンの日付を新しくするために更新することにした.

safariextzを作るために証明書を発行しようとしたらApple Developer Programに1ユキチを要求されたため, 今回からSafariサポートを落とした. Safari Extensionのアップデートは提供できないが, グリモン版の問い合わせは受け付ける所存である. 前述の通り, 旧バージョンでも致命的な問題はないはずなので, そのまま使っても差し支えない.

変更点

  • [修正] マンガページ内で設定ダイアログのレイアウトが壊れていた不具合を修正.
  • [修正] 「pixivコミックアイコンを除去する」オプションが機能しなくなっていた不具合を修正.

Buffalo ルータのファームウェアアップデータを分解する

WZR-HP-G450Hファムウェアアップデータを分解する手順を調べたのでメモ.

使用ツール

buffalo-enc

$ cd
$ git clone git://git.openwrt.org/openwrt.git --depth 1
$ cd openwrt/tools/firmware-utils/src
$ gcc -o ~/buffalo-enc buffalo-enc.c buffalo-lib.c

unsquashfs-lzma

$ cd
$ git clone https://github.com/mirror/firmware-mod-kit.git --depth 1
$ cd firmware-mod-kit/src/others/squashfs-4.0-lzma
$ make
$ cp unsquashfs-lzma ~

分解する

$ cd
$ unzip -x wzrhpg450h-188.exe
$ cd wzrhpg450h-188
$ grep -abo start wzr_hp_g450h_jp_188
20:start
208:start
$ tail -c+209 < wzr_hp_g450h_jp_188 > b1.bin
$ ~/buffalo-enc -d -i b1.bin -o b2.bin
Magic           : 'start'
Seed            : 0xec
Product         : 'WZR-HP-G450H'
Version         : '1.88'
Data len        : 21651456
Checksum        : 0x20bd9f5c
$ binwalk b2.bin

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             uImage header, header size: 64 bytes, header CRC: 0x5AF62ABA, created: Thu Jan 21 17:59:24 2016, image size: 21651392 bytes, Data Address: 0x80002000, Entry Point: 0x8020A9F0, data CRC: 0x95476FBA, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: lzma, image name: "Linux Rootfs Combined Image"
64            0x40            LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 2873876 bytes
1048576       0x100000        Squashfs filesystem, little endian, version 4.0, compression:lzma, size: 20599552 bytes,  4063 inodes, blocksize: 131072 bytes, created: Thu Jan 21 17:59:22 2016

$ tail -c+1048577 < b2.bin > b3.bin
$ ~/unsquashfs-lzma b3.bin

所感

重要なバイナリの多くが /bin/busybox/bin/rc へのシンボリックリンクになっている. GPL に感染しているコードは http://opensource.buffalo.jp/gpl_wireless.html で公開されていて, /bin/busybox もこれに含まれているが, プラットフォーム固有の機能, 特に /www/cgi-bin/* の実体である /bin/rc は含まれていないようだ.

例えば /etc 下のいくつかのファイルは /tmp 下へのシンボリックリンクになっていて, 推測であるが, /bin/rc 内にコードされているデータをシステム起動時にそこへ書き出す仕様になっているようだ.

今回, この簡単な調査を行った動機としてファームウェアバージョン 1.88 において一部界隈で有名な bufpy アカウントにアクセスできなくなった問題があり, パスワードが変更されただけなら調べられるだろうと思ったのだが, どうやら /bin/rc にハードコードされていた bufpy アカウントの設定がまるごと削除されたらしく, どうにもならないことがわかった.

なおファームウェアは通常のアップデートと同じ手順で旧バージョンを食わせればダウングレード可能だが, 設定が吹き飛ぶので注意されたい.

Gentoo で Portage と Entropy を混ぜて運用する

目的

Chromium などビルドにたいへん時間がかかるものを emerge するのはしんどいので, そういうものだけ Sabayon のバイナリパッケージを導入したい.

Entropy の導入

参考文献: HOWTO: Install from an existing Linux system

Sabayon Wiki の説明にはやや問題があって, このままやると上手くいかない. まず equoPortage にあるので layman を使わなくていいとあるが, 2016年3月現在 Portage にある equo-254, entropy-254 は上手く動かない(equo rescue generate が終わらない)ので, sabayon オーバーレイから入れる必要がある.

# emerge layman
# layman -a sabayon
# layman -a sabayon-distro
# emerge equo
# equo rescue generate

sabayon-distro は当初は必要ないが, あとで必要になるので入れておく. equo でパッケージをインストールすると, おおむね gentoo リポジトリから入れたことになる(equery l '*::gentoo' で出る)のだが, 一部は sabayon ないし sabayon-distro リポジトリになるため, sabayon-distro オーバーレイを追加していないと, equo で入れたものを Portage で mask しても emerge -ugentoo リポジトリのものにダウングレードしようとする.

また, equo にバグ(Bug 4858)があって, equo rescue generate はおそらく失敗する. コマンド実行後に /var/lib/entropy/client/database/amd64/equo.db が存在すれば上手くいっているのだが, 作られていない場合, Sabayon の ISO から equo.db を持ってきて(.iso をマウントしてファイルサイズが大きいやつを mount -t squashfs する) equo rescue generate し直すとよい.

# cp /etc/entropy/repositories.conf.d/entropy_sabayonlinux.org{.example,}
# equo update
# equo repo mirrorsort sabayonlinux.org
# equo rescue spmsync

一部のパッケージのみ Entropy でインストールする

このまま equo upgrade してしまえば Gentoo Linux は Sabayon Linux にコンバートされるわけだが, Sabayon を使うくらいなら Arch でいいじゃん, という向きもあり, この記事ではとりあえず Chromium のみ Entropy で管理することを目指す.

そのためには, Entropy ですべて mask しておいて Chromium のみ unmask したいのだが, Entropy は残念ながら package.maskワイルドカードを(部分的にしか)サポートしておらず, また, unmask より mask のほうが優先度が高いため, package.mask* と書いて package.unmaskwww-client/chromium と書くような運用はできない. そこでしょうがないので Entropy にパッチを当てる.

Entropyですべてマスクする

こいつを /etc/portage/patches/sys-apps/entropy/ に置く. このパッチをあてておくと, equo update の後に equoリポジトリ側の packages.db.mask* を追加してくれる. これで自動的にすべてのパッケージが mask されるが, /etc/entropy/packages/package.unmask はもちろんこれより優先度が高いので, 一部だけ unmask するという運用ができるようになる.

# emerge entropy
# equo update --force

equo upgrade -av して何もアップグレードされなければ成功である.

Chromium だけ Entropy でインストールする場合

Portage::sabayon, ::sabayon-distro, www-client/chromium::gentoo を mask して Entropy で www-client/chromium を unmask すると, emerge -uChromium は無視されて equo upgradeChromium だけがアップグレードされる.

# >> /etc/portage/package.mask <<EOF
*/*::sabayon
*/*::sabayon-distro
www-client/chromium::gentoo
EOF
# >> /etc/portage/package.unmask <<EOF
sys-apps/entropy::sabayon
app-admin/equo::sabayon
EOF
# >> /etc/entropy/packages/package.unmask <<EOF
www-client/chromium
EOF

emerge したら自動的に equo rescue spmsync する

Entropy は Portage でインストールされたパッケージのリストを持っていて, emerge したら equo rescue spmsync で更新することが望ましい. これを自動化する.

# cat >> /etc/portage/bashrc
post_pkg_postinst() {
  if test "$AMANDA_SERVER_TAPE" != sabayon; then
    equo rescue spmsync
  fi
}

equoPortage を呼び出してパッケージをインストールさせるため, post_pkg_postinst() で無条件に equo rescue spmsync すると, equo から post_pkg_postinst() が呼ばれて equo が実行され, デッドロックに陥る. これを回避するため, post_pkg_postinst()equo から呼ばれていないか判断しなければならないが, env してみたところ AMANDA_SERVER_TAPE 環境変数が使えそうだったので, 上のコードではとりあえずこれを使っている. ロックファイルなど, もっと適切なものがあるかもしれない.

書きためたパッチのまとめ

書いたパッチがたまっているので, ここにまとめておく.

avfs

gistaecf835f94404da8842b

avfs で zip 内のファイル名の文字コードを変換する. CP932=>UTF-8 決め打ち. 読むほうしか書いてないので書き込みはたぶん上手くいかない.

gist272347ff4ac44d088a8d

avfs で rar の unicode なファイル名に対応する. ヘッダにも書いたが, デコード部分は unrarsrc からコピペしている. avfs は GPLv2 で, unrarsrc は acknow.txt によれば GPL で配布できるとあるので, このパッチのライセンスは GPLv2 とした.

gist57bbcb68a7a4aaef3d00

avfs は rar 内のファイルリストを作る処理は自前で実装しているが, 格納されているファイルを読む処理は rar ないし unrar コマンドを叩いてパイプで読んでいる. Gentoo に入っている avfs-1.0.1 ではリードオンリーで open() したファイルディスクリプタを stderr に貼り付けているせいで unrar が SEGV って read() が失敗するバグがあって, それを直すパッチ.

pam_encfs

gistc64565058669b9148415

EncFS という FUSE の暗号化ファイルシステムがあって, こいつをログイン時にマウントする PAM プラグインpam_encfs というのがあるのだが, ユーザにつき一個しかマウントできない問題があって(バグではなく実装がしょぼい), それをなんとかするパッチ. とりあえず最大 10 個にした. 増やしたり N 個対応は簡単にできる.

wxMaxima

gist03e7a72ff93cee44d507

やはり Emacs で imaxima より wxMaxima のほうが使い勝手が良いので, wxMaxima でキーバインドを適当にいじるやつ. このパッチのキーバインドEmacs 風ではなく我流である.

Firefox の Chrome Code から任意のドメインに対してクッキーを許可する

概要

about:permissions や Page Info dialog では任意のドメインに対してパーミッションを操作できないので, 任意のドメインに対してパーミッションの設定をしたい. これだけのためにアドオンを入れたくないので自作する.

やり方

let uri = makeURI('http://example.com/');
SitePermissions.set(uri, 'cookie', 1);

などとやる. uri

let uri = window.content.document.documentURIObject.clone();
uri.host = 'hoge';

としてもよい. document.documentURIObject はリードオンリーである. uri に対して設定変更できるかどうかは SitePermissions.isSupportedURI(uri) でチェックする. 例えば about:about では false になる. SitePermissions.set() の第二引数は SitePermissions.listPermissions() で得られる. 'plugins'permissions.js にハードコードされている. 第三引数の選択肢は SitePermissions.getAvailableStates('partid') で取得する. 選択肢のタイトルは SitePermissions.getStateLabel('partid', state) する.

参考文献

  • browser/base/content/pageinfo/pageInfo.js
  • browser/base/content/pageinfo/permissions.js

sympy で遊ぶ

目的

とりあえず動かす, というところまでの how to な記事が少なくいろいろ苦労したので, そのあたりのことを書いておきたい.

スクリプトから API 叩くというだけなら sympy 入れたら良いだけなのだが, インタラクティブな UI で遊ぶことを目指す.

概要

ipython notebook するとウェブサーバが上がってデフォルトブラウザでそいつを開くので, ここで sympy を使って微分方程式解いたり plot() したりする.

導入

Gentoo

# emerge numpy scipy sympy ipython jinja www-servers/tornado jsonschema

jinja やら tornado やらは ipython notebook に必要なのだが, 依存関係に入ってないので, 手動で入れる必要がある. なにか他にも必要かもしれない.

Homebrew

$ brew tap homebrew/science
$ brew tap homebrew/python
$ brew install numpy
$ brew install scipy
$ pip3 install sympy
$ pip3 install ipython
$ pip3 install notebook
$ pip3 install matplotlib

pip の場合 notebookipython と別になってるので, notebook に必要なものは一通り勝手に入るらしい.

起動

$ ipython3 notebook

とすると

f:id:crckyl:20151110210239p:plain

こういうのが起動するので, Notebook を新規作成する.

Pretty print

数式を表示するときに, 裏で latex を叩いて綺麗に表示してくれる機能がある. ぐぐる%load_ext ... なるコマンドを入れたら良いとの記述が見つかるが, この方法は古いらしい.

init_printing()

とすると綺麗になる.

f:id:crckyl:20151110210837p:plain

from sympy import *
init_printing()
t,m,k=symbols('t m k')
x=Function('x')
eq=Eq(m*x(t).diff(t,2),-k*x(t))
eq

おなじみのバネです.

微分方程式を解く

f:id:crckyl:20151110211311p:plain

classify_ode(eq)
x2=dsolve(eq)
x2

解けないときは classify_ode()() になる. 偏微分方程式classify_pde(), pdsolve(). Equality オブジェクトでなく式でも良い. その場合 =0 ということになるらしい.

プロットする

f:id:crckyl:20151110211629p:plain

x3=x2.subs(zip(symbols('C1 C2 k m'),(1,1,1,1)))
x3=x3.simplify()
x3
%matplotlib inline
plot(x3.rhs)

%matplotlib inline するとインラインに表示してくれる. pyglet かなにかが入ってると別ウィンドウで出してくる. 入ってないと何も出ない.

フーリエ級数展開

f:id:crckyl:20151111193256p:plain

from sympy.mpmath import *
r=[-2,2]
f=lambda x:1 if -1<x<1 else 0
def g(n):
    cs=fourier(f, r, n)
    return lambda x: fourierval(cs, r, x)
plot([f,g(1),g(3),g(10),g(50)],r)

どうやらこれは数値計算になるのかな.

f:id:crckyl:20151111200500p:plain

def fourier_series(f, arg, range_, N):
  T = range_[1] - range_[0]
  a, b = [], []
  for k in range(N):
    a_k = 2/T*integrate(f*cos(2*pi*(k+1)/T*arg), [arg] + range_)
    b_k = 2/T*integrate(f*sin(2*pi*(k+1)/T*arg), [arg] + range_)
    a.append(a_k)
    b.append(b_k)
    pass
  a_0=integrate(f, [arg] + range_)/T
  return a_0 + sum([a_k*cos(2*pi*(k+1)/T*arg) + b_k*sin(2*pi*(k+1)/T*arg)
                     for k, (a_k, b_k) in enumerate(zip(a, b))])

t = symbols('t')
f = Piecewise((0, t<-1), (0, t>1), (1, True))
g = lambda n: fourier_series(f, t, [-2, 2], n)
plot(*[g(n*2+1) for n in (1,2,5,20)],xlim=(-2,2))

というわけで手書き.

交流 RC 回路

f:id:crckyl:20151111224855p:plain

うまく解けない.