Пользователь Linux, который действительно работает в этой системе, часто сталкивается с проблемами кодировок: как содержимого файлов, так названий файлов. Практически на каждом шагу встречаются случаи, когда пользователя заставляют указывать кодировку (названий) файлов, с которыми он имеет дело. Это происходит при
монтировании дискет, компакт-дисков, флэш-дисков, принесённых жёстких дисков и других носителей; файловой системы jfs;
монтировании сетевых ресурсов через SAMBA;
записи дисков (создании файловых систем) с помощью команд mkisofs, growisofs, программ k3b, xcdroast и подобное;
в файловом менеджере mc, если вы хотите воспользоваться заложенной туда возможностью перекодирования текстов
Более того, существует целое непаханое поле программ, где надо бы указывать кодировку, а нечем:
ftp-сервера и ftp-клиенты;
nfs-сервера и при монтировании nfs
все файловые системы, используемых как для установки ОС, так и для переноса данных; (кроме jfs)
файловая система Rock Ridge на оптических дисках;
многие мультимедиа-проигрыватели. Выбор субтитров и звуковых дорожек для DVD. Перекодирование тегов mp3, записанных упрощенными, не совместимами со стандартом программами
Зачастую эти проблемы не решены, или решены частным образом (например, путём выбора при установке системы/программы), или решены не совсем корректным патчем.
Становится понятно, что в системе должна быть возможность получить ответ на следующие вопросы:
какая кодировка используется для хранения названий файлов в системе?
какая кодировка используется для хранения содержимого файлов?
При этом часто можно слышать мнение, что вопросы эти в общем случае не имеют ответа, и принципиально иметь не могут, а потому не нужно и невозможно пытаться на них ответить.
По большому счёту ситуацию практически исправляет (если полностью забыть о совместимости) полный перевод системы на кодировку UTF-8. К сожалению, даже при этом возникнет ряд проблем (см. Проблемы Перехода На UTF 8)
Но вопросы совместимости никто не отменял и в любом случае порядок взаимодействия как с другими операционными системами (Windows, DOS, MAC), так и с Unix-подобными операционными системами должен быть установлен и сформулирован. Особенно это важно для дистрибутива.
При (возможно, беглом) рассмотрении кода таких проектов как WINE, Linux kernel, gettext, LyX, GLIBC, GLIB, mount, submount, cdrtools, zip, dia, beep, xmms были сформулированы требования и создана реализация библиотеки, которая позволяет получать ответы на вопросы о кодировках, а также имеет ряд вспомогательных функций, востребованных во многих проектах.
Зачем она нужна
Существует множество программ, тесно работающие с кодировками, но по объективным обстоятельствам идущие своим путём в их поддержке. Чего стоит только поддержка перекодирования, встроенная в mkisofs, и использующая nls, выдранный из ядра Linux неизвестно какой версии.
Данный проект создан для того, чтобы решать большинство вопросов, связанных с перекодированием, вне конкретной программы. Это повышает переносимость, и позволяет не отвлекаться конкретному проекту на написание костылей для решения общесистемных проблем. Проект не является серебряной пулей или панацеей, это всего лишь средство повысить переносимость данных между разными системами, и облегчить жизнь пользователей и программистов на текущем переходном этапе, когда всё прогрессивное человечество одной ногой перешло в UTF-8 (нет, эта аббревиатура не относится к НЛО или гробам).
Централизация очень важна в данной ситуации. Множество программ копирует один и тот же (как дословный, так и аналогичный по функциональности) код, причём проблема редко когда решается в целом, обычно предлагаются частные решения. Использование библиотеки, в которой сосредоточено решение проблемы, позволит большому количеству проектов не отвлекаться на решение проблем взаимодействия, перекодировки.
Как она устроена
Библиотека LIBNATSPEC определяет такие важные понятия, как
кодировка локальной файловой системы (filename encoding) — это кодировка названий файлов, с которыми ведётся работа в данном процессе;
системная локаль (system locale) — локаль, установленная базовой для всей системы, действует по умолчанию;
пользовательская локаль (user locale) — локаль, установленная для данного пользователя (обычно задана в ~/.i18n и хранится в переменной LANG)
текущая локаль (current locale) — локаль, действующая для данного процесса (обычно соответствует user locale, но если та не задана, или имеет значение POSIX или C, используется значение system locale);
кодировка текущей локали (charset) — кодировка, принятая для использования в локали, являющейся текущей;
кодировка (charset) и кодовая таблица (codepage) иных операционных систем (WIN, DOS, MAC) для заданной локали (это работает корректно только при соответствии поддерживаемых локалей в LIBNATSPEC и GLIBC)
и предоставляет API для их использования, а также дополнительные функции, позволяющие:
дополнить параметры монтирования указанием кодировок в соответствии с типом файловой системы
преобразовывать строки из одной кодировки в другую с транслитерацией при необходимости (для целей отображения информации пользователю в ситуациях, когда его локаль не позволяет воспроизвести все используемые символы)
Принцип построения: Вся получаемая из библиотеки информация по возможности зависит от текущей локали (current locale). Предложенное в natspec автоматическое указание кодировок монтирования выставляет автоопределённые значения по умолчанию. НИКТО НЕ ОТМЕНЯЛ возможность задать кодировку вручную. Просто умолчание становится не то, которое вкомпилировано в ядро, или просто iso-8859–1, а то, которое положено по локали.
Базой для эвристики является таблица, получаемая примерно по следующему алгоритму: по списку локалей, установленных с glibc, имеющейся в локали информации об основной кодировке, используя программу, получающую информацию о соответствии кодировок различных ОС из WINE, формируется статический массив, который используется в данной библиотеке для определения кодировки по локали и пр.
Библиотека написана на языке C с учётом максимально возможной переносимости. В настоящий момент для сборки требуется glibc и libpopt (для консольной части).
Проводилось тестирование на различных операционных системах, в том числе на популярных ветвях GNU/Linux, FreeBSD, SunOS, OS X
Имеются интерфейсы для других языков:
python
Для использования в скриптах имеется консольная программа, позволяющая получать определённые библиотекой параметры. Например
$ natspec -f – показать кодировку файловой системы
$ natspec -i – вывести всю доступную информацию (просьба посмотреть и высказать свои замечания по качеству определения ситуации на вашей машине)
(для полного списка см. natspec -h)
Вот пример вывода на системе Mandriva Linux:
Для определения системной локали используется обращение к файлу, в котором она хранится. Для redhat-based систем это /etc/sysconfig/i18n. Подробнее см. файл get_locale.c исходного текста.
Где скачать и как ознакомиться
Библиотека опубликована на sourceforge.net: http://sourceforge.net/projects/natspec
В собранном для ALT Linux виде библиотека доступна в свободном репозитории пакетов Сизиф, в backports для ALT Linux Master 2.4.
Также на следующих ресурсах всегда выложены последние версии библиотеки:
С любыми вопросами можно обращаться по адресу, указанному в файле README проекта. Мы будем рады помочь собрать эту библиотеку для вашего дистрибутива.
Как использовать
В каталоге examples проекта лежат исправленные файлы и образцы патчей, решающих проблему с кодировками для ряда программ. Возможно в вашей системе эти патчи ещё не применены, или они не внесены в основную ветвь разработки программы.
В natspec.h описана каждая функция. Если что-то непонятно или надо улучшить – пишите.