New API call iso_file_add_zisofs_filter() (needs -lz and <zlib.h>).

This does not produce ZF entries yet but filtered file content already
suits mkzftree -uF
This commit is contained in:
Thomas Schmitt 2009-04-09 16:18:50 +02:00
parent 5732726a27
commit a809a87eef
8 changed files with 1067 additions and 302 deletions

View File

@ -14,9 +14,9 @@ lib_LTLIBRARIES = libisofs/libisofs.la
libisofs_libisofs_la_LDFLAGS = \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
# ts A90123 : Eventually enabling system adapters for ACL and EA
libisofs_libisofs_la_CFLAGS = $(LIBACL_DEF) $(XATTR_DEF)
# Eventually enabling system adapters for ACL and EA.
# ts A90409: Eventually enabling use of zlib.
libisofs_libisofs_la_CFLAGS = $(LIBACL_DEF) $(XATTR_DEF) $(ZLIB_DEF)
# ts A90114 : added aaip_0_2.*
@ -44,6 +44,7 @@ libisofs_libisofs_la_SOURCES = \
libisofs/filter.c \
libisofs/filters/xor_encrypt.c \
libisofs/filters/external.c \
libisofs/filters/zisofs.c \
libisofs/util.h \
libisofs/util.c \
libisofs/util_rbtree.c \

View File

@ -183,6 +183,22 @@ fi
AC_SUBST(XATTR_DEF)
dnl ts A90409
AC_ARG_ENABLE(zlib,
[ --enable-zlib Enable use of zlib by libisofs, default=yes],
, enable_zlib=yes)
if test x$enable_zlib = xyes; then
dnl Check whether there is the header for zlib.
dnl If not, erase this macro which would enable use of compress2() and others.
dnl The empty parameter after "compress2" causes -lz.
ZLIB_DEF="-DLibisofs_with_zliB"
AC_CHECK_HEADER(zlib.h, AC_CHECK_LIB(z, compress2, , ZLIB_DEF= ), ZLIB_DEF= )
else
ZLIB_DEF=
fi
AC_SUBST(ZLIB_DEF)
AC_CONFIG_FILES([
Makefile
doc/doxygen.conf

View File

@ -39,18 +39,21 @@ array tells the start of the next block which begins immediately after the
end of its predecessor. A final pointer gives the first invalid byte address
and thus marks the end of the last block.
The block pointers are stored as an array of 4-byte values which are in ISO
9660:7.3.1 format directly after the file header, i.e. beginning at byte 16.
So there are ceil(input_size / block_size) + 1 block pointers.
They are stored as an array of 4-byte values which are in ISO 9660:7.3.1 format
directly after the file header, i.e. beginning at byte 16.
Data Part
The data part begins immediately after the pointer array. In principle it
consists of the variable length output blocks as delivered by zlib function
compress2() when fed with the fixed size input blocks.
A special case of input and output block is defined:
- Zero-length blocks represent a block full of 0-bytes.
They do not get processed by compress2() but have to be implemented as
bypass of compress2().
Zero-length blocks represent a block full of 0-bytes.
Such input blocks do not get processed by compress2() but shall be mapped to
0-sized output directly. Vice versa 0-sized blocks have to bypass uncompress()
when being read.
ZF System Use Entry Format
@ -116,6 +119,9 @@ References:
zisofs-tools
http://freshmeat.net/projects/zisofs-tools/
zlib:
/usr/include/zlib.h
cdrtools with mkisofs
ftp://ftp.berlios.de/pub/cdrecord/alpha
@ -128,6 +134,3 @@ SUSP 1.12
RRIP 1.12
ftp://ftp.ymi.com/pub/rockridge/rrip112.ps
zlib:
/usr/include/zlib.h

View File

@ -21,6 +21,8 @@
/* libisofs/filters/external.c */
#define ISO_FILTER_EXTERNAL_DEV_ID 2
/* libisofs/filters/zisofs.c */
#define ISO_FILTER_ZISOFSL_DEV_ID 3
typedef struct filter_context FilterContext;

View File

@ -655,7 +655,7 @@ int extf_filter_get_filter(FilterContext *filter, IsoStream *original,
return ISO_OUT_OF_MEM;
}
data = malloc(sizeof(ExternalFilterStreamData));
if (str == NULL) {
if (data == NULL) {
free(str);
return ISO_OUT_OF_MEM;
}

684
libisofs/filters/zisofs.c Normal file
View File

@ -0,0 +1,684 @@
/*
* Copyright (c) 2009 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. See COPYING file for details.
*
* It implements a filter facility which can pipe a IsoStream into zisofs
* compression resp. uncompression, read its output and forward it as IsoStream
* output to an IsoFile.
* The zisofs format was invented by H. Peter Anvin. See doc/zisofs_format.txt
* It is writeable and readable by zisofs-tools, readable by Linux kernels.
*
*/
#include "../libisofs.h"
#include "../filter.h"
#include "../fsource.h"
#include "../util.h"
#include <sys/types.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#ifdef Libisofs_with_zliB
#include <zlib.h>
#else
/* If zlib is not available then this code is a dummy */
#endif
/*
* A filter that encodes or decodes the content of zisofs compressed files.
*/
/* --------------------------- ZisofsFilterRuntime ------------------------- */
/* Sizes to be used for compression. Decompression learns from input header. */
#define Libisofs_zisofs_block_log2 15
#define Libisofs_zisofs_block_sizE 32768
/* Individual runtime properties exist only as long as the stream is opened.
*/
typedef struct
{
int state; /* processing: 0= header, 1= block pointers, 2= data blocks */
int block_size;
int block_pointer_fill;
int block_pointer_rpos;
char *read_buffer;
char *block_buffer;
int buffer_size;
int buffer_fill;
int buffer_rpos;
off_t block_counter;
off_t in_counter;
off_t out_counter;
} ZisofsFilterRuntime;
static
int ziso_running_destroy(ZisofsFilterRuntime **running, int flag)
{
ZisofsFilterRuntime *o= *running;
if (o == NULL)
return 0;
if (o->read_buffer != NULL)
free(o->read_buffer);
if (o->block_buffer != NULL)
free(o->block_buffer);
free((char *) o);
*running = NULL;
return 1;
}
/*
* @param flag bit0= do not set block_size, do not allocate buffers
*/
static
int ziso_running_new(ZisofsFilterRuntime **running, int flag)
{
ZisofsFilterRuntime *o;
*running = o = calloc(sizeof(ZisofsFilterRuntime), 1);
if (o == NULL) {
return ISO_OUT_OF_MEM;
}
o->state = 0;
o->block_pointer_fill = 0;
o->block_pointer_rpos = 0;
o->block_size= 0;
o->read_buffer = NULL;
o->block_buffer = NULL;
o->buffer_size = 0;
o->buffer_fill = 0;
o->buffer_rpos = 0;
o->block_counter = 0;
o->in_counter = 0;
o->out_counter = 0;
if (flag & 1)
return 1;
o->block_size = Libisofs_zisofs_block_sizE;
#ifdef Libisofs_with_zliB
o->buffer_size= compressBound((uLong) Libisofs_zisofs_block_sizE);
#else
o->buffer_size= 2 * Libisofs_zisofs_block_sizE;
#endif
o->read_buffer = calloc(o->block_size, 1);
o->block_buffer = calloc(o->buffer_size, 1);
if (o->block_buffer == NULL || o->read_buffer == NULL)
goto failed;
return 1;
failed:
ziso_running_destroy(running, 0);
return -1;
}
/* ---------------------------- ZisofsFilterStreamData --------------------- */
/* The first 8 bytes of a zisofs compressed data file */
static unsigned char zisofs_magic[9] =
{0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07};
/*
* The data payload of an individual Zisofs Filter IsoStream
*/
typedef struct
{
ino_t id;
IsoStream *orig;
off_t size; /* -1 means that the size is unknown yet */
uint32_t orig_size;
uint32_t *block_pointers; /* Cache for output block addresses. They get
written before the data and so need 2 passes.
This cache avoids surplus passes.
*/
ZisofsFilterRuntime *running; /* is non-NULL when open */
} ZisofsFilterStreamData;
/* Each individual ZisofsFilterStreamData needs a unique id number. */
/* >>> This is very suboptimal:
The counter can rollover.
*/
static ino_t ziso_ino_id = 0;
/*
* Methods for the IsoStreamIface of an External Filter object.
*/
/*
* @param flag bit0= original stream is not open
*/
static
int ziso_stream_close_flag(IsoStream *stream, int flag)
{
ZisofsFilterStreamData *data;
if (stream == NULL) {
return ISO_NULL_POINTER;
}
data = stream->data;
if (data->running == NULL) {
return 1;
}
ziso_running_destroy(&(data->running), 0);
if (flag & 1)
return 1;
return iso_stream_close(data->orig);
}
static
int ziso_stream_close(IsoStream *stream)
{
return ziso_stream_close_flag(stream, 0);
}
/*
* @param flag bit0= do not run .get_size() if size is < 0
*/
static
int ziso_stream_open_flag(IsoStream *stream, int flag)
{
ZisofsFilterStreamData *data;
ZisofsFilterRuntime *running = NULL;
int ret;
if (stream == NULL) {
return ISO_NULL_POINTER;
}
data = (ZisofsFilterStreamData*) stream->data;
if (data->running != NULL) {
return ISO_FILE_ALREADY_OPENED;
}
if (data->size < 0 && !(flag & 1)) {
/* Do the size determination run now, so that the size gets cached
and .get_size() will not fail on an opened stream.
*/
stream->class->get_size(stream);
}
ret = ziso_running_new(&running, 0);
if (ret < 0) {
return ret;
}
data->running = running;
ret = iso_stream_open(data->orig);
if (ret < 0) {
return ret;
}
return 1;
}
static
int ziso_stream_open(IsoStream *stream)
{
return ziso_stream_open_flag(stream, 0);
}
static
int ziso_stream_read(IsoStream *stream, void *buf, size_t desired)
{
int ret, todo, i;
ZisofsFilterStreamData *data;
ZisofsFilterRuntime *rng;
size_t fill = 0;
off_t orig_size, next_pt;
char *cbuf = buf;
#ifdef Libisofs_with_zliB
uLongf buf_len;
#else
unsigned long buf_len;
#endif
if (stream == NULL) {
return ISO_NULL_POINTER;
}
data = stream->data;
rng= data->running;
if (rng == NULL) {
return ISO_FILE_NOT_OPENED;
}
while (1) {
if (rng->state == 0) {
/* Delivering file header */
if (rng->buffer_fill == 0) {
memcpy(rng->block_buffer, zisofs_magic, 8);
orig_size = iso_stream_get_size(data->orig);
if (orig_size > 4294967295.0) {
/* >>> cannot compress file >= 4 GiB to zisofs */;
/* <<< need better error code (or fallback strategy ?) */
return ISO_FILE_READ_ERROR;
}
data->orig_size = orig_size;
iso_lsb((unsigned char *) (rng->block_buffer + 8),
(uint32_t) orig_size, 4);
rng->block_buffer[12] = 4;
rng->block_buffer[13] = Libisofs_zisofs_block_log2;
rng->block_buffer[14] = rng->block_buffer[15] = 0;
rng->buffer_fill = 16;
rng->buffer_rpos = 0;
} else if (rng->buffer_rpos >= rng->buffer_fill) {
rng->buffer_fill = rng->buffer_rpos = 0;
rng->state = 1; /* header is delivered */
}
}
if (rng->state == 1) {
/* Delivering block pointers */;
if (rng->block_pointer_fill == 0) {
/* Initialize block pointer writing */
rng->block_pointer_rpos = 0;
rng->block_pointer_fill = data->orig_size / rng->block_size
+ 1 + !!(orig_size % rng->block_size);
if (data->block_pointers == NULL) {
/* On the first pass, create pointer array with all 0s */
data->block_pointers = calloc(rng->block_pointer_fill, 4);
if (data->block_pointers == NULL) {
rng->block_pointer_fill = 0;
return ISO_OUT_OF_MEM;
}
}
}
if (rng->buffer_rpos >= rng->buffer_fill) {
if (rng->block_pointer_rpos >= rng->block_pointer_fill) {
rng->buffer_fill = rng->buffer_rpos = 0;
rng->block_counter = 0;
data->block_pointers[0] = 16 + rng->block_pointer_fill * 4;
rng->state = 2; /* block pointers are delivered */
} else {
/* Provide a buffer full of block pointers */
todo = rng->block_pointer_fill - rng->block_pointer_rpos;
if (todo * 4 > rng->buffer_size)
todo = rng->buffer_size / 4;
memcpy(rng->block_buffer,
data->block_pointers + 4 * rng->block_pointer_rpos,
todo * 4);
rng->buffer_rpos = 0;
rng->buffer_fill = todo * 4;
rng->block_pointer_rpos += todo;
}
}
}
if (rng->state == 2 && rng->buffer_rpos >= rng->buffer_fill) {
/* >>> Delivering data blocks */;
ret = iso_stream_read(data->orig, rng->read_buffer,
rng->block_size);
if (ret > 0) {
rng->in_counter += ret;
if (rng->in_counter > data->orig_size) {
/* >>> Input size overflow */
/* <<< need better error code */
return ISO_FILE_READ_ERROR;
}
/* Check whether all 0 : represent as 0-length block */;
for (i = 0; i < ret; i++)
if (rng->read_buffer[i])
break;
if (i >= ret) { /* All 0-bytes. Bypass compression. */
buf_len = 0;
} else {
buf_len = rng->buffer_size;
#ifdef Libisofs_with_zliB
ret = compress2((Bytef *) rng->block_buffer, &buf_len,
(Bytef *) rng->read_buffer, (uLong) ret, 9);
if (ret != Z_OK) {
#else
{
#endif
/* >>> compression failed */
/* <<< need better error code */
return ISO_FILE_READ_ERROR;
}
}
rng->buffer_fill = buf_len;
rng->buffer_rpos = 0;
next_pt = data->block_pointers[rng->block_counter] + buf_len;
/* >>> check for data->size overflow */;
if (data->size >= 0 && next_pt > data->size) {
/* >>> Compression yields more bytes than on first run */
/* <<< need better error code */
return ISO_FILE_READ_ERROR;
}
/* >>> record resp. check block pointer */;
rng->block_counter++;
if (data->block_pointers[rng->block_counter] > 0) {
/* >>> check */;
if (next_pt != data->block_pointers[rng->block_counter] ) {
/* >>> block pointers mismatch , content has changed */
/* <<< need better error code */
return ISO_FILE_READ_ERROR;
}
} else {
data->block_pointers[rng->block_counter] = next_pt;
}
} else if (ret == 0) {
rng->state = 3;
return fill;
} else
return ret;
if (rng->buffer_fill == 0) {
continue;
}
}
if (rng->state == 3 && rng->buffer_rpos >= rng->buffer_fill) {
return 0; /* EOF */
}
/* Transfer from rng->block_buffer to buf */
todo = desired - fill;
if (todo > rng->buffer_fill - rng->buffer_rpos)
todo = rng->buffer_fill - rng->buffer_rpos;
memcpy(cbuf + fill, rng->block_buffer + rng->buffer_rpos, todo);
fill += todo;
rng->buffer_rpos += todo;
rng->out_counter += todo;
if (fill >= desired) {
return fill;
}
}
return ISO_FILE_READ_ERROR; /* should never be hit */
}
static
off_t ziso_stream_get_size(IsoStream *stream)
{
int ret, ret_close;
off_t count = 0;
ZisofsFilterStreamData *data;
char buf[64 * 1024];
size_t bufsize = 64 * 1024;
if (stream == NULL) {
return ISO_NULL_POINTER;
}
data = stream->data;
if (data->size >= 0) {
return data->size;
}
/* Run filter command and count output bytes */
ret = ziso_stream_open_flag(stream, 1);
if (ret < 0) {
return ret;
}
while (1) {
ret = ziso_stream_read(stream, buf, bufsize);
if (ret <= 0)
break;
count += ret;
}
ret_close = ziso_stream_close(stream);
if (ret < 0)
return ret;
if (ret_close < 0)
return ret_close;
data->size = count;
return count;
}
static
int ziso_stream_is_repeatable(IsoStream *stream)
{
/* Only repeatable streams are accepted as orig */
return 1;
}
static
void ziso_stream_get_id(IsoStream *stream, unsigned int *fs_id,
dev_t *dev_id, ino_t *ino_id)
{
ZisofsFilterStreamData *data;
data = stream->data;
*fs_id = ISO_FILTER_FS_ID;
*dev_id = ISO_FILTER_ZISOFSL_DEV_ID;
*ino_id = data->id;
}
static
void ziso_stream_free(IsoStream *stream)
{
ZisofsFilterStreamData *data;
if (stream == NULL) {
return;
}
data = stream->data;
if (data->running != NULL) {
ziso_stream_close(stream);
}
if (data->block_pointers != NULL) {
free((char *) data->block_pointers);
}
iso_stream_unref(data->orig);
free(data);
}
static
int ziso_update_size(IsoStream *stream)
{
/* By principle size is determined only once */
return 1;
}
static
IsoStream *ziso_get_input_stream(IsoStream *stream, int flag)
{
ZisofsFilterStreamData *data;
if (stream == NULL) {
return NULL;
}
data = stream->data;
return data->orig;
}
IsoStreamIface ziso_stream_class = {
2,
"ziso",
ziso_stream_open,
ziso_stream_close,
ziso_stream_get_size,
ziso_stream_read,
ziso_stream_is_repeatable,
ziso_stream_get_id,
ziso_stream_free,
ziso_update_size,
ziso_get_input_stream
};
static
void ziso_filter_free(FilterContext *filter)
{
/* no data are allocated */;
}
/* To be called by iso_file_add_filter().
* The FilterContext input parameter is not furtherly needed for the
* emerging IsoStream.
*/
static
int ziso_filter_get_filter(FilterContext *filter, IsoStream *original,
IsoStream **filtered)
{
IsoStream *str;
ZisofsFilterStreamData *data;
if (filter == NULL || original == NULL || filtered == NULL) {
return ISO_NULL_POINTER;
}
str = calloc(sizeof(IsoStream), 1);
if (str == NULL) {
return ISO_OUT_OF_MEM;
}
data = calloc(sizeof(ZisofsFilterStreamData), 1);
if (data == NULL) {
free(str);
return ISO_OUT_OF_MEM;
}
/* These data items are not owned by this filter object */
data->id = ++ziso_ino_id;
data->orig = original;
data->size = -1;
data->orig_size = 0;
data->block_pointers = NULL;
data->running = NULL;
/* get reference to the source */
iso_stream_ref(data->orig);
str->refcount = 1;
str->data = data;
str->class = &ziso_stream_class;
*filtered = str;
return ISO_SUCCESS;
}
/* Produce a parameter object suitable for iso_file_add_filter().
* It may be disposed by free() after all those calls are made.
*
* This is quite a dummy as it dows not carry individual data.
*/
static
int ziso_create_context(FilterContext **filter, int flag)
{
FilterContext *f;
*filter = f = calloc(1, sizeof(FilterContext));
if (f == NULL) {
return ISO_OUT_OF_MEM;
}
f->refcount = 1;
f->version = 0;
f->data = NULL;
f->free = ziso_filter_free;
f->get_filter = ziso_filter_get_filter;
return ISO_SUCCESS;
}
/*
* @param flag bit0= if_block_reduction rather than if_reduction
* >>> bit1= Install a decompression filter
*/
int iso_file_add_zisofs_filter(IsoFile *file, int flag)
{
#ifdef Libisofs_with_zliB
int ret;
FilterContext *f = NULL;
IsoStream *stream;
off_t original_size = 0, filtered_size = 0;
original_size = iso_file_get_size(file);
if (original_size <= 0) {
return 2;
}
if (original_size > 4294967295.0) {
return ISO_ZISOFS_TOO_LARGE;
}
ret = ziso_create_context(&f, 0);
if (ret < 0) {
return ret;
}
ret = iso_file_add_filter(file, f, 0);
free(f);
if (ret < 0) {
return ret;
}
/* Run a full filter process getsize so that the size is cached */
stream = iso_file_get_stream(file);
filtered_size = iso_stream_get_size(stream);
if (filtered_size < 0) {
iso_file_remove_filter(file, 0);
return filtered_size;
}
if ((filtered_size >= original_size && !(flag & 1)) ||
filtered_size / 2048 >= original_size / 2048){
ret = iso_file_remove_filter(file, 0);
if (ret < 0) {
return ret;
}
return 2;
}
return ISO_SUCCESS;
#else
return ISO_ZLIB_NOT_ENABLED;
#endif /* ! Libisofs_with_zliB */
}

View File

@ -811,7 +811,10 @@ struct IsoStream_Iface
/**
* Attempts to read up to count bytes from the given stream into
* the buffer starting at buf.
* the buffer starting at buf. The implementation has to make sure that
* either the full desired count of bytes is delivered or that the
* next call to this function will return EOF or error.
* I.e. only the last read block may be shorter than parameter count.
*
* The stream must be open() before calling this, and close() when no
* more needed.
@ -4085,251 +4088,6 @@ void iso_stream_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
char *iso_stream_get_source_path(IsoStream *stream, int flag);
/************ Error codes and return values for libisofs ********************/
/** successfully execution */
#define ISO_SUCCESS 1
/**
* special return value, it could be or not an error depending on the
* context.
*/
#define ISO_NONE 0
/** Operation canceled (FAILURE,HIGH, -1) */
#define ISO_CANCELED 0xE830FFFF
/** Unknown or unexpected fatal error (FATAL,HIGH, -2) */
#define ISO_FATAL_ERROR 0xF030FFFE
/** Unknown or unexpected error (FAILURE,HIGH, -3) */
#define ISO_ERROR 0xE830FFFD
/** Internal programming error. Please report this bug (FATAL,HIGH, -4) */
#define ISO_ASSERT_FAILURE 0xF030FFFC
/**
* NULL pointer as value for an arg. that doesn't allow NULL (FAILURE,HIGH, -5)
*/
#define ISO_NULL_POINTER 0xE830FFFB
/** Memory allocation error (FATAL,HIGH, -6) */
#define ISO_OUT_OF_MEM 0xF030FFFA
/** Interrupted by a signal (FATAL,HIGH, -7) */
#define ISO_INTERRUPTED 0xF030FFF9
/** Invalid parameter value (FAILURE,HIGH, -8) */
#define ISO_WRONG_ARG_VALUE 0xE830FFF8
/** Can't create a needed thread (FATAL,HIGH, -9) */
#define ISO_THREAD_ERROR 0xF030FFF7
/** Write error (FAILURE,HIGH, -10) */
#define ISO_WRITE_ERROR 0xE830FFF6
/** Buffer read error (FAILURE,HIGH, -11) */
#define ISO_BUF_READ_ERROR 0xE830FFF5
/** Trying to add to a dir a node already added to a dir (FAILURE,HIGH, -64) */
#define ISO_NODE_ALREADY_ADDED 0xE830FFC0
/** Node with same name already exists (FAILURE,HIGH, -65) */
#define ISO_NODE_NAME_NOT_UNIQUE 0xE830FFBF
/** Trying to remove a node that was not added to dir (FAILURE,HIGH, -65) */
#define ISO_NODE_NOT_ADDED_TO_DIR 0xE830FFBE
/** A requested node does not exist (FAILURE,HIGH, -66) */
#define ISO_NODE_DOESNT_EXIST 0xE830FFBD
/**
* Try to set the boot image of an already bootable image (FAILURE,HIGH, -67)
*/
#define ISO_IMAGE_ALREADY_BOOTABLE 0xE830FFBC
/** Trying to use an invalid file as boot image (FAILURE,HIGH, -68) */
#define ISO_BOOT_IMAGE_NOT_VALID 0xE830FFBB
/**
* Error on file operation (FAILURE,HIGH, -128)
* (take a look at more specified error codes below)
*/
#define ISO_FILE_ERROR 0xE830FF80
/** Trying to open an already opened file (FAILURE,HIGH, -129) */
#define ISO_FILE_ALREADY_OPENED 0xE830FF7F
/* @deprecated use ISO_FILE_ALREADY_OPENED instead */
#define ISO_FILE_ALREADY_OPENNED 0xE830FF7F
/** Access to file is not allowed (FAILURE,HIGH, -130) */
#define ISO_FILE_ACCESS_DENIED 0xE830FF7E
/** Incorrect path to file (FAILURE,HIGH, -131) */
#define ISO_FILE_BAD_PATH 0xE830FF7D
/** The file does not exist in the filesystem (FAILURE,HIGH, -132) */
#define ISO_FILE_DOESNT_EXIST 0xE830FF7C
/** Trying to read or close a file not openned (FAILURE,HIGH, -133) */
#define ISO_FILE_NOT_OPENED 0xE830FF7B
/* @deprecated use ISO_FILE_NOT_OPENED instead */
#define ISO_FILE_NOT_OPENNED ISO_FILE_NOT_OPENED
/** Directory used where no dir is expected (FAILURE,HIGH, -134) */
#define ISO_FILE_IS_DIR 0xE830FF7A
/** Read error (FAILURE,HIGH, -135) */
#define ISO_FILE_READ_ERROR 0xE830FF79
/** Not dir used where a dir is expected (FAILURE,HIGH, -136) */
#define ISO_FILE_IS_NOT_DIR 0xE830FF78
/** Not symlink used where a symlink is expected (FAILURE,HIGH, -137) */
#define ISO_FILE_IS_NOT_SYMLINK 0xE830FF77
/** Can't seek to specified location (FAILURE,HIGH, -138) */
#define ISO_FILE_SEEK_ERROR 0xE830FF76
/** File not supported in ECMA-119 tree and thus ignored (WARNING,MEDIUM, -139) */
#define ISO_FILE_IGNORED 0xD020FF75
/* A file is bigger than supported by used standard (WARNING,MEDIUM, -140) */
#define ISO_FILE_TOO_BIG 0xD020FF74
/* File read error during image creation (MISHAP,HIGH, -141) */
#define ISO_FILE_CANT_WRITE 0xE430FF73
/* Can't convert filename to requested charset (WARNING,MEDIUM, -142) */
#define ISO_FILENAME_WRONG_CHARSET 0xD020FF72
/* This was once a HINT. Deprecated now. */
#define ISO_FILENAME_WRONG_CHARSET_OLD 0xC020FF72
/* File can't be added to the tree (SORRY,HIGH, -143) */
#define ISO_FILE_CANT_ADD 0xE030FF71
/**
* File path break specification constraints and will be ignored
* (WARNING,MEDIUM, -144)
*/
#define ISO_FILE_IMGPATH_WRONG 0xD020FF70
/**
* Offset greater than file size (FAILURE,HIGH, -145)
* @since 0.6.4
*/
#define ISO_FILE_OFFSET_TOO_BIG 0xE830FF6A
/** Charset conversion error (FAILURE,HIGH, -256) */
#define ISO_CHARSET_CONV_ERROR 0xE830FF00
/**
* Too many files to mangle, i.e. we cannot guarantee unique file names
* (FAILURE,HIGH, -257)
*/
#define ISO_MANGLE_TOO_MUCH_FILES 0xE830FEFF
/* image related errors */
/**
* Wrong or damaged Primary Volume Descriptor (FAILURE,HIGH, -320)
* This could mean that the file is not a valid ISO image.
*/
#define ISO_WRONG_PVD 0xE830FEC0
/** Wrong or damaged RR entry (SORRY,HIGH, -321) */
#define ISO_WRONG_RR 0xE030FEBF
/** Unsupported RR feature (SORRY,HIGH, -322) */
#define ISO_UNSUPPORTED_RR 0xE030FEBE
/** Wrong or damaged ECMA-119 (FAILURE,HIGH, -323) */
#define ISO_WRONG_ECMA119 0xE830FEBD
/** Unsupported ECMA-119 feature (FAILURE,HIGH, -324) */
#define ISO_UNSUPPORTED_ECMA119 0xE830FEBC
/** Wrong or damaged El-Torito catalog (SORRY,HIGH, -325) */
#define ISO_WRONG_EL_TORITO 0xE030FEBB
/** Unsupported El-Torito feature (SORRY,HIGH, -326) */
#define ISO_UNSUPPORTED_EL_TORITO 0xE030FEBA
/** Can't patch an isolinux boot image (SORRY,HIGH, -327) */
#define ISO_ISOLINUX_CANT_PATCH 0xE030FEB9
/** Unsupported SUSP feature (SORRY,HIGH, -328) */
#define ISO_UNSUPPORTED_SUSP 0xE030FEB8
/** Error on a RR entry that can be ignored (WARNING,HIGH, -329) */
#define ISO_WRONG_RR_WARN 0xD030FEB7
/** Error on a RR entry that can be ignored (HINT,MEDIUM, -330) */
#define ISO_SUSP_UNHANDLED 0xC020FEB6
/** Multiple ER SUSP entries found (WARNING,HIGH, -331) */
#define ISO_SUSP_MULTIPLE_ER 0xD030FEB5
/** Unsupported volume descriptor found (HINT,MEDIUM, -332) */
#define ISO_UNSUPPORTED_VD 0xC020FEB4
/** El-Torito related warning (WARNING,HIGH, -333) */
#define ISO_EL_TORITO_WARN 0xD030FEB3
/** Image write cancelled (MISHAP,HIGH, -334) */
#define ISO_IMAGE_WRITE_CANCELED 0xE430FEB2
/** El-Torito image is hidden (WARNING,HIGH, -335) */
#define ISO_EL_TORITO_HIDDEN 0xD030FEB1
/** Read error occured with IsoDataSource (SORRY,HIGH, -513) */
#define ISO_DATA_SOURCE_SORRY 0xE030FCFF
/** Read error occured with IsoDataSource (MISHAP,HIGH, -513) */
#define ISO_DATA_SOURCE_MISHAP 0xE430FCFF
/** Read error occured with IsoDataSource (FAILURE,HIGH, -513) */
#define ISO_DATA_SOURCE_FAILURE 0xE830FCFF
/** Read error occured with IsoDataSource (FATAL,HIGH, -513) */
#define ISO_DATA_SOURCE_FATAL 0xF030FCFF
/** AAIP info with ACL or xattr in ISO image will be ignored
(NOTE, HIGH, -336) */
#define ISO_AAIP_IGNORED 0xB030FEB0
/** Error with decoding ACL from AAIP info (FAILURE, HIGH, -337) */
#define ISO_AAIP_BAD_ACL 0xE830FEAF
/** Error with encoding ACL for AAIP (FAILURE, HIGH, -338) */
#define ISO_AAIP_BAD_ACL_TEXT 0xE830FEAE
/** AAIP processing for ACL or xattr not enabled at compile time
(FAILURE, HIGH, -339) */
#define ISO_AAIP_NOT_ENABLED 0xE830FEAD
/** Error with decoding AAIP info for ACL or xattr (FAILURE, HIGH, -340) */
#define ISO_AAIP_BAD_AASTRING 0xE830FEAC
/** Error with reading ACL or xattr from local file (FAILURE, HIGH, -341) */
#define ISO_AAIP_NO_GET_LOCAL 0xE830FEAB
/** Error with attaching ACL or xattr to local file (FAILURE, HIGH, -342) */
#define ISO_AAIP_NO_SET_LOCAL 0xE830FEAA
/** Unallowed attempt to set an xattr with non-userspace name
(FAILURE, HIGH, -343) */
#define ISO_AAIP_NON_USER_NAME 0xE830FEA9
/* ts A90325 */
/** Too many references on a single IsoExternalFilterCommand
(FAILURE, HIGH, -344) */
#define ISO_EXTF_TOO_OFTEN 0xE830FEA8
/* --------------------------------- AAIP --------------------------------- */
/**
@ -4694,6 +4452,320 @@ int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag);
/************ Error codes and return values for libisofs ********************/
/** successfully execution */
#define ISO_SUCCESS 1
/**
* special return value, it could be or not an error depending on the
* context.
*/
#define ISO_NONE 0
/** Operation canceled (FAILURE,HIGH, -1) */
#define ISO_CANCELED 0xE830FFFF
/** Unknown or unexpected fatal error (FATAL,HIGH, -2) */
#define ISO_FATAL_ERROR 0xF030FFFE
/** Unknown or unexpected error (FAILURE,HIGH, -3) */
#define ISO_ERROR 0xE830FFFD
/** Internal programming error. Please report this bug (FATAL,HIGH, -4) */
#define ISO_ASSERT_FAILURE 0xF030FFFC
/**
* NULL pointer as value for an arg. that doesn't allow NULL (FAILURE,HIGH, -5)
*/
#define ISO_NULL_POINTER 0xE830FFFB
/** Memory allocation error (FATAL,HIGH, -6) */
#define ISO_OUT_OF_MEM 0xF030FFFA
/** Interrupted by a signal (FATAL,HIGH, -7) */
#define ISO_INTERRUPTED 0xF030FFF9
/** Invalid parameter value (FAILURE,HIGH, -8) */
#define ISO_WRONG_ARG_VALUE 0xE830FFF8
/** Can't create a needed thread (FATAL,HIGH, -9) */
#define ISO_THREAD_ERROR 0xF030FFF7
/** Write error (FAILURE,HIGH, -10) */
#define ISO_WRITE_ERROR 0xE830FFF6
/** Buffer read error (FAILURE,HIGH, -11) */
#define ISO_BUF_READ_ERROR 0xE830FFF5
/** Trying to add to a dir a node already added to a dir (FAILURE,HIGH, -64) */
#define ISO_NODE_ALREADY_ADDED 0xE830FFC0
/** Node with same name already exists (FAILURE,HIGH, -65) */
#define ISO_NODE_NAME_NOT_UNIQUE 0xE830FFBF
/** Trying to remove a node that was not added to dir (FAILURE,HIGH, -65) */
#define ISO_NODE_NOT_ADDED_TO_DIR 0xE830FFBE
/** A requested node does not exist (FAILURE,HIGH, -66) */
#define ISO_NODE_DOESNT_EXIST 0xE830FFBD
/**
* Try to set the boot image of an already bootable image (FAILURE,HIGH, -67)
*/
#define ISO_IMAGE_ALREADY_BOOTABLE 0xE830FFBC
/** Trying to use an invalid file as boot image (FAILURE,HIGH, -68) */
#define ISO_BOOT_IMAGE_NOT_VALID 0xE830FFBB
/**
* Error on file operation (FAILURE,HIGH, -128)
* (take a look at more specified error codes below)
*/
#define ISO_FILE_ERROR 0xE830FF80
/** Trying to open an already opened file (FAILURE,HIGH, -129) */
#define ISO_FILE_ALREADY_OPENED 0xE830FF7F
/* @deprecated use ISO_FILE_ALREADY_OPENED instead */
#define ISO_FILE_ALREADY_OPENNED 0xE830FF7F
/** Access to file is not allowed (FAILURE,HIGH, -130) */
#define ISO_FILE_ACCESS_DENIED 0xE830FF7E
/** Incorrect path to file (FAILURE,HIGH, -131) */
#define ISO_FILE_BAD_PATH 0xE830FF7D
/** The file does not exist in the filesystem (FAILURE,HIGH, -132) */
#define ISO_FILE_DOESNT_EXIST 0xE830FF7C
/** Trying to read or close a file not openned (FAILURE,HIGH, -133) */
#define ISO_FILE_NOT_OPENED 0xE830FF7B
/* @deprecated use ISO_FILE_NOT_OPENED instead */
#define ISO_FILE_NOT_OPENNED ISO_FILE_NOT_OPENED
/** Directory used where no dir is expected (FAILURE,HIGH, -134) */
#define ISO_FILE_IS_DIR 0xE830FF7A
/** Read error (FAILURE,HIGH, -135) */
#define ISO_FILE_READ_ERROR 0xE830FF79
/** Not dir used where a dir is expected (FAILURE,HIGH, -136) */
#define ISO_FILE_IS_NOT_DIR 0xE830FF78
/** Not symlink used where a symlink is expected (FAILURE,HIGH, -137) */
#define ISO_FILE_IS_NOT_SYMLINK 0xE830FF77
/** Can't seek to specified location (FAILURE,HIGH, -138) */
#define ISO_FILE_SEEK_ERROR 0xE830FF76
/** File not supported in ECMA-119 tree and thus ignored (WARNING,MEDIUM, -139) */
#define ISO_FILE_IGNORED 0xD020FF75
/* A file is bigger than supported by used standard (WARNING,MEDIUM, -140) */
#define ISO_FILE_TOO_BIG 0xD020FF74
/* File read error during image creation (MISHAP,HIGH, -141) */
#define ISO_FILE_CANT_WRITE 0xE430FF73
/* Can't convert filename to requested charset (WARNING,MEDIUM, -142) */
#define ISO_FILENAME_WRONG_CHARSET 0xD020FF72
/* This was once a HINT. Deprecated now. */
#define ISO_FILENAME_WRONG_CHARSET_OLD 0xC020FF72
/* File can't be added to the tree (SORRY,HIGH, -143) */
#define ISO_FILE_CANT_ADD 0xE030FF71
/**
* File path break specification constraints and will be ignored
* (WARNING,MEDIUM, -144)
*/
#define ISO_FILE_IMGPATH_WRONG 0xD020FF70
/**
* Offset greater than file size (FAILURE,HIGH, -145)
* @since 0.6.4
*/
#define ISO_FILE_OFFSET_TOO_BIG 0xE830FF6A
/** Charset conversion error (FAILURE,HIGH, -256) */
#define ISO_CHARSET_CONV_ERROR 0xE830FF00
/**
* Too many files to mangle, i.e. we cannot guarantee unique file names
* (FAILURE,HIGH, -257)
*/
#define ISO_MANGLE_TOO_MUCH_FILES 0xE830FEFF
/* image related errors */
/**
* Wrong or damaged Primary Volume Descriptor (FAILURE,HIGH, -320)
* This could mean that the file is not a valid ISO image.
*/
#define ISO_WRONG_PVD 0xE830FEC0
/** Wrong or damaged RR entry (SORRY,HIGH, -321) */
#define ISO_WRONG_RR 0xE030FEBF
/** Unsupported RR feature (SORRY,HIGH, -322) */
#define ISO_UNSUPPORTED_RR 0xE030FEBE
/** Wrong or damaged ECMA-119 (FAILURE,HIGH, -323) */
#define ISO_WRONG_ECMA119 0xE830FEBD
/** Unsupported ECMA-119 feature (FAILURE,HIGH, -324) */
#define ISO_UNSUPPORTED_ECMA119 0xE830FEBC
/** Wrong or damaged El-Torito catalog (SORRY,HIGH, -325) */
#define ISO_WRONG_EL_TORITO 0xE030FEBB
/** Unsupported El-Torito feature (SORRY,HIGH, -326) */
#define ISO_UNSUPPORTED_EL_TORITO 0xE030FEBA
/** Can't patch an isolinux boot image (SORRY,HIGH, -327) */
#define ISO_ISOLINUX_CANT_PATCH 0xE030FEB9
/** Unsupported SUSP feature (SORRY,HIGH, -328) */
#define ISO_UNSUPPORTED_SUSP 0xE030FEB8
/** Error on a RR entry that can be ignored (WARNING,HIGH, -329) */
#define ISO_WRONG_RR_WARN 0xD030FEB7
/** Error on a RR entry that can be ignored (HINT,MEDIUM, -330) */
#define ISO_SUSP_UNHANDLED 0xC020FEB6
/** Multiple ER SUSP entries found (WARNING,HIGH, -331) */
#define ISO_SUSP_MULTIPLE_ER 0xD030FEB5
/** Unsupported volume descriptor found (HINT,MEDIUM, -332) */
#define ISO_UNSUPPORTED_VD 0xC020FEB4
/** El-Torito related warning (WARNING,HIGH, -333) */
#define ISO_EL_TORITO_WARN 0xD030FEB3
/** Image write cancelled (MISHAP,HIGH, -334) */
#define ISO_IMAGE_WRITE_CANCELED 0xE430FEB2
/** El-Torito image is hidden (WARNING,HIGH, -335) */
#define ISO_EL_TORITO_HIDDEN 0xD030FEB1
/** Read error occured with IsoDataSource (SORRY,HIGH, -513) */
#define ISO_DATA_SOURCE_SORRY 0xE030FCFF
/** Read error occured with IsoDataSource (MISHAP,HIGH, -513) */
#define ISO_DATA_SOURCE_MISHAP 0xE430FCFF
/** Read error occured with IsoDataSource (FAILURE,HIGH, -513) */
#define ISO_DATA_SOURCE_FAILURE 0xE830FCFF
/** Read error occured with IsoDataSource (FATAL,HIGH, -513) */
#define ISO_DATA_SOURCE_FATAL 0xF030FCFF
/** AAIP info with ACL or xattr in ISO image will be ignored
(NOTE, HIGH, -336) */
#define ISO_AAIP_IGNORED 0xB030FEB0
/** Error with decoding ACL from AAIP info (FAILURE, HIGH, -337) */
#define ISO_AAIP_BAD_ACL 0xE830FEAF
/** Error with encoding ACL for AAIP (FAILURE, HIGH, -338) */
#define ISO_AAIP_BAD_ACL_TEXT 0xE830FEAE
/** AAIP processing for ACL or xattr not enabled at compile time
(FAILURE, HIGH, -339) */
#define ISO_AAIP_NOT_ENABLED 0xE830FEAD
/** Error with decoding AAIP info for ACL or xattr (FAILURE, HIGH, -340) */
#define ISO_AAIP_BAD_AASTRING 0xE830FEAC
/** Error with reading ACL or xattr from local file (FAILURE, HIGH, -341) */
#define ISO_AAIP_NO_GET_LOCAL 0xE830FEAB
/** Error with attaching ACL or xattr to local file (FAILURE, HIGH, -342) */
#define ISO_AAIP_NO_SET_LOCAL 0xE830FEAA
/** Unallowed attempt to set an xattr with non-userspace name
(FAILURE, HIGH, -343) */
#define ISO_AAIP_NON_USER_NAME 0xE830FEA9
/* ts A90325 */
/** Too many references on a single IsoExternalFilterCommand
(FAILURE, HIGH, -344) */
#define ISO_EXTF_TOO_OFTEN 0xE830FEA8
/* ts A90409 */
/** Use of zlib was not enabled at compile time (FAILURE, HIGH, -345) */
#define ISO_ZLIB_NOT_ENABLED 0xE830FEA7
/* ts A90409 */
/** Cannot apply zisofs filter to file >= 4 GiB (FAILURE, HIGH, -346) */
#define ISO_ZISOFS_TOO_LARGE 0xE830FEA6
/* --------------------------- Filters in General -------------------------- */
/*
* A filter is an IsoStreams which uses another IsoStream as input. It gets
* attached to an IsoFile by specialized calls iso_file_add_*_filter() which
* replace its current IsoStream by the filter stream which takes over the
* current IsoStream as input.
* The consequences are:
* iso_file_get_stream() will return the filter stream.
* iso_stream_get_size() will return the (cached) size of the filtered data,
* iso_stream_open() will start eventual child processes,
* iso_stream_close() will kill eventual child processes,
* iso_stream_read() will return filtered data. E.g. as data file content
* during ISO image generation.
*
* There are external filters which run child processes
* iso_file_add_external_filter()
* and internal filters
* iso_file_add_zisofs_filter()
* which may or may not be available depending on compile time settings and
* installed software packages like libz.
*/
/* ts A90328 */
/**
* Delete the top filter stream from a data file. This is the most recent one
* which was added by iso_file_add_*_filter().
* Caution: One should not do this while the IsoStream of the file is opened.
* For now there is no general way to determine this state.
* Filter stream implementations are urged to eventually call .close()
* inside method .free() . This will close the input stream too.
* @param file
* The data file node which shall get rid of one layer of content
* filtering.
* @param flag
* Bitfield for control purposes, unused yet, submit 0.
* @return
* 1 on success, 0 if no filter was present
* <0 on error
*
* @since 0.6.18
*/
int iso_file_remove_filter(IsoFile *file, int flag);
/* ts A90328 */
/**
* Obtain the eventual input stream of a filter stream.
* @param stream
* The eventual filter stream to be inquired.
* @param flag
* Bitfield for control purposes. Submit 0 for now.
* @return
* The input stream, if one exists. Elsewise NULL.
* No extra reference to the stream is taken by this call.
*
* @since 0.6.18
*/
IsoStream *iso_stream_get_input_stream(IsoStream *stream, int flag);
/* ---------------------------- External Filters --------------------------- */
/* ts A90325 */
@ -4769,13 +4841,6 @@ typedef struct iso_external_filter_command IsoExternalFilterCommand;
* Install an external filter command on top of the content stream of a data
* file. The filter process must be repeatable. It will be run once by this
* call in order to cache the output size.
* This call creates a new IsoStream which uses the existing IsoStream of the
* data file as input.
* iso_file_get_stream() will return the filter stream.
* iso_stream_get_size() will return the cached size of the filtered data,
* iso_stream_open() will start again the external filter process,
* iso_stream_close() will kill it,
* iso_stream_read() will return filtered data.
* @param file
* The data file node which shall show filtered content.
* @param cmd
@ -4791,43 +4856,6 @@ typedef struct iso_external_filter_command IsoExternalFilterCommand;
int iso_file_add_external_filter(IsoFile *file, IsoExternalFilterCommand *cmd,
int flag);
/* ts A90328 */
/**
* Delete the top filter stream from a data file. This is the most recent one
* which was added by iso_file_add_*_filter().
* Caution: One should not do this while the IsoStream of the file is opened.
* For now there is no general way to determine this state.
* Filter stream implementations are urged to eventually call .close()
* inside method .free() . This will close the input stream too.
* @param file
* The data file node which shall get rid of one layer of content
* filtering.
* @param flag
* Bitfield for control purposes, unused yet, submit 0.
* @return
* 1 on success, 0 if no filter was present
* <0 on error
*
* @since 0.6.18
*/
int iso_file_remove_filter(IsoFile *file, int flag);
/* ts A90328 */
/**
* Obtain the eventual input stream of a filter stream.
* @param stream
* The eventual filter stream to be inquired.
* @param flag
* Bitfield for control purposes. Submit 0 for now.
* @return
* The input stream, if one exists. Elsewise NULL.
* No extra reference to the stream is taken by this call.
*
* @since 0.6.18
*/
IsoStream *iso_stream_get_input_stream(IsoStream *stream, int flag);
/* ts A90402 */
/**
@ -4851,6 +4879,33 @@ int iso_stream_get_external_filter(IsoStream *stream,
IsoExternalFilterCommand **cmd, int flag);
/* ---------------------------- Internal Filters --------------------------- */
/* ts A90409 */
/**
* Install a zisofs filter on top of the content stream of a data * file.
* zisofs is a compression format which is decompressed by some Linux kernels.
* See also doc/zisofs_format.txt .
* The filter will not be installed if its output size is not smaller than
* the size of the input stream.
* This is only enabled if the use of libz was enabled at compile time.
* @param file
* The data file node which shall show filtered content.
* @param flag
* Bitfield for control purposes
* bit0= Do not install filter if the number of output blocks is
* not smaller than the number of input blocks. Block size is 2048.
* bit1= Install a decompression filter rather than one for compression.
* @return
* 1 on success, 2 if filter installation revoked
* <0 on error, e.g. ISO_ZLIB_NOT_ENABLED
*
* @since 0.6.18
*/
int iso_file_add_zisofs_filter(IsoFile *file, int flag);
/* ------------------------------------------------------------------------- */
#ifdef LIBISOFS_WITHOUT_LIBBURN

View File

@ -249,6 +249,10 @@ const char *iso_error_to_msg(int errcode)
return "Unallowed attempt to set an xattr with non-userspace name";
case ISO_EXTF_TOO_OFTEN:
return "Too many references on a single external filter command";
case ISO_ZLIB_NOT_ENABLED:
return "Use of zlib was not enabled at compile time";
case ISO_ZISOFS_TOO_LARGE:
return "Cannot apply zisofs filter to file >= 4 GiB";
default:
return "Unknown error";
}