2014/07/19

charは「ちゃー」だと思う

いくつかの事例を考える。
bin=「ビン」、proc=「プロック」、spec=「スペック」などを見てみると、短縮された場合は必ずしも元の語の発音に忠実に読む必要はないことがわかる。
元の発音を気にするならば、上の例はそれぞれ「バイン」「プロシ」「スピーシ」のように読まれるはずである。
よって、同様に考えてchar=「チャー」≠「キャラ」であると思われる。

ちなみにenum今まで脳内では「イーナム」と読んでいたが、よく考えると「{イ,エ}{ナ,ヌ}ム」のように読まれるはずである。
音節を区切ってe-numのように読めば合理性は説明できなくもない気はするが、4文字と短い略語でこのように音節を切るのは適切なのだろうか。
それはともかく「エニューム」はやはりおかしいと思った。

2014/07/13

squid,dnsmasq,openresolv on gentooで幸せになろう

wpa_supplicantで無線を使っているが、ネットワークを切り替えるとsquidが動かなくなる。
squidを通さなければ普通にネットワークが使えるので、どうも名前解決あたりで駄目になっているのではないかと考えたが、結果的に正解だった。
squidは内部に独自の名前解決の仕組みを持っているらしく、せっかくopenresolvとdnsmasqでローカルに正しく変更の反映されるDNSを持っているのに、それを利用してくれない(「dns_nameservers 127.0.0.1」しているにも関わらず、である)。
この挙動はsquidのconfigureオプションで「--disable-internal-dns」を指定することで変更でき、外部のDNSを使わせられるらしい。
ここでgentooの強みが生きる。

configureのオプションは普通ebuild内で指定されるが、configureスクリプトがautotoolsによるものの場合に限り、EXTRA_ECONF環境変数をオプションとして渡してくれるらしい(詳しくはManpage of EBUILD の"Compile"のところのebuildの説明を参照のこと)。
そんなわけで、merge時に「ECONF="--disable-internal-dns"」を指定できれば良いわけだが、ここでいつぞやの「jdkのヘッダにパスが通ってなくてemergeが失敗した話。」のケースを思い出す。
このときも環境変数(C_INCLUDE_PATH)を弄ろうという話だった。つまり、/etc/portage/package.envあたりを弄ってやれば良いだろう。

/etc/portage/package.env (追記)
net-proxy/squid squid-disable-internal-dns
/etc/portage/env/squid-disable-internal-dns (新規作成)
EXTRA_CONF="--disable-internal-dns"

んで、あとはsquidをmergeしなおしてやれば完了。
幸せだ。

2014/05/02

東工大ポータルとtitech-pubnetのログイン自動化のスクリプト(とブックマークレット)書いた

新規性あります!

ブックマークレットを利用するには、 東工大script ←このリンクをブックマークに登録し、その後、urlの最後らへんにある「14X99999」「password1234」「111……777」の箇所を自分のアカウントやパスワードに合わせて変えてください。
または、
javascript:(function(d,n,j,i,p,m){var l=d.login,f=d.getElementsByTagName('input'),t,c;switch(n.search.replace(/[&?]Template=([^&]*)(&.*)?/,'$1')){case 'userpass_key':l.usr_name.value=i;l.usr_password.value=p;l.submit();break;case 'idg_key':while(++j-4){t=f.item(j);c=t.parentNode.parentNode.getElementsByTagName('th')[0].innerHTML;t.value=m[c.match(/[1-7]/)[0].charCodeAt(0)-'1'.charCodeAt(0)].charAt(c.match(/[A-J]/)[0].charCodeAt(0)-'A'.charCodeAt(0));}l.submit();break;default:if(n.host+n.pathname=='wlanauth.noc.titech.ac.jp/fs/customwebauth/login.html'){d.getElementById('username').value=i;d.getElementById('password').value=p;submitAction();}else{n.href='http://portal.titech.ac.jp/';}}})(document,location,0,'14X99999','password1234',['1111111111','2222222222','3333333333','4444444444','5555555555','6666666666','7777777777']); これを一度テキストエディタなどにコピーして、編集後に手動でブックマーク登録するのもアリです。
(ちなみに、上の枠内では折り返しして表示されてると思いますが、改行はありませんので気にせずそのままコピペしてください。)



言うまでもないとは思いますが、たとえば「333…3」は学生証ウラの表の3行目のアルファベットを続けて10文字(AからJ列まで)入れてください。
ワンクリックで使える場所(ツールバーとか)に置いとくのが便利です。

