ブログ

Armadillo-420でunzipに失敗する

at_takuya.sasaki
2014年4月27日 10時18分

[現象]

Armadillo-420上でunzipを使ってzipファイルを解凍しようとすると、 以下のように失敗する。

[root@armadillo420-0 (ttymxc1) ~]# unzip test.zip
Archive:  test.zip
unzip: Unsupported compression method 0

[原因]

zipファイルの圧縮メソッド(アルゴリズム)が、無圧縮(stored)になっているため。

[詳細]

zipファイルの圧縮メソッドについては、以下のURLに説明があります。 http://www.wdic.org/w/TECH/ZIP - 圧縮アルゴリズム

Armadillo-400シリーズに標準でインストールされているbusybox 1.00.rc3のunzipでは、 一般的に使用されている[Deflate]という圧縮メソッド以外は、対応できていません。

atmark-dist/user/busybox/busybox-1.00.rc3/archival/unzip.c

177   if (zip_header.formated.method != 8) {
178      bb_error_msg_and_die("Unsupported compression method %d\n", zip_header.formated.method);
179   }

[回避策]

1) zipの圧縮メソッドを[Deflate]に変更する

zipファイルが[無圧縮(stored)]である必要がなく、[Deflate]で問題なければ、 こちらが一番簡単な対策になるかと思います。 Windowsの一般的な圧縮ツールでzipファイルを作成すると、たいていは[Deflate]になるかと思います。 今回試したzipファイルは、Lhaplusというツールで[圧縮設定3]-[圧縮アルゴリズム]-[ZIP]-[非圧縮]を 選択して、作成しています。

2) busyboxのバージョンを1.20.2に上げる。

Armadillo-400シリーズでは、ユーザーランドのコンフィギュレーションで busyboxのバージョンを上げることが可能です。

atmark@atde3:~$ cd ~/atmark-dist
atmark@atde3:~/atmark-dist$ make menuconfig 
 
    Kernel/Library/Defaults Selection  --->  を選択。
    [*] Customize Vendor/User Settings       をチェックしExitで抜ける。
 
    Userland Configuration より、
    BusyBox  --->   
    (v1.20.2)   Version  
atmark@atde3:~/atmark-dist$ make

busybox 1.20.2では、[無圧縮(stored)]にも対応しています。

atmark-dist/user/busybox/busybox-1.20.2/archival/unzip.c

243 static void unzip_extract(zip_header_t *zip_header, int dst_fd)
244 {
245         if (zip_header->formatted.method == 0) {
246                 /* Method 0 - stored (not compressed) */
247                 off_t size = zip_header->formatted.ucmpsize;
248                 if (size)
249                         bb_copyfd_exact_size(zip_fd, dst_fd, size);
250         } else {

ただし、 busyboxのバージョンを上げることでunzip以外のbusyboxで実装されている コマンドの仕様が変わる可能性もありますので、十分な確認が必要になるかと思います。

3) Debianパッケージのunzipを使用する。

busyboxではなく、Debian GNU/Linuxで使用されているunzipを使用します。 以下のHowToが参考になるかと思います。

[Howto : Debianのパッケージに含まれるコンパイル済みのバイナリをArmadilloで動作させる方法]
https://armadillo.atmark-techno.com/howto/use-debian-binary

以下は、すでに一度atmark-distのビルドが済んでいる状況で、 Debianのunzipを組み込む手順の一例になります。

3-1) unzipパッケージをダウンロード

atmark@atde3:~$ wget http://ftp.riken.jp/Linux/debian/debian-archive/debian/pool/main/u/unzip/unzip_5.52-12_armel.deb

3-2) unzipパッケージを展開

atmark@atde3:~$ dpkg -X unzip_5.52-12_armel.deb ./

3-3) Debianのunzipをbusyboxへのシンボリックリンクとは異なる    /binにコピーします

atmark@atde3:~$ cp usr/bin/unzip atmark-dist/romfs/bin/

3-4) atmark-distのイメージを再作成します

atmark@atde3:~$ cd atmark-dist
atmark@atde3:~/atmark-dist$ make image

3-6) 再作成したromfs.img.gzをArmadilloに書き込みます

3-5) Armadillo上で、パスを指定してunzipを実行します

[root@armadillo420-0 (ttymxc1) ~]# /bin/unzip
UnZip 5.52 of 28 February 2005, by Debian. Original by Info-ZIP.
…(省略)
[root@armadillo420-0 (ttymxc1) ~]# /bin/unzip test.zip
Archive:  test.zip
 extracting: test2.txt
 extracting: test.txt

(補足情報)

当初は、/usr/bin/unzipというbusyboxへのシンボリックリンクを 削除して、Debian版へ置き換えようと思ったが、以下にあるように、 シンボリックリンクがなくても、unzipはbusyboxが優先されてしまうようなので、 別なディレクトリにコピーする手段をとりました。

http://d.hatena.ne.jp/kakurasan/20131011/p1

ユーザーランドのコンフィギュレーションでbusyboxのbuilt-inから unzipを外すなど、いろいろと他の方法もあるかと思います。

以上