前回 紹介したように、gmtpに文字コード回りのパッチをあてることで、無事Plamo Linux環境とNexus 7の間でファイルをやりとりできるようになりました。しかしながら、あれこれ使っているとgmtpの欠点も目についてきました。
まず最初に気になったのは、gmtpを起動してからNexus 7側のデータが表示されるまでにずいぶん時間がかかることです。しばらく待っていれば表示はされるものの、どれくらい待たされるのかが分からないのはちょっと苦痛です。
またgmtpには、ファイルの転送のみならず、ファイルの削除や移動といった機能も用意されてはいるものの、Nexus 7上ではそれらの処理は機能しないようで、操作しようとすると多数のエラーメッセージが出力されます。
前回紹介したように、EUC-JPを利用可能にするための修正も、ファイル名の文字コードしか直していないので、途中のパス名に日本語があるとエラーダイアログが表示されるのも見苦しいところです。
そのようなわけで、gmtp以外に何かいいツールはないか、と探してみることにしました。
FUSEとjmtpfs
そうして見つけたのがjmtpfs です。mtpfsはgmtpとは全く異なる視点から開発されたソフトウェアです。すなわち、gmtpがMTPデバイス上のファイルを操作するための、いわゆるファイル管理ツール として設計されているのに対し、jmtpfsはMTPデバイスを従来のUSBマス・ストレージクラスと同じように、ファイルシステムとしてマウントする機能を提供する ように設計されています。
しかし前回にも触れたように、自律的にファイルを管理しているMTPデバイスでは、単純なUSBストレージデバイスとは異なり、ファイルシステムそのものは外部に公開せず、データのやりとりはMTPプロトコル を介することになっています。そこでjmtpfsでは、MTPデバイスへのアクセスはlibmtpを用い、その結果をカーネルへFUSE の機能を用いて提供することで、MTPデバイスを仮想的なファイルシステムとして見せる ような設計になっています。
この方法でMTPデバイスを利用するのはjmtpfsが最初ではなく、先に開発された"MTPfs"というというソフトウェアも存在します。しかし、MTPfsはここ数年開発が停滞しており、Nexus 7のような新しめのMTPデバイスは正しく操作できないようです。
FUSE (Filesystem in USErspace)は、本来カーネル内部の処理であるファイルシステムに関する操作をユーザ領域で実行可能にする機能 です。
HDD等の記憶装置とデータをやりとりするファイルシステムは、速度と信頼性を要求される重要かつ複雑な機能で、たいていのOSでは専用に設計された標準ファイルシステムがカーネルの構成要素として不可分に組み込まれています。
一方、伝統的なUNIXに比べてずっと遅れて誕生したLinuxでは、専用のファイルシステムを開発する一方で、他のOS用に普及している各種ファイルシステムにも積極的に対応してきました。その結果、モジュールドライバ化された多数のファイルシステムが利用可能で、それらを必要に応じて組み込んだり取り外したりできるようになっています。
Linuxのファイルシステムはこのように柔軟性に富んだ設計になっているので、新しいファイルシステムはカーネルの他の部分とは独立 したモジュールドライバとして開発することができます。しかし、他の部分とは独立に開発できると言っても、カーネル内部で動作するドライバを書くにはカーネルプログラムに関する知識が必要で、コーディングやデバッグもユーザ領域で動作する通常のソフトウェアに比べて大変です。そこで考案されたのがFUSEです。
FUSEは他のファイルシステム用のドライバ同様、モジュールとしてカーネルに組み込まれるものの、HDD等の記憶装置用のデバイスドライバを操作するのではなく、ユーザ領域で動作するソフトウェアからのデータを受け取り、あたかも記憶装置からのデータのように見せる ことができます。
図1 通常のファイルアクセスとFUSEを使ったアクセス
すなわち、FUSEのAPIを利用して必要な情報をやりとりするようなソフトウェア(FUSE用サービス)さえ書けば、ファイルがどこにあっても、極論すればファイルの実体は存在しなくても、他のファイル操作コマンドからはHDD上の通常ファイルと同様に扱える わけです。
このようなFUSEの特徴を利用して、tarやzipでまとめた書庫ファイルを展開せずに読み書きしたり、sshやhttp経由で利用しているネットワークサービスをローカルなファイルシステムと同様に見せたり、ファイルやディレクトリを透過的に暗号化したり、NTFSやZFSといったLinux以外のOS用のファイルシステムを利用したりするサービスが多数開発 されています。
今回紹介するjmtpfs もそのようなサービスの一種で、libmtp経由でMTPデバイスにアクセスした結果をFUSE経由で他のアプリケーションに提供するように設計されているわけです。
jmtpfsとFDclone
jmtpfsのビルドは簡単で、ソースコードを展開し、configure && make install
だけで済みます。作成されるのはjmtpfsというコマンドだけで、MTPデバイスをマウントしたいディレクトリを引数に指定して、このコマンドを実行すればいいだけのようです。一般ユーザとして自分のホームディレクトリ以下にマウントすることも可能なようなので、さっそく試してみました。
$ mkdir ~/Mtp
$ jmtpfs ~/Mtp
Error: Unable to open ~/.mtpz-data for reading.
Device 0 (VID=18d1 and PID=4e41) is a Google Inc (for Asus) Nexus 7 (MTP).
Android device detected, assigning default bug flags
gmtpではずいぶん時間がかかるMTPデバイスとの接続作業が、jmtpfsではあっと言う間に完了しました。dfで確認してもちゃんと見えます。
$ df -h
ファイルシス サイズ 使用 残り 使用% マウント位置
/dev/sdb2 46G 28G 16G 65% /
none 7.9G 916K 7.9G 1% /dev
/media 7.9G 0 7.9G 0% /media
/tmp 7.9G 72K 7.9G 1% /tmp
192.168.1.6:/share/Srcs/ 299G 280G 19G 94% /share/Srcs
..
jmtpfs 28G 14G 14G 50% /home/kojima/Mtp
これはいけるかも、と思って~/Mtp以下をのぞいてみましたが、残念ながら文字コードが合っていない ようです。
$ ls ~/Mtp/
????????鴻???????若??/
NKFを使って文字コードを調べると、想像通りUTF-8になっていました。
$ ls ~/Mtp/ | nkf -g
UTF-8
$ ls ~/Mtp/ | nkf -e
内部ストレージ/
普段使っているKDEのファイルマネージャdolphinでは、ファイルシステム上の文字コードはEUC-JPだと思っているので、文字化けして使いものになりません。
図2 Dolphineから見たMTPデバイス
一方、Xfce4用のファイルマネージャであるThunarには文字コードの自動認識機能があるようで、~/Mtp/以下のファイル名を正しく表示することはできるものの、別ディレクトリにあるEUC-JPなファイルを転送しようとするとエラーになってしまいます。
図3 Thunarから見たMTPデバイス
jmtpfsはMTPデバイスの操作には優れているようだけど、文字コードのことを考えるとgmtpを使い続けるしかないか……、そう考えている時にFDclone というファイル管理ソフトを思い出しました。
FDcloneは、MS-DOS環境で普及していたFDというファイル管理ソフトを参考に、UNIX環境向けに開発されたCUIなファイル管理ソフト で、白井隆氏が1995年ごろから開発を続けている国内最古参のフリーソフトウェアの一つです。
FDcloneはそのような長い歴史を持つソフトウェアなだけあって、さまざまなUNIX環境、さまざまな文字コードの元で使われることが想定されていて、ディレクトリごとに異なる文字コードを指定するような機能も持っています。
かつてUNIXサーバでCAP(Columbia Appletalk Protocol)とsambaを動かして、UNIX/Windows/Macの3種でファイル共有する際など、CAPが使うディレクトリはCAPかHEXエンコード、sambaが使うディレクトリはShift-JIS、UNIX向けのディレクトリはEUC-JP、メールやニュースのスプールはISO-2022-JP、とディレクトリごとに異なる文字コードを使い分ける設定がよくありました。
具体的には、/etc/fd2rcあるいは~/.fd2rcという設定ファイルで、UTF-8を使っているディレクトリのリストをUTF8PATH という変数に指定してやれば、そのディレクトリ以下ではファイル名の文字コードにUTF-8を使っていると見なし、別のディレクトリからファイルをコピーする際も自動的に文字コードを変換 してくれます。
493 # directories on which Kanji code in filename is UTF-8
494 # Default: none
495 UTF8PATH="~/Mtp"
496
試してみると、FDcloneを動かしているターミナルのタイトルは文字化けするものの、FDclone自体は文字コードを正しく認識して表示できます。また、文字コードが異なるファイル名の補完も問題なく行えるようです。
図4 FDcloneを使ったファイルコピー
どうやらFDcloneを使えば、jmtpfsの安定したMTPデバイス操作を、文字コードを気にせず利用できそうです。
この組み合わせを見つけた時は、かつての文字コード混在時代のノウハウを、その当時から使われてきたFDcloneで活用するのは、温故知新なPlamoらしいな、と思わずほくそ笑んでしまったのでした。
ちなみにjmtpfsでマウントしたMTPデバイスをアンマウントする際は、fusermountに -u オプションを指定します。
$ fusermount -u ~/Mtp
jmtpfsとiconv
jmtpfsが使いものになりそうだ、ということをチェックして数日後、再度Nexus 7にファイルを転送しようとしてjmtpfsをイジっていると、あれこれオプションが指定できることに気づきました。その中には文字コードを指定するためのオプション もあるようです。
$ jmtpfs -h
Error: Unable to open ~/.mtpz-data for reading.
usage: jmtpfs mountpoint [options]
general options:
-o opt,[opt...] mount options
-h --help print help
-V --version print version
...
Module options:
[iconv]
-o from_code=CHARSET original encoding of file names (default: UTF-8)
-o to_code=CHARSET new encoding of the file names (default: EUC-JP)
[subdir]
-o subdir=DIR prepend this directory to all paths (mandatory)
-o [no]rellinks transform absolute symlinks to relative
jmtpfs options:
-l --listDevices list available mtp devices and then exit
-device=, Device to mount. It not specified the first device found is used
これを使えば文字コードの変換も可能かも、と試してみましたが、オプション指定がうまく行きません。
$ jmtpfs -o from_code=UTF-8 -o to_code=EUC-JP ~/Mtp
...
fuse: unknown option `from_code=UTF-8'
"Module options:"として紹介されているので、FUSEモジュールをロードする際に指定するのかな、と試しましたが、そうでもなさそうです。
$ sudo modprobe fuse -o from_code=UTF-8,to_code=EUC-JP
modprobe: invalid option -- 'o'
$ sudo modprobe fuse from_code=UTF-8,to_code=EUC-JP
modprobe: ERROR: could not insert 'fuse': Invalid argument
さて、このオプションはどう指定するのだろう……、と調べてみたところ、モジュールとしてiconvを指定した上で、文字コードの変換を指定するという形式でした。
$ jmtpfs -o modules=iconv,from_code=UTF-8,to_code=EUC-JP ~/Mtp
Error: Unable to open ~/.mtpz-data for reading.
Device 0 (VID=18d1 and PID=4e41) is a Google Inc (for Asus) Nexus 7 (MTP).
Android device detected, assigning default bug flags
こうしてマウントすれば ~/Mtp 以下の文字コードは自動的に変換されて表示されます。
$ ls ~/Mtp
内部ストレージ/
$ ls ~/Mtp/内部ストレージ/MyBookshelf/青空文庫/
09hokkyokuseigono_sencho.txt ジンジャー&ブレッドのお話/
19_14618.html ドグラ・マグラ(夢野久作).txt
975_15935.html 悪魔(芥川竜之介).txt
...
bashのTabキーによるファイル名の補完も効きますし、dolphin等のファイルマネージャからも問題なく操作できます。
図5 FUSEレベルで文字コードを変換
前節で紹介した設定はFDclone自身にしか効きませんが、jmtpfsで指定した設定はカーネルと同じレベルで機能するので、全てのアプリケーションから利用可能です。jmtpfsでこのオプションを指定することが、Plamo Linux環境でMTPデバイスを利用する際のファイナル・アンサーということになりました。
さて、去年の暮れから5ヵ月ほど、Nexus 7を主に自炊電子書籍と青空文庫のリーダーとして使ってみました。
革製カバーを付けたNexus 7は約480g ほどあります。480gというと500mlのペットボトル飲料程度なので、そう大した重さではないだろうと高をくくっていましたが、ベッドに寝ころがって読んでると、思ったよりも腕がツラくなります。
この重さは本だと何ページくらいになるだろう、と思って、手元にある文庫本を調べてみたところ、京極夏彦の「魍魎の匣」が1060pで510g ほどでした。
図6 Nexus 7と「魍魎の匣」の重さ比較
さすがに「魍魎の匣」ほどのページ数になると寝ころがっての片手読みなんてことはできないので、膝に置くなりして重さを分散するからそれほど気にならないものの、Nexus 7の場合は片手持ちでページめくりもできてしまう分、余計重さが効いてくるようです。
マニアの性(さが)として、この手のガジェットを選択する際は、画面解像度や記憶容量などを優先しがちですが、「 重量」というのも決して無視できない要素だなぁ…、と改めて思い知った次第です。