gistの方にも書いときましたが、このブックマークレットは、

  • titech-pubnetのログイン画面でクリックすると自動入力+自動送信
  • 「同意(マトリクス認証)」をクリックした直後のページでクリックすると、自動入力+自動送信
  • その後の「Matrix Authentication」のページでクリックすると、適切に自動入力+自動送信でログイン完了
  • これら以外の普通のページからこのブックマークをクリックすると東工大ポータルのページにジャンプ
といった挙動をします。
要は普通のブックマークとしても使えて、ログインページではワンクリックで次のページに進める便利なスクリプトです。

詳しい解説はしませんが、安全性が心配なら gist にコメント付きのソース置いとくので各自確認するといいと思います。

ちなみに、Firefoxには Greasemonkey という、自作スクリプトを任意のwebページ上で動かせるアドオンがありまして、それを使えばクリック無しで自動ログインできます。
Firefoxユーザは是非そっちを使ってください。楽なので。

gist にアクセスして、titech-automatrix.user.jsの横にある「<>」みたいなボタンをクリックすると自動でインストール画面が出るはずです。

警告のある通りスクリプトで何でもできてしまうので、信頼したいならソース読んでください。

Google Chromeだとuser scriptを自作の拡張機能として使えるようですが、スクリプト読み込みのタイミングのせいか正常に動作しません。
(詳しく言うと、パスワード認証の段階でd.login.usr_nameが未定義だと言われます。たぶんDOMが構築される前にスクリプトが実行されてるとかじゃないかな。)
気が向いたら適当に対応するんでそれまで待つか、待てないなら誰か適当に改造しちゃってください。
利益取らなければ勝手に公開して構いませんので。

あと他になんか問題あったら連絡ください。

参考:新規性

  • ブックマークレット版は、ワンクリックで入力のみならず送信までできます
  • Greasemonkey版が用意されており、ノークリックで全自動ログインできます
  • パスワード認証にも対応しています。共通のブックマークレット(も、Greasemonkey用スクリプトも)ひとつでtitech-pubnetとtitech-portalの2つのサイトでのログインができます
  • 関係ないページでクリックした場合、普通のブックマークとして機能し、titech-portalにジャンプします(webページでなくブラウザ用の画面(新規タブとかアドオン管理とか)からは無理でしたが)。つまり普段からブックマークバーに置いておくだけの利用価値があります

2014/03/03

ターミナルでバイナリを表示して文字が化けることあるよね

ありませんか?そうですか。
僕は昔 $ sudo cat /proc/kcore とかやって残念なことになったり、最近だとうっかりvimの.swpファイルやgccの中間オブジェクトをcatしてしまったり。
まあ、そんなときtmux使いの僕は容赦なくペインを落として仕切り直すのですが、前の出力をまだ捨てたくない、表示を復活させたいときどうするか。

こうする。

