Skip to content

Instantly share code, notes, and snippets.

@w495
Created June 1, 2012 16:00
Show Gist options
  • Save w495/2853187 to your computer and use it in GitHub Desktop.
Save w495/2853187 to your computer and use it in GitHub Desktop.
Пример использования библиотеки libmagic
/**
@file magic_buffer.c
Пример использования библиотеки libmagic.
Ниже показано как собирать и тестировать файл:
$> gcc magic_buffer.c -lmagic -I/usr/include/magic -Wall -o magic_buffer
$>./magic_buffer "asas" 2> errr
text/plain
$>./magic_buffer "<?xml version="1.0" encoding="utf-8"?><x>абырвалг</x>"
application/xml
$>./magic_buffer "<?xml"
application/xml
$>./magic_buffer "<?xm"
text/plain
$>./magic_buffer ""
application/x-empty
$>./magic_buffer "FLV �"
video/x-flv
Пример распространяется по GPL лицензии.
**/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <magic.h>
/**
@fn new_magic
Создает новое отображение.
Если не может ничего создать
и загрузить базу данных символов,
то останваливает выполнения программы.
@param void
@return magic_t преобразователь
**/
magic_t new_magic(void);
/**
@fn buffer
Отвечает на вопрос, каков тип переданных данных.
Для данного буфера данных
(представленного строкой) возвращает результат отображения.
@param magic отображение
@param buffer набор данных, которые требуется отобразить
@return const char*
ответ преобразователя
**/
const char* buffer(magic_t magic, const char* buffer);
/**
@fn free_magic
Освобождает ресурсы,
созданные для отображения
@param magic отображение
@return void
**/
void free_magic(magic_t magic);
int main(int argc, char* argv[], char* env[])
{
magic_t magic = new_magic();
if(2 != argc){
fprintf(stderr, "USAGE: %s \"<data>\"\n", argv[0]);
return 1;
}
printf("%s\n", buffer(magic, argv[1]));
free_magic(magic);
return 0;
}
/*
@fn new_magic
Создает новое отображение.
Если не может ничего создать
и загрузить базу данных символов,
то останваливает выполнения программы.
@param void
@return magic_t преобразователь
*/
magic_t new_magic(void){
/*
Ниже создаем magic.
Если указать не MAGIC_MIME_TYPE, MAGIC_MIME,
то даже правильно определит кодировку.
*/
magic_t magic = magic_open(MAGIC_MIME_TYPE);
if (NULL == magic) {
fprintf(stderr, "unable to initialize magic library\n");
exit(1);
}
/*
Загружает базу данных по умолчанию
*/
if (0 != magic_load(magic, NULL)) {
fprintf(stderr, "cannot load magic database - %s\n", magic_error(magic));
magic_close(magic);
exit(1);
}
return magic;
}
/*
@fn buffer
Отвечает на вопрос, каков тип переданных данных.
Для данного буфера данных
(представленного строкой) возвращает результат отображения.
@param magic отображение
@param buffer набор данных, которые требуется отобразить
@return const char*
ответ преобразователя
*/
const char* buffer(magic_t magic, const char* buffer){
return magic_buffer(magic, buffer, strlen(buffer));
}
/*
@fn free_magic
Освобождает ресурсы,
созданные для отображения
@param magic отображение
@return void
*/
void free_magic(magic_t magic){
magic_close(magic);
}
@w495
Copy link
Author

w495 commented Jun 1, 2012

Подобные вещи могут очень сильно пригодиться в веб-приложениях. Например для проверки содержимого загружаемых файлов. Использовать предполагается через open_port в erlang, Нужно только сделать пул мертвых циклов с вызовом buffer.
Если я где-то не прав скажите, пожалуйста, я на сях давно не писал.

@piroman-lynx
Copy link

Огромное спасибо за пример!

Заодно забавный баг нашел в механизме libmagic - если определить magic_t magic; как свойство объекта (c++), не важно - приватное или публичное - библиотека падает в coredump, gdb показывает что стектрейс уходит внутрь libmagic из вызова magic_buffer.
Не стал разбиратся я не прав (может стоило определять как magic_t *magic и делать new magic) или косяк в libmagic . Не знаете куда можно отписать bugreport об этой проблеме?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment