Статическая компиляция libmagic (определение типа файла c/ C++)

Спасибо ребятам, которые помогли мне с моим предыдущим вопросом (ссылка только для справки).

Я могу разместить файлы fileTypeTest.cpp, libmagic.a, а также magic в каталоге, и я могу скомпилировать с g++ -lmagic fileTypeTest.cpp fileTypeTest, Позже я буду тестировать, чтобы увидеть, работает ли он в Windows, скомпилированной с MinGW.

Я планирую использовать libmagic в небольшом приложении с графическим интерфейсом, и я хотел бы скомпилировать его статически для распространения. Моя проблема в том что libmagic кажется, требует внешнего файла, magic, (На самом деле я использую свою сокращенную и скомпилированную версию magic_short.mgc, но я отвлекся.)

Хакерским решением было бы закодировать файл в приложение, создав (и удалив) внешний файл по мере необходимости. Как я могу избежать этого?

добавлено для ясности:

magic текстовый файл, описывающий свойства разных типов файлов Когда его попросят идентифицировать файл, libmagic ищет через magic, Есть скомпилированная версия, magic.mgc это работает быстрее. Моему приложению нужно только определить несколько типов файлов, прежде чем решить, что с ними делать, поэтому я буду использовать свой собственный magic_short файл для создания magic_short.mgc,

3 ответа

Решение

Это сложно, я полагаю, вы могли бы сделать это таким образом... кстати, я скачал источник libmagic и смотрю на него...

Там есть функция под названием magic_read_entries в пределах minifile.c (это чистый ванильный источник, который я скачал из sourceforge, где он читает из внешнего файла.

Вы можете добавить magic файл (который находится в каталоге /etc) до конца кода библиотеки, например cat magic >> libmagic.a, В моей системе magic 474443 байт, libmagic.a 38588 байт.

в magic.c файл, вам нужно будет изменить magichandle_t* magic_init(unsigned flags) функция, в конце функции, добавьте строку magic_read_entries и измените саму функцию для чтения по смещению самой библиотеки, чтобы получить данные, обработать ее как указатель на указатель на char (char **) и использовать его вместо чтения из файла. Поскольку вы знаете, где находится смещение данных библиотеки для чтения, это не должно быть сложным.

Теперь функция magic_read_entries больше не будет использоваться, так как больше не будет считываться из файла. Функция `magichandle_t* magic_init(unsigned flags)'позаботится о загрузке записей, и с вами все будет в порядке.

Если вам нужна дополнительная помощь, дайте мне знать,

Редактировать: я использовал старый 'libmagic' с sourceforge.net и вот что я сделал:

  1. Извлеките загруженный архив в мой домашний каталог, разархивировав / распаковав архив создаст папку с именем libmagic.
  2. Создайте папку в libmagic и назовите ее Test
  3. Скопируйте оригинальный magic.c и minifile.c в Test
  4. Используя вложенный вывод diff, подчеркивающий разницу, примените его к источнику magic.c.
48a49,51> #define MAGIC_DATA_OFFSET 0x971C> #define MAGIC_STAT_LIB_NAME "libmagic.a"> 125a129,130> / * magic_read_entries устарел... */
>       magic_read_entries(mh, MAGIC_STAT_LIB_NAME);
251c256,262 <--->>       if (! Fseek(fp, MAGIC_DATA_OFFSET, SEEK_SET)){
>               if (ftell(fp)!= MAGIC_DATA_OFFSET) вернуть 0;
>       }else{
>               return 0;
>       }
> 
  • Тогда выпустите марку
  • Волшебный файл (который я скопировал из /etc под Slackware Linux 12.2) объединяется с файлом libmagic.a, т.е. cat magic >> libmagic.a, Контрольная сумма SHA для магии (4abf536f2ada050ce945fbba796564342d6c9a61 magic), вот точные данные для магии (-rw-r -r-- 1 корневой корень 474443 2007-06-03 00:52 /etc/file/magic), найденные на моем система.
  • Вот diff для источника minifile.c, примените его и пересоберите исполняемый файл minifile, снова запустив make.
40c40
 /*magic_read_entries(mh,"magic");*/

Это должно работать тогда. Если нет, вам нужно будет скорректировать смещение в библиотеке для чтения, изменив MAGIC_DATA_OFFSET. Если хочешь, я могу вставить волшебный файл данных в pastebin. Дай мне знать.

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

Я могу рассказать вам, как скомпилировать библиотеку статически - вы просто передаете путь к файлу.a в конце вашей команды g++ - файлы.a являются просто архивами скомпилированных объектов (.o). Использование "ldd fileTypeTest" покажет вам динамически связанные библиотеки - ${libdir}/libmagic.so не должно быть в нем.

Что касается связывания во внешнем файле данных... Я не знаю - Вы не можете упаковать приложение (.deb|.rpm|.tar.bz2)? На окнах я бы написал установщик с помощью NSIS.

В прошлом я создавал самораспаковывающиеся архивы. По сути, это файл.exe, состоящий из архива.zip и кода для его распаковки. скачайте.exe, запустите его и poof! Вы можете иметь столько файлов, сколько хотите.

http://en.wikipedia.org/wiki/Self-extracting_archive

Другие вопросы по тегам