en
ru
SF.net Project Page
Download
Forums
anysurrect-plugins
Section: C Library Functions (3)
Updated: 27 July 2007
Index
НАЗВАНИЕ
anysurrect-plugins - плагины для anysurrect позволяют распознавать и восстанавливать дополнительные форматы помимо "вшитых" в него самого. В руководстве описаны макросы и функции полезные при программировании новых функций распознавания форматов.
СИНТАКСИС
#include <anysurrect.h>
SKIP_STRING(const char *name, any_off_t len);
SKIP_BYTE(const char *name);
SKIP_SHORT(const char *name);
SKIP_BESHORT(const char *name);
SKIP_LESHORT(const char *name);
SKIP_LONG64(const char *name);
SKIP_BELONG64(const char *name);
SKIP_LELONG64(const char *name);
SKIP_LONG(const char *name);
SKIP_BELONG(const char *name);
SKIP_LELONG(const char *name);
COND_STRING(const char *name, size_t len, CONDITION);
EX_STRING(const char *name, const char *string);
LIST_STRING(const char *name, size_t len
, {const char string_1[len+1], const char
string_2[len+1], ..., NULL} );
uint32_t READ_BELONG64(const char *name);
uint32_t COND_BELONG64(const char *name, CONDITION);
EX_BELONG64(const char *name, uint32_t value);
uint32_t READ_BELONG(const char *name);
uint32_t COND_BELONG(const char *name, CONDITION);
EX_BELONG(const char *name, uint32_t value);
uint16_t READ_BESHORT(const char *name);
uint16_t COND_BESHORT(const char *name, CONDITION);
EX_BESHORT(const char *name, uint16_t value);
uint32_t READ_LELONG64(const char *name);
uint32_t COND_LELONG64(const char *name, CONDITION);
EX_LELONG64(const char *name, uint32_t value);
uint32_t READ_LELONG(const char *name);
uint32_t COND_LELONG(const char *name, CONDITION);
EX_LELONG(const char *name, uint32_t value);
uint16_t READ_LESHORT(const char *name);
uint16_t COND_LESHORT(const char *name, CONDITION);
EX_LESHORT(const char *name, uint16_t value);
uint8_t READ_BYTE(const char *name);
uint8_t COND_BYTE(const char *name, CONDITION);
EX_BYTE(const char *name, uint8_t value);
FUNCOVER(name, operation);
MAYBE(operation);
int read_byte(uint8_t *value);
int read_beshort(uint16_t *value);
int read_belong(uint32_t *value);
int read_belong64(uint32_t *value);
int read_leshort(uint16_t *value);
int read_lelong(uint32_t *value);
int read_lelong64(uint32_t *value);
any_off_t fd_seek(any_off_t offset, int whence);
any_size_t fd_size();
any_ssize_t fd_read(void *buf, any_size_t count);
char* <file_format>_surrect();
void* <file_format>_parseopts(const int argc, const char* argv[]);
void* <file_format>_usage();
const char* <file_format>_indicator=<short_format_name>;
const int <file_format>_text=1;
const mode_t <file_format>_mode=<mode>;
const char* <file_format>_opts=<module_name>;
ОПИСАНИЕ
Вы всегда можете написать модуль для
anysurrect
для распознавания новых форматов, и загружать его опцией
-g.
Ниже будут описаны функции полезные при написании таких модулей.
НЕОБХОДИМЫЕ ОБЪЯВЛЕНИЯ ДЛЯ МОДУЛЯ
- char* <file_format>_surrect();
-
Именно такой тип и имя должна иметь функция распознавания формата. В случае успешного распознавания формата функция должна возвращать строку -- путь к каталогу в который будет помещён данный файл. Например:
audio/MIDI
для MIDI-файлов. Указатель чтения устанавливаемый функцией
fd_seek()
(см. ниже) должен при этом указывать на конец найденного файла. В случае неудачи -- функция должна возвратить NULL.
- void* <file_format>_parseopts(const int argc, const char* argv[]);
-
Функция для разбора опций модуля, вызываемая если найдены опции передаваемые
соответствующему модулю (см.
<file_format>_opts
)
При этом номер первой опции модуля передаётся в глобальной переменной
optind
(она устанавливается библиотечной функцией
getopt)
Ожидается что после разбора функция установит соответствующее значение
optind
для указания окончания опций этого модуля.
- void* <file_format>_usage();
-
Функция справки модуля. Вызывается при указании anysurrect'у опции
-H.
- const char* <file_format>_indicator=<short_format_name>;
-
Короткое имя для индикатора в строке прогресса. Если данного объявления для формата обнаружено не будет, то будет использоваться указатель по умолчанию "UNKNOWN".
- const int <file_format>_text=1;
-
Опциональное объявление полезное для текстовых форматов, таких как
text_ASCII, text_EIGTH_BIT, text_UTF8, text_UTF16BE и
text_UTF16LE.
Дело в том, что в случае, если попадается очень длинная последовательность текстовых символов (но не текста), то дойдя до конца них, обработчик текстовых форматов понимает, что это не текстовый формат, но после этого
anysurrect
снова вызывает его для следующего блока, т.е. для того же текста и обработчик опять пробегает почти по всему этому тексту, чтобы понять, что это не текст (ведь, у текстов нет никаких магических последовательностей в начале файла -- что ты смотришь с начала файла, что с середины -- с точки зрения обработчика тесктовых форматов -- всё это такой же текст). Но на каждый такой вызов уходит много времени (так как, последовательность текстовых символов может быть очень длинной), а для многих таких вызовов и вовсе вечность. Для экономии времени, служит это объявление, которое говорит
anysurrect,
что даже, если обработчик формата возвратил
NULL
стоит посмотреть на указатель
fd_seek
и не вызывать более этот обработчик до окончания этого блока очень похожего на текст.
- const mode_t <file_format>_mode=<mode>;
-
По умолчанию восстановленные файлы имеют маску режима доступа 0666. Данное опциональное объявление может изменить режим доступа для файлов вашего типа. Так, например, для файлов формата ELF32 используется следующее объявление:
const mode_t executable_ELF32_mode=0777;
- const char* <file_format>_opts=<module_name>;
-
Короткое название модуля для передачи ему опций из командной строки
anysurrect
ФУНКЦИИ ЧТЕНИЯ ФАЙЛА
При написании модуля обработчика файла, вам не нужно использовать функции чтения из файла устройства, напрямую.
anysurrect
сам открывает устройство, сам перемещает указатель чтения на некоторое предполагаемое начало файла и лишь потом вызывает обработчик формата. Более того,
anysurrect
может "подставлять" блоки для чтения обработчику формата не в том порядке, котором они лежат на устройстве -- он может пропускать блоки, которые уже заняты другими файлами (описание, которых взято из загруженной с помощью опции
-i
внешней таблицы инф.узлов). Используйте следующие функции чтения из файла и не задумывайтесь о том, что на самом деле на устройстве может быть что-то до вашего файла, но обязательно думайте о том, что на нём есть что-то после -- вам нужно вовремя остановиться при достижении конца файла.
- any_off_t fd_seek(any_off_t offset, int whence);
-
Функция аналогичная
lseek64
за тем исключением что не имеет аргумента файлового дескриптора --
anysurrect
уже знает откуда читать.
- any_size_t fd_size();
-
Возвращает максимальный размер файла, который сможет в конечном итоге возвратить обработчик формата.
- any_ssize_t fd_read(void *buf, any_size_t count);
-
Аналогично
read(2)
за тем исключением что не имеет аргумента файлового дескриптора --
anysurrect
уже знает откуда читать.
- int read_byte(uint8_t *value);
-
Считывает 1 байт в буфер, на который указывает
value.
Возвращает 0 при удаче и 1 -- при неудаче.
- int read_beshort(uint16_t *value);
-
Считывает значение типа
uint16_t
(2 байта) в буфер, на который указывает
value,
считая что старший байт на диске хранится впереди (т.е. значение сохранено в Big Endian формате). Возвращает 0 при удаче и 1 -- при неудаче.
- int read_belong(uint32_t *value);
-
Считывает значение типа
uint32_t
(4 байта) в буфер, на который указывает
value,
считая что старший байт на диске хранится впереди (т.е. значение сохранено в Big Endian формате). Возвращает 0 при удаче и 1 -- при неудаче.
- int read_belong64(uint64_t *value);
-
Считывает значение типа
uint64_t
(8 байт) в буфер, на который указывает
value,
считая что старший байт на диске хранится впереди (т.е. значение сохранено в Big Endian формате). Возвращает 0 при удаче и 1 -- при неудаче.
- int read_leshort(uint16_t *value);
-
Считывает значение типа
uint16_t
(2 байта) в буфер, на который указывает
value,
считая что младший байт на диске хранится впереди (т.е. значение сохранено в Little Endian формате). Возвращает 0 при удаче и 1 -- при неудаче.
- int read_lelong(uint32_t *value);
-
Считывает значение типа
uint32_t
(4 байта) в буфер, на который указывает
value,
считая что младший байт на диске хранится впереди (т.е. значение сохранено в Little Endian формате). Возвращает 0 при удаче и 1 -- при неудаче.
- int read_lelong64(uint64_t *value);
-
Считывает значение типа
uint64_t
(8 байт) в буфер, на который указывает
value,
считая что младший байт на диске хранится впереди (т.е. значение сохранено в Little Endian формате). Возвращает 0 при удаче и 1 -- при неудаче.
МАКРОСЫ ЧТЕНИЯ ФАЙЛА
Макросы для чтения файла были созданы для упрощения программирования обработчиков форматов и увеличения читабельности их кода. Любой из этих макросов может НЕ возвратить управления следующей инструкции функции в связи с неудачей, невыполнением указанного условия. При этом функция возвратит значение
ERROR_VALUE.
- const char *name
-
Аргумент
name
во всех этих макросах -- это некоторая строка, описывающая считываемое, проверяемое или пропускаемое инструкцией поле файла. Если хотите, то это такие обязательные комментарии кода.
- SKIP_STRING(const char *name, any_off_t len);
-
это обёртка для инструкции типа
fd_seek(len, SEEK_CUR);
с проверкой выхода за границу
fd_size().
- SKIP_*
-
Другие макросы для пропуска полей различных типов. Они аналогичны
SKIP_STRING
за тем исключением, что длина пропускаемого поля определяется самим типом пропускаемого поля, а не передаётся макросу вторым аргументом.
- COND_STRING(const char *name, size_t len, CONDITION);
-
Считывает строку длиной
len
и проверяет её на условие
CONDITION.
Условие здесь -- это некоторое выражение с использованием переменной
val,
в которую будет помещено значение строки.
- EX_STRING(const char *name, const char *string);
-
Считывает строку и проверяет его на совпадение со строкой
string.
Аналогично вызову:
COND_STRING(name, strlen(string), strcmp(val, string)==0);
- LIST_STRING(const char *name, size_t len, {const char string_1[len+1], const char string_2[len+1], ..., NULL} );
-
Считывает строку длиной
len
и проверяет её на совпадение с одной из строк в списке (список должен быть помещён в фигурные скобки, состоять из строк длиной
len
и заканчиваться
NULL)
- READ_*
-
Макросы -- обёртки для соответствующих функций
read_*
с выходом при неудаче. В отличии от функций, они не принимают указателя на буфер, а возвращают это считанное значение непосредственно в программу.
- COND_*
-
Макросы для чтения из файла различных значений с проверкой на выполнение условия.
CONDITION
в них -- это некоторое выражение с использованием переменной
val,
в которую будет помещено значение переменной перед возвращением его в программу.
- EX_*
-
Макросы для чтения из файла различных значений с проверкой на строгое равенство нужному значению. Аналогичны вызову:
COND_*(name, val==value);
Вообще говоря они имеют возвращаемым значением, считанное значение, но в связи с проводимой проверкой -- если эти макросы возвращают управление программе, то возвращаемое значение всегда равно
value.
- FUNCOVER(name, operation);
-
Все вышеприведённые макросы вовсе не возвращают управления программе в случае неудачи чтения или невыполнении указанного условия, но часто при невыполнении условия не нужно сразу выходить из функции обработки формата -- нужно сделать что-то ещё. В этом случае пригодиться этот макрос. Он помещает операцию (группу операций) в функциональную обёртку:
int name() { operation; return !ERROR_VALUE; }
которая в случае успеха возвращает
!ERROR_VALUE
А в случае не успеха:
ERROR_VALUE
- MAYBE(operation);
-
Используя макрос
FUNCOVER
мы можем теперь получить управление назад в функцию не зависимо от успеха любых проверок, но при этом указатель
fd_seek
окажется сбитым -- помещённым после всех неудачно считанных значений. Поэтому макрос
MAYBE
запоминает указатель
fd_seek,
выполняет операцию
operation
и в случае возвращения ею
ERROR_VALUE
она перемещает указатель
fd_seek
обратно на позицию до начала выполнения операции. Само возвращаемое значение передаётся назад в программу без изменений.
ПРИМЕРЫ МОДУЛЯ ОБРАБОТКИ ФОРМАТА
Простейшими примерами модуля обработки формата пожалуй будут являться функции обработки форматов
MIDI и RAR
Их описание можно найти на
http://www.wotsit.org.
А функции такие какими их можно найти в исходниках
anysurrect
приведены ниже:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <anysurrect.h>
/*MIDI*/
const char* audio_MIDI_indicator="MIDI";
char *audio_MIDI_surrect()
{
int res;
unsigned short number_tracks;
EX_STRING("header", "MThd");
EX_BELONG("magic_number", 0x00000006);
COND_BESHORT("FileFormat", val<=2);
number_tracks =
READ_BESHORT("NumberTracks");
SKIP_BESHORT("ticks_per_note");
for (int i=0; i<number_tracks; i++)
{
unsigned long size;
EX_STRING("track_header", "MTrk");
size = READ_BELONG("track_size");
SKIP_STRING("track_body", size);
}
return "audio/MIDI";
}
/*RAR*/
const char* archieve_RAR_indicator="RAR";
#define RAR_BLOCK ({ \
SKIP_LESHORT("crc"); \
COND_BYTE("type", val>=0x72 && val<=0x7F); \
uint16_t flags = READ_LESHORT("flags"); \
uint16_t size = READ_LESHORT("size"); \
uint32_t add_size=0; \
if (flags&0x8000) \
{ add_size=READ_LELONG("add_size")-4; } \
SKIP_STRING("data", add_size + size - 7); \
})
FUNCOVER(rar_block, RAR_BLOCK);
char *archieve_RAR_surrect()
{
int res;
EX_LESHORT("crc", 0x6152);
EX_BYTE("type", 0x72);
EX_LESHORT("flags", 0x1a21);
EX_LESHORT("size", 0x0007);
while( MAYBE( rar_block() )!=ERROR_VALUE );
return "archieve/RAR";
}
Собрать данную программу можно примерно следующей командой:
$ gcc -std=gnu99 -nostdlib -shared -I /usr/local/include/anyfs-tools -o anysurrect_plug-in.so anysurrect_plug-in.c
После чего можно подключить и просмотреть экспортируемые этим модулем форматы можно следующим образом:
$ /usr/local/sbin/anysurrect -g ./anysurrect_plug-in.so -l
anysurrect 0.84.5 (06 Aug 2006)
FILE SURRECTERS EXPORTED BY "anysurrect" MODULE:
archieve_BZIP2 archieve_RAR archieve_TAR archieve_ZIP audio_MIDI audio_MP3 audio_video_AVI audio_video_MPEG12PM audio_video_MPEG12 audio_video_OGG audio_WAV document_PDF executable_ELF32 filesystem_info_ext2fs_direct_blocks_links filesystem_info_ext2fs_double_indirect_blocks_links filesystem_info_ext2fs_indirect_blocks_links image_BMP image_JPEG image_PNG image_PNM image_TIFF text_ASCII text_EIGHT_BIT text_UTF16BE text_UTF16LE text_UTF8
FILE SURRECTERS EXPORTED BY "anysurrect_plug-in.so" MODULE:
archieve_RAR audio_MIDI
Так как названия обработчиков форматов archieve_RAR и audio_MIDI в
anysurrect
и полученном модуле совпадают, то при попытке запуска восстановления первыми найденными и используемыми окажутся, обработчики встроенные в
anysurrect.
А потому не надо писать обработчиков форматов совпадающих по названию со встроенными в
anysurrect
обработчиками.
АВТОР
Николай Кривченков aka unDEFER <undefer@gmail.com>
СООБЩЕНИЯ ОБ ОШИБКАХ
Сообщения о любых проблемах с применением пакета
anyfs-tools
направляйте по адресу:
undefer@gmail.com
ДОСТУПНОСТЬ
последнюю версию пакета вы можете получить на сайте проекта: http://anyfs-tools.sourceforge.net
СМ. ТАКЖЕ
anyfs-tools(8),
anysurrect(8),
lseek(2),
read(2)
Index
- НАЗВАНИЕ
-
- СИНТАКСИС
-
- ОПИСАНИЕ
-
- НЕОБХОДИМЫЕ ОБЪЯВЛЕНИЯ ДЛЯ МОДУЛЯ
-
- ФУНКЦИИ ЧТЕНИЯ ФАЙЛА
-
- МАКРОСЫ ЧТЕНИЯ ФАЙЛА
-
- ПРИМЕРЫ МОДУЛЯ ОБРАБОТКИ ФОРМАТА
-
- АВТОР
-
- СООБЩЕНИЯ ОБ ОШИБКАХ
-
- ДОСТУПНОСТЬ
-
- СМ. ТАКЖЕ
-
This document was created by
man2html (from man 1.5o1),
using the manual pages.
Time: 21:52:22 GMT, August 16, 2008