Введение ======== Программы zip/unzip устарели чрезвычайно. Это видно по их запутанному, перегруженному ifdef'ами коду. Плетёшься по нему и спотыкаешься. Несмотря на поддержку кучу платформ, эти программы не умеют обращаться с кодировками при компилировании в Linux. Обмен с внешним миром для пользователей Linux невозможен без архиваторов. Проблемы совместимости должны быть сведены к минимуму. Но что мы имеем. Проблема ======== При распаковке архива, созданного в DOS/Win, названия файлов перекодируются из cp866 (кодировка хранения имён при архивации в указанных системах) в неизвестно что, поэтому при всём желании кодировку не восстановить уже никакими силами. Предлагается ============ Поскольку в файлах ZIP хранится информация о том, в каких системах они созданы, предлагается перекодировать названия в кодировку файловой системы.
Created attachment 502 [details] Патч, убирающий перекодировку Приложенный патч убирает перекодировку названий в unzip, после чего можно хотя бы воспользоваться convmv для перекодирования названий. Было бы замечательно вставить использование iconv, чтобы названия перекодировались автоматически.
(In reply to comment #0) > При распаковке архива, созданного в DOS/Win, названия файлов перекодируются из > cp866 (кодировка хранения имён при архивации в указанных системах) в > неизвестно что, поэтому при всём желании кодировку не восстановить уже > никакими силами. Ну не такое уж это и "неизвестно что" :-) Просто они там избалованы своими латинскими языками, вот и перекодируют всё из cp850 в cp1252. Работает такой вариант: $ unzip -Z1 filename.zip | iconv -f cp1252 -t cp850 | iconv -f cp866 Безобразие, конечно. Надо исправлять. Вопрос в том, как правильно. Честно говоря, я не совсем понял предложение Виталия по перекодировке. Как мне кажется, кусок кода, удаляемый патчем, именно и занимается разбором случаев ОС архива -> кодировка. Другое дело, что сейчас исходная и результирующая кодировки жестко забиты (850/1252 и наоборот?!). Можно поступить немного лучше авторов unzip и переопределить макросы _OEM_INTERN как cp866->локаль и _ISO_INTERN как cpххх->локаль. Либо пойти дальше и добавить переменные окружения / ключ, которые бы указывали исходные кодировки имён файлов в архивах.
Да, именно так и надо сделать. Приложенный мной патч просто показывал место решения проблемы (я, например, его достаточно долго искал). Правда для соответствия кодировок в DOS/Unix наверное придётся таблицу составить, чтобы сделать и для украинских и белорусский локалей.
Предлагаю на рассмотрение следующий патч. Добавлены ключи -O и -I, задающие кодировку имён файлов в архивах DOS/Windows и всех остальных ОС соответственно. По умолчанию для совместимости установлены CP850 и CP1252. Однако, имена файлов перекодируются лишь в случае полностью безошибочной работы iconv(). Поскольку из CP850/1252 в кириллическую локаль конвертировать пока ещё никто не научился, то для кириллицы перекодировка по умолчанию отсутствует. Возможно, имеет смысл совсем отбросить совместимость и убрать попытки перекодировки CP850/1252 -> локаль. Что скажете? В пакет можно также положить /etc/profile.d/unzip.sh примерно такого содержания: # Set default encoding for filenames inside DOS/Windows Zip archives export UNZIP="-O CP866" export ZIPINFO="-O CP866" К сожалению, авторы unzip изначально не предусматривали свои многочисленные макросы для преобразования имён файлов из/в многобайтные кодировки. Поэтому для работы в UTF-8 локали это хозяйство, скорее всего, не годится.
Created attachment 531 [details] unzip-5.50-alt-iconv.patch
Я бы всё-таки составил таблицу зависимости кодировки в DOS в зависимости от текущей локали. cp1252 cp850 iso8859-1 cp850 или как там cp1251 cp866 koi8-r cp866 koi8-u cp866 и т.д. unzip должен корректно работать в 1. командной строке 2. ark 3. mc не требуя особых настроек для этого. Разархивирование - тривиальная операция, и должна выполняться без напряжения.
Created attachment 532 [details] unzip-5.50-alt-iconv-v1.1.patch Теперь понял, что вы имели в виду под таблицей. Цепляю новый патч.
Здорово. А люди столько лет мучались... (Я проверил, вроде действительно всё нормально) Теперь бы ещё для zip такой патч написать, чтобы созданные в Linux архивы читались в DOS/Win.
Сформулирую задачи: 1. Обеспечить переносимость ZIP архивов, содержащих файлы с кириллические именами, между OC DOS/Windows и Linux. 2. Обеспечить переносимость ZIP архивов, созданных в Linux с различными кодировками локали. Формат ZIP официально поддерживает лишь имена файлов в кодировке ISO8859-1 и информацию о кодировке не предусматривает. На практике линуксовые ZIP архивы создаются в кодировке текущей локали, а DOS/Windows архивы -- в кодировке OEM CP850/866/... Что касается переносимости, то фактически на данный момент большинство архиваторов для Windows, и в том числе встроенный в Windows XP, рассматривают все архивы, вне зависимости от ОС, где они были созданы, как хранящие имена файлов в кодировке OEM. Исключениями являются Info-Zip Wiz и 7-zip, которые оставляют имена файлов в Linux-архивах без перекодировки (таким образом корректно отображаются кириллические Linux-архивы, созданные, например, в локали ru_RU.CP1251). Получается, что для решения пункта No.1 надо создавать Linux-архивы в CP850/866, что в принципе не запрещено, как если бы у пользователя была установлена соответствующая кодировка локали. А что касается пункта No.2, то unzip'у остаётся только прикрутить автоугадывание кириллических кодировок для Linux-архивов, иных вариантов я не пока вижу.
patch (v1.1) applied in 5.50-alt4. thanks :)
Можно пока прикрыть, но решение к сожалению не универсальное. Буду думать.
Created attachment 1402 [details] Патч для перекодировки с поддержкой UTF-8 состряпал для себя патч для перекодировки в UTF-8 локаль.
(In reply to comment #12) > Created an attachment (id=1402) [edit] > Патч для перекодировки с поддержкой UTF-8 > состряпал для себя патч для перекодировки в UTF-8 локаль. Хорошо было бы найти патч для zip. Чтобы можно было аод Linux с русской локалью UTF-8 паковать архивы ZIP с русскими именами, которые корректно бы читались в Windows.
для unzip FIXED (#12313), для zip -- NEW (#12562)
Окончательный патч с использованием natspec можно найти в пакете http://sisyphus.ru/srpm/Sisyphus/unzip/patches
Спасибо!
извините, что здесь спрашиваю. А где есть информация, какими перекодировками можно распаковать современные zip-файлы? С использованием natspec или без него / с enca / без enca. Как угодно! А?
(В ответ на комментарий №17) > А где есть информация, какими перекодировками можно распаковать современные > zip-файлы? Возможно, такой вопрос когда-то и привёл к enconvmv из одноименного пакета.
(В ответ на комментарий №17) > извините, что здесь спрашиваю. > А где есть информация, какими перекодировками можно распаковать современные > zip-файлы? С использованием natspec или без него / с enca / без enca. Как > угодно! Современные zip-файлы должны паковаться с использованием UTF-8, и тот же 7z должен успешно их распаковывать.