選択1
$ echo ^O
もちろん^Oは「C-v C-o」です。
選択2
$ echo ^[c
もちろん^[は「C-v Esc」です。念のため。
選択3
$ setterm -default
今回調べて初めて知った。
まあ実際どれがベターなのかは知りません。ちなみに $ hoge | od -t x1 してみるとわかりますが、全部出力するバイナリが(僕の環境では)違います。謎。
ちなみにわざわざバイナリファイルを探さずとも $ echo ^N で化けさせられます(追記:tmux上でしか化けなかった。なんだろう)。お試しあれ。

追記:

なんかtputコマンドを使うやり方があった気がするんだけどなぁ……「tput reset」じゃうまくいかなかったし。
他のやり方知ってたら教えて偉い人。

2013/09/05

不動点コンビネータの作り方(λ抽象)

「λ抽象」とわざわざ付けたのは、SKIコンビネータとかでも不動点コンビネータは作れるよなあ、などとしょうがないことを考えただけであって、 λ抽象の方がだいぶ簡単に作れるとはいえどちらも本質的には同じものであるから、とりあえず簡単な方だけ紹介しようという目論見である。
SKIコンビネータで作りたいなら自動生成するなりプロの技で作るなりすればいいと思う。

基本方針

不動点コンビネータとは、
Fg -> g(Fg) となるようなλ抽象Fのことである。
後述するが、これによってλ計算で再帰を記述できるようになる。
(ちなみに、コンビネータとは自由変数を含まないλ抽象のこと……だと思う)

さて、簡約後の式にF自体が含まれているということは、Fは何か断片から全体を再生できる構造になっている必要がある。
より正確には、「コピーや再生、適用を担当する式」と「適用される側の式」の2段構えになっていて、かつ前者と後者はどちらか一方から再現できるのが良い。
まあ最初に思いつくのは前者と後者が全く同じ場合だし、他にクールな方法も思いつかないので、ここではその戦略でいく。
以下では、その断片をfとし、fを代入される予定の束縛変数をcとしよう。

Fg -> ffg

「繰り返し」の最も単純なパターン。まあ発想の単純さと完成したコンビネータの単純さに相関があるかは知らないが。

Fg -> ffg -> g(Fg) -> g(ffg) fab -> b(aab) より f = (λa.(λb.b(aab))) よって F = (λc.cc)(λa.(λb.b(aab)))

Fg -> fgf

これはちょっとひねくれている。とはいえ、することは上と同じだ。

Fg -> fgf -> g(Fg) -> g(fgf) fab -> a(bab) より f = (λa.(λb.a(bab))) よって F = (λc.(λg.cgc))(λa.(λb.a(bab)))

Fg -> fg(fg)

実はこれがなかなか良い。

Fg -> fg(fg) -> g(Fg) -> g(fg(fg)) fab -> a(bb) より f = (λa.(λb.a(bb))) このとき fg -> (λb.g(bb)) より F = (λg.fg(fg)) = (λg.(λb.g(bb))(λb.g(bb)))

これは特に「Yコンビネータ」と呼ばれる。
(普通は (λf.(λx.f(xx))(λx.f(xx))) と書かれる。)

不動点コンビネータの使い方(再帰)

面倒なので再帰としての簡単な使い方だけ書く。
まあこの記事を読みたいような人なら言うまでもないだろうけど。

function f(x) { if(p(x)) { A(x); } else { f(B(x)); } } という処理は、 Yfx -> f(Yf)x より、 f = (λn.(λx.px(Ax)(n(Bx)))) と表現できる。 (ただし、pxは真偽値を返し、true = (λxy.x)、false = (λxy.y) とする)

2013/09/04

「checking version... configure: error: not suitable, we need >= 1.0.6」の解決

詳細はここ。
[Libreoffice-bugs] [Bug 45652] New: error in autogen.sh. Incorrect detection mysqlcppconn (MySQL c++ connector)
ログは略。

$ emerge --version Portage 2.2.1 (default/linux/amd64/13.0/desktop, gcc-4.8.0, glibc-2.17, 3.10.7-gentoo x86_64) $ sudo emerge -u libreoffice (略) checking version... configure: error: not suitable, we need >= 1.0.6 (後略)

問題が起きるlibreofficeのバージョンは4.0.4.2以降。 確認した限りでは4.1.1.2でもこの問題が起きた。
このメッセージの意味するところは「dev-db/mysql-connector-c++ のバージョンが古い」ということなのだが、実際の問題点は「mysqlのshared libraryがロードされていない」ことである。

簡単に説明すると、例えばlibreoffice-4.1.1.2のconfigure.acにおいては以下のような記述がある。
なお、先頭の数字は行番号。

libreoffice-4.1.1.2/configure.ac
7671 AC_MSG_CHECKING([MySQL Connector/C++]) 7672 if test "$with_system_mysql_cppconn" = "yes"; then 7673 AC_MSG_RESULT([external]) 7674 SYSTEM_MYSQL_CPPCONN=YES 7675 AC_LANG_PUSH([C++]) 7676 AC_CHECK_HEADER(mysql_driver.h, [], 7677 [AC_MSG_ERROR(mysql_driver.h not found. install MySQL C++ Connectivity)], []) 7678 AC_CHECK_LIB([mysqlcppconn], [main], [:], 7679 [AC_MSG_ERROR(MySQL C++ Connectivity lib not found or functional)], []) 7680 save_LIBS=$LIBS 7681 LIBS="$LIBS -lmysqlcppconn" 7682 AC_MSG_CHECKING([version]) 7683 AC_RUN_IFELSE([AC_LANG_SOURCE([[ 7684 #include 7685 7686 int main(int argc, char **argv) { 7687 sql::Driver *driver; 7688 driver = get_driver_instance(); 7689 if (driver->getMajorVersion() > 1 || \ 7690 (driver->getMajorVersion() == 1 && driver->getMinorVersion() > 0) || \ 7691 (driver->getMajorVersion() == 1 && driver->getMinorVersion() == 0 && driver->getPatchVersion() >= 6)) 7692 return 0; 7693 else 7694 return 1; 7695 } 7696 ]])],[AC_MSG_RESULT(OK)],[AC_MSG_ERROR([not suitable, we need >= 1.0.6])],[]) 7697 7698 AC_LANG_POP([C++]) 7699 LIBS=$save_LIBS 7700 else

ここで7684行から7695行までのコードがコンパイル・実行され、それが0を返した場合はバージョンが要求される条件を満たすと判断するようだ。
しかし、(少なくとも俺の)gentooでは、/usr/lib/mysql/にパスが通っていないため、コンパイルは通るもののlibmysqlclient.so.18がロードされず、その結果上記プログラムは実行時エラーを返す。無論、戻り値は0ではない。
んで、その結果バージョンが古すぎると判定されるという仕組みだ。
解決策として、mysqlのライブラリがロードされるようにパスを通せば良い。
幸運にも、gentooはld.so.confを編集したりせずともグローバルの環境変数を弄れる仕組みがあるので、それを利用する。

/etc/env.d/99local (追記、無ければ新規作成)
# for mysql LDPATH="/usr/lib/mysql:/usr/lib64/mysql"

シェルのPATH環境変数を弄ったことのある人には違和感があるかもしれないが、ここで記されているように、LDPATHは自動で連結される仕組みになっているので、

LDPATH="foo:bar:$LDPATH"
のように最後にLDPATH自体を繋げる必要は無いらしい。

さて、上記ファイルを作成したら最後に変更を反映させよう。

# env-update && source /etc/profile

have a good gentoo!

2013/03/24

ABI関係の新フラグ導入で依存が滅茶苦茶になりかけたので対処

ABI_X86というオプションが導入されたらしい。
簡単に言うと、ABIとはamd64のCPUでx86のバイナリを動かしたりできる機能らしい。 それはそれで良いのだが、問題は依存関係。
wineが依存してるABI関係のパッケージが衝突しやがった。

$ emerge --version Portage 2.2.0_alpha166 (default/linux/amd64/13.0/desktop, gcc-4.7.2, glibc-2.16.0, 3.8.4-gentoo x86_64) $ ABI_X86="64 32" emerge -uDNpv world --with-bdeps=y These are the packages that would be merged, in order: Calculating dependencies... done! (ここへんでいろいろパッケージ) [blocks B ] x11-libs/libXrandr[abi_x86_32] ("x11-libs/libXrandr[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXinerama[abi_x86_32] ("x11-libs/libXinerama[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXp[abi_x86_32] ("x11-libs/libXp[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXcursor[abi_x86_32] ("x11-libs/libXcursor[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libpciaccess[abi_x86_32] ("x11-libs/libpciaccess[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXpm[abi_x86_32] ("x11-libs/libXpm[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] media-libs/fontconfig[abi_x86_32] ("media-libs/fontconfig[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXft[abi_x86_32] ("x11-libs/libXft[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXxf86vm[abi_x86_32] ("x11-libs/libXxf86vm[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] media-libs/freetype[abi_x86_32] ("media-libs/freetype[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] <=app-emulation/emul-linux-x86-xlibs-20130224 ("<=app-emulation/emul-linux-x86-xlibs-20130224" is blocking x11-libs/libXdmcp-1.1.1-r1, x11-libs/libXtst-1.2.1-r1, media-libs/freetype-2.4.11-r2, x11-libs/libXt-1.1.3-r1, x11-proto/renderproto-0.11.1-r1, x11-$ ibs/libXrandr-1.4.0-r1, x11-libs/libXcomposite-0.4.4-r1, x11-libs/libXinerama-1.1.2-r1, x11-proto/xineramaproto-1.2.1-r1, x11-libs/libXxf86vm-1.1.2-r1, x11-libs/libXpm-3.5.10-r1, media-libs/fontconfig-2.10.2-r1, x11-proto/inputproto-2.3, x11-libs/libXdamage-1.1.4-r1, x11-$ roto/xf86bigfontproto-1.2.0-r1, x11-libs/libXaw-1.0.11-r2, x11-libs/libICE-1.0.8-r1, x11-proto/xproto-7.0.23-r2, x11-libs/libX11-1.5.0-r1, x11-libs/libXi-1.7, x11-libs/libXmu-1.1.1-r1, x11-libs/libxcb-1.9-r1, x11-libs/libXau-1.0.7-r1, x11-libs/libXxf86dga-1.1.3-r1, x11-pr$ to/xextproto-7.2.1-r1, x11-proto/damageproto-1.2.1-r1, x11-proto/recordproto-1.14.2-r1, x11-proto/scrnsaverproto-1.2.2-r1, x11-libs/libXScrnSaver-1.2.2-r1, x11-libs/libXfixes-5.0-r1, x11-libs/libXext-1.3.1-r1, x11-proto/xf86vidmodeproto-2.3.1-r1, x11-proto/kbproto-1.0.6-r$ , x11-proto/xcb-proto-1.8-r1, x11-proto/compositeproto-0.4.2-r1, dev-libs/libpthread-stubs-0.3-r1, x11-libs/libSM-1.2.1-r1, x11-proto/randrproto-1.4.0-r1, x11-libs/libXv-1.0.7-r1, x11-proto/xf86dgaproto-2.1-r2, x11-proto/fixesproto-5.0-r1, x11-proto/printproto-1.0.5-r1, x$ 1-libs/libpciaccess-0.13.1-r1, x11-libs/libXcursor-1.1.13-r1, x11-libs/libXp-1.0.1-r1, x11-libs/libXrender-0.9.7-r1, x11-proto/videoproto-2.3.1-r1, x11-libs/libXft-2.3.1-r1) [blocks B ] x11-libs/libXau[abi_x86_32] ("x11-libs/libXau[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXfixes[abi_x86_32] ("x11-libs/libXfixes[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libxcb[abi_x86_32] ("x11-libs/libxcb[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXmu[abi_x86_32] ("x11-libs/libXmu[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXrender[abi_x86_32] ("x11-libs/libXrender[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libSM[abi_x86_32] ("x11-libs/libSM[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libICE[abi_x86_32] ("x11-libs/libICE[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXaw[abi_x86_32] ("x11-libs/libXaw[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXxf86dga[abi_x86_32] ("x11-libs/libXxf86dga[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXv[abi_x86_32] ("x11-libs/libXv[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXScrnSaver[abi_x86_32] ("x11-libs/libXScrnSaver[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXdmcp[abi_x86_32] ("x11-libs/libXdmcp[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXcomposite[abi_x86_32] ("x11-libs/libXcomposite[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXtst[abi_x86_32] ("x11-libs/libXtst[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXdamage[abi_x86_32] ("x11-libs/libXdamage[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXext[abi_x86_32] ("x11-libs/libXext[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXt[abi_x86_32] ("x11-libs/libXt[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libXi[abi_x86_32] ("x11-libs/libXi[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) [blocks B ] x11-libs/libX11[abi_x86_32] ("x11-libs/libX11[abi_x86_32]" is blocking app-emulation/emul-linux-x86-xlibs-20130224) Total: 54 packages (2 upgrades, 1 new, 51 reinstalls), Size of downloads: 0 kB Conflict: 30 blocks (30 unsatisfied) (その他のメッセージ)

ABI_X86="64 32"というのは、64bitと32bitのバイナリを実行できるようにしたいという意味である、たぶん。
上のログから、app-emulation/emul-linux-x86-xlibsが、abi_x86_32(ABI_X86で32を指定していると有効にされるようだ)が有効になったlibX*とかXorg関係の多数のパッケージと衝突しているらしい。
んで、wineがemul-linux-x86-xlibsに依存しててこのままだと後々面倒になりそうだったので、とりあえずwineでだけABI_X86="64 32"を指定して、他のパッケージではデフォルト(たぶんABI_X86="64"だけ)にしておくようにした。

必要なportageのバージョンは2.2以降。
まず、/etc/portage/env/以下に適当な名前のファイルを作る。envディレクトリが無ければそれも作る。
俺は今回はabi_x86_32_enableという名前で作ることにした。
そのファイルに、優先して設定したいオプションを記入する。

/etc/portage/env/abi_x86_32_enable
# for wine, app-emulation/emul-linux-x86-xlibs, etc... ABI_X86="64 32"

あとは、このファイルの内容を適用したいパッケージを/etc/portage/package.envに追記する。

/etc/portage/env/package.env (一部)
app-emulation/wine abi_x86_32_enable

あとは、うどんワールドとかしておけば幸せになれます。
jdkのヘッダにパスが通ってなくてemergeが失敗した話。とかabi_x86_32 Multilib madness [Not as SOLVED as I thought]も参照。