X-0027 XPIパッケージ作成時のパーミッションの問題を回避する

パーミッションの問題とは?

一般的なWindowsユーザーにとってはなじみの薄い話ですが、Linuxなどのプラットフォームではそれぞれのファイルについて、例えば作成者は自由に読み書きできるが他のユーザーは見るだけで変更はできない、などのようにアクセス権(パーミッション)を設定できます。WebサイトにCGIを設置する時などに出てくるアレです。なお、NT系のWindowsでも同じような機能があるのですが、それについてはここでは語りません。

Windows環境で普通に作成したファイルはLinuxなどのUnix系の環境ではどのようなアクセス権設定で扱われるのでしょうか。FTPクライアントなどで普通に転送した場合、通常は「644(作成者以外は読み込みのみ可能)」「666(誰でも読み書き可能)」「777(誰でも読み書き&実行可能)」などになるのですが……実はここに落とし穴があって、Mozillaは、Windows上でZIP形式で圧縮されたファイルについて、Unix系環境で展開したときに中身のファイルを「600(作成者以外は読み書きできない)」として扱ってしまうのです。そのため、Windows上で作成されたXPIパッケージをUnix系環境でインストールすると、管理者以外のユーザーはインストールされたファイルを読み込めず、Mozillaがエラーを起こして起動できなくなってしまいます

これはMozillaの実装の問題だと思うのですが、実際にパッケージを公開するにあたってはそんなことは言っていられません。どうにかしてこれを運用でカバーする必要があります。

install.jsではファイルのアクセス権はできない

まず考えつくのは、XPIパッケージに含めるinstall.js(インストール用スクリプト)の中でファイルのアクセス権を自動設定するというやり方です。しかし実際にはこれはできません。セキュリティの都合上、install.jsで使える機能の範囲内ではファイルのアクセス権は変更できないようになっています。

アクセス権の設定も含めて圧縮する

ここでちょっと発想を逆転してみましょう。展開されたファイルのアクセス権を後から変更するのではなく、元からアクセス権を設定した状態でファイルを圧縮してしまえば良いのです。

とはいえ、WindowsのファイルシステムはUnix系のそれとはだいぶ違いますので、普通のやり方でUnix式のアクセス権を設定する事はできません。

Windows環境でこれを行うには、Cygwinのchmodコマンドとzipコマンドを使うのが手っ取り早いです(zipコマンドは標準では組み込まれないので、インストール時に手動で選択する必要があります)。CygwinはWindows上でUnix環境を再現するためのソフトウェアで、CygwinのchmodコマンドはWindows上でもUnix式のアクセス権設定ができますし、zipコマンドはそうして設定されたアクセス権を保持したままファイルを圧縮できます。

chmodとzipの利用例

以下のようなディレクトリ構成の場合の例を示しましょう。Cygwinは「C:\Cygwin\」以下にインストールしているものと仮定します。

  • C [root]
    • XUL [dir]
      • myapp [dir]
        • content [dir]
          • myapp [dir]
            • contents.rdf
            • ...
        • locale [dir]
          • myapp [dir]
            • en-US [dir]
              • contents.rdf
              • ...
            • ja-JP [dir]
              • contents.rdf
              • ...
        • skin [dir]
          • myapp [dir]
            • classic [dir]
              • contents.rdf
              • ...
        • install.js

まず、content, locale, skinの3つのディレクトリを丸ごとmyapp.jarという名前のZIP書庫に圧縮してしまいます。

C:\XUL\myapp>C:\Cygwin\bin\zip -r myapp.jar content locale skin

最初の引数がオプション(rはディレクトリの中身も含める指定)、次が書庫ファイル名、その後に圧縮したいディレクトリやファイルの名前が続きます(ワイルドカードも使用可能)。圧縮するとMozillaの起動速度が低下する可能性があるので、パフォーマンス重視の場合はオプションを-r0(前述の指定+無圧縮モード)と指定するとよいでしょう。

次に、myapp.jarのアクセス権を設定します。ここでは「644(作成者以外は読み込みのみ可能)」にしてみます。

C:\XUL\myapp>C:\Cygwin\bin\chmod -c 644 myapp.jar install.js

chmodコマンドは、zipコマンドと同様に複数のファイルのアクセス権を同時に変更できます。

アクセス権を設定したら、後はこれらのファイルをXPIパッケージとして圧縮すれば完成です。

C:\XUL\myapp>C:\Cygwin\bin\zip -9 myapp.xpi myapp.jar install.js

-9は書庫をできる限り小さく圧縮する指定です。結果はあまり変わらないかもしれませんが、少しでもディスク容量を節約したい場合などはこれを指定してもよいでしょう。

ちなみに、僕はこれらに加えていくつかのファイルコピーなどのコマンドもまとめてバッチファイルに記述し、XPIパッケージの生成作業を半自動化しています。Windows時代でもこういう場合にはバッチファイルが便利でいいですね。