書庫マネージャって、GNOME 最新版でも、未だ Windows の SJIS エンコーディングを含んだ zip ファイルをまともに扱えないんだねぇ…。未だに文字化けする:
ちょっと仕事でそういう書庫ファイルを扱うことが多くなってきて、それを毎回手動で変換するのがだんだんと面倒になってきたので Web で調べてみたんだけど、上位にあがってくる検索結果としては、例えば “p7zip-full” をインストールしていると文字化けするとか、”unzip” を日本語対応のパッチ付きのもので置き換えるとか、古くて信ぴょう性の低い情報ばかり (例えば、前者のパッケージをインストールしていない環境でも文字化けは発生しているとか)。
で、一体正解は何なのだろうかと 。ちなみに、今の環境はと言うと:
$ dpkg -l file-roller unzip ii file-roller 3.10.2.1-mikeforce1 amd64 archive manager for GNOME ii unzip 6.0-9ubuntu1 amd64 De-archiver for .zip files
おそらくは “unzip” 側が怪しいだろうということで、その deb-src をダウンロードしてみると、changelog に以下のような記述が:
unzip (6.0-9ubuntu1) saucy; urgency=low * Resynchronise with Debian. Remaining changes: - Add patch from archlinux which adds the -O option, allowing a charset to be specified for the proper unzipping of non-Latin and non-Unicode filenames. -- Colin Watson Mon, 13 May 2013 13:00:12 +0100
この -O オプションに対するパッチファイルは:
06-unzip60-alt-iconv-utf8
で、実際のコマンドライン・オプションは:
$ unzip -h UnZip 6.00 of 20 April 2009, by Debian. Original by Info-ZIP. Usage: unzip [-Z] [-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir] Default action is to extract files in list, except those in xlist, to exdir; file[.zip] may be a wildcard. -Z => ZipInfo mode ("unzip -Z" for usage). -p extract files to pipe, no messages -l list files (short format) -f freshen existing files, create none -t test compressed archive data -u update files, create if necessary -z display archive comment only -v list verbosely/show version info -T timestamp archive to latest -x exclude files that follow (in xlist) -d extract files into exdir modifiers: -n never overwrite existing files -q quiet mode (-qq => quieter) -o overwrite files WITHOUT prompting -a auto-convert any text files -j junk paths (do not make directories) -aa treat ALL files as text -U use escapes for all non-ASCII Unicode -UU ignore any Unicode fields -C match filenames case-insensitively -L make (some) names lowercase -X restore UID/GID info -V retain VMS version numbers -K keep setuid/setgid/tacky permissions -M pipe through "more" pager -O CHARSET specify a character encoding for DOS, Windows and OS/2 archives -I CHARSET specify a character encoding for UNIX and other archives See "unzip -hh" or unzip.txt for more help. Examples: unzip data1 -x joe => extract all files except joe from zipfile data1.zip unzip -p foo | more => send contents of foo.zip via pipe into program more unzip -fo foo ReadMe => quietly replace existing ReadMe if archive file newer
「太字のオプション」を使うと日本語SJISなどを正しくエンコーディングしてくれるっぽい。実際に試してみると:
$ uznip -l test-zip-from-winxp.zip Archive: test-zip-from-winxp.zip Length Date Time Name --------- ---------- ----- ---- 0 2013-12-30 15:45 test-zip-from-winxp/ГEГBГУГhГEГYВ┼НьРмВ╡В╜ГtГ@ГCГЛ.txt 277040 2013-12-28 13:38 test-zip-from-winxp/У·Ц{МъВ╠ZIPГtГHГЛГ_.zip 0 2013-12-30 15:45 test-zip-from-winxp/У·Ц{МъВ╠ГtГHГЛГ_/ --------- ------- 277040 3 files $ unzip -l -O shift-jis test-zip-from-winxp.zip Archive: test-zip-from-winxp.zip Length Date Time Name --------- ---------- ----- ---- 0 2013-12-30 15:45 test-zip-from-winxp/ウィンドウズで作成したファイル.txt 277040 2013-12-28 13:38 test-zip-from-winxp/日本語のZIPフォルダ.zip 0 2013-12-30 15:45 test-zip-from-winxp/日本語のフォルダ/ --------- ------- 277040 3 files
ということで、このオプションは利用できるっぽいので試しに書庫マネージャの zip コマンドクラスにオプションを追加してみる:
diff -uNrdp file-roller-3.10.2.1~/src/fr-command-zip.c file-roller-3.10.2.1/src/fr-command-zip.c --- file-roller-3.10.2.1~/src/fr-command-zip.c 2013-10-27 21:28:46.000000000 +0900 +++ file-roller-3.10.2.1/src/fr-command-zip.c 2013-12-30 09:35:10.193504249 +0900 @@ -182,6 +182,10 @@ fr_command_zip_list (FrCommand *comm) fr_process_begin_command (comm->process, "unzip"); fr_process_set_begin_func (comm->process, list__begin, comm); fr_process_add_arg (comm->process, "-ZTs"); + + fr_process_add_arg (comm->process, "-O"); + fr_process_add_arg (comm->process, "shift-jis"); + fr_process_add_arg (comm->process, "--"); fr_process_add_arg (comm->process, comm->filename); fr_process_end_command (comm->process); @@ -315,6 +319,9 @@ fr_command_zip_extract (FrCommand *comm fr_process_add_arg (comm->process, "-j"); add_password_arg (comm, FR_ARCHIVE (comm)->password); + fr_process_add_arg (comm->process, "-O"); + fr_process_add_arg (comm->process, "shift-jis"); + fr_process_add_arg (comm->process, "--"); fr_process_add_arg (comm->process, comm->filename);
で、リビルドして実際に開いてみると:
ちなみに、Linux (UTF-8) と WindowsXP (Shift-JIS) の双方で作成した書庫の閲覧や展開も問題なかった。iconv で実装されたパッチなので Shift-JIS 以外のエンコーディングもちゃんと処理してくれているようだ。こんな Dirty なパッチに対して、Dirty なハックで対応してみたけれど、当分このまま使ってみることにする。