Implemented numeber of multisession options, reading, modifying tree, and a number of improvements

This commit is contained in:
Mario Danic 2007-08-10 09:35:10 +00:00
parent 2e073c258c
commit 0b1a9c5565
25 changed files with 2099 additions and 232 deletions

View File

@ -1 +1,13 @@
nothing here now
Development
===========
- Support for reading of plain iso images.
- Support for reading RR extensions
Version 0.2.8
=============
TODO

View File

@ -33,7 +33,12 @@ libisofs_libisofs_la_SOURCES = \
libisofs/file.h \
libisofs/file.c \
libisofs/eltorito.h \
libisofs/eltorito.c
libisofs/eltorito.c \
libisofs/data_source.c \
libisofs/ecma119_read.h \
libisofs/ecma119_read.c \
libisofs/ecma119_read_rr.h \
libisofs/ecma119_read_rr.c
libinclude_HEADERS = \
libisofs/libisofs.h
@ -42,12 +47,27 @@ libinclude_HEADERS = \
## Build test applications
noinst_PROGRAMS = \
test/iso
test/iso \
test/isoread \
test/isoms \
test/isoadd
test_iso_CPPFLAGS = -Ilibisofs
test_iso_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS)
test_iso_SOURCES = test/iso.c
test_isoread_CPPFLAGS = -Ilibisofs
test_isoread_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS)
test_isoread_SOURCES = test/iso_read.c
test_isoms_CPPFLAGS = -Ilibisofs
test_isoms_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS)
test_isoms_SOURCES = test/iso_ms.c
test_isoadd_CPPFLAGS = -Ilibisofs
test_isoadd_LDADD = $(libisofs_libisofs_la_OBJECTS) $(THREAD_LIBS)
test_isoadd_SOURCES = test/iso_add.c
## Build unit test
check_PROGRAMS = \
@ -64,6 +84,8 @@ test_test_SOURCES = \
test/test_file_hashtable.c \
test/test_util.c \
test/test_volume.c \
test/test_data_source.c \
test/test_read.c \
test/test.c
## ========================================================================= ##

14
TODO
View File

@ -5,9 +5,14 @@ FEATURES
Support for multiple images
HFS/HFS+
CD reading
[ok] plain iso
[ok] Rock Ridge
Joliet
Merge RR and Joliet trees
User options to customize reading
Multisession
UDF
ISO relaxed contraints
[ok] ISO relaxed contraints
ISO 9660:1998
Support for special files (only dirs, reg. files and symlinks are supported).
@ -15,6 +20,9 @@ FEATURES
TESTS
=====
[several done]
Test all util.h functions, especially date-related ones
Test for RR read functions
For all
IMPLEMENTATION
@ -22,8 +30,10 @@ IMPLEMENTATION
a way to return NULL sources meaning a failure!!
Error message queue
Public API for all things already implemented
Better charset support
default input charset to locale one, no always UTF-8
add charset management on image reading
use iso-8859-1 instead of UTF-8 dor RR?
Improve date handling

View File

@ -246,7 +246,14 @@ calc_file_pos(struct ecma119_write_target *t,
do {
struct iso_file *file = node->file;
if (file->size)
/*
* We only need to write the file when.
* a) The size is greater than 0.
* b) The file is new (not from a previous image) or we
* are writting an image not for ms (i.e., we are modifying an
* image).
*/
if ( file->size && (!file->prev_img || !t->ms_block) )
t->filelist[t->curfile++] = file;
node = node->next;
} while (node);
@ -308,6 +315,9 @@ ecma119_target_new(struct iso_volset *volset,
t->ouput_charset = opts->ouput_charset ? opts->ouput_charset : "UTF-8";
t->sort_files = opts->sort_files;
t->ms_block = opts->ms_block;
t->src = opts->src;
t->file_table = iso_file_table_new(t->cache_inodes);
volset->refcount++;
t->iso_level = opts->level;
@ -356,7 +366,8 @@ ecma119_target_new(struct iso_volset *volset,
}
}
t->curblock = 16 /* system area */
t->curblock = t->ms_block /* nwa for ms, usually 0 */
+ 16 /* system area */
+ 1 /* volume desc */
+ 1; /* volume desc terminator */
@ -409,6 +420,9 @@ ecma119_target_new(struct iso_volset *volset,
}
t->total_size = t->curblock * t->block_size;
//TODO how needs to be here for ms?
// a change here requires changes in bs_read!!
t->vol_space_size = t->curblock;
/* prepare for writing */
@ -489,31 +503,51 @@ wr_files(struct ecma119_write_target *t, uint8_t *buf)
struct state_files *f_st = &t->state_files;
size_t nread;
struct iso_file *f = t->filelist[f_st->file];
const char *path = f->path;
if (f->prev_img) {
int block;
assert( !t->ms_block && t->src );
if (!f_st->fd) {
printf("Writing file %s\n", path);
f_st->data_len = f->size;
f_st->fd = fopen(path, "r");
if (!f_st->fd)
err(1, "couldn't open %s for reading", path);
assert(t->curblock == f->block);
}
/**
* f->block block where file read begins
* t->curblock block we're writting now
* f->real_ino initial block for file on source
*/
block = t->curblock - f->block;
if ( t->src->read_block(t->src, f->real_ino + block, buf) ) {
warn("problem reading from previous image");
}
if ( f->size <= (off_t) (block+1) * t->block_size ) {
f_st->file++;
if (f_st->file >= t->filelist_len)
next_state(t);
}
} else {
const char *path = f->path;
nread = fread(buf, 1, t->block_size, f_st->fd);
f_st->pos += t->block_size;
if (nread < 0)
warn("problem reading from %s", path);
else if (nread != t->block_size && f_st->pos < f_st->data_len)
warnx("incomplete read from %s", path);
if (f_st->pos >= f_st->data_len) {
fclose(f_st->fd);
f_st->fd = 0;
f_st->pos = 0;
f_st->file++;
if (f_st->file >= t->filelist_len)
next_state(t);
if (!f_st->fd) {
printf("Writing file %s\n", path);
f_st->data_len = f->size;
f_st->fd = fopen(path, "r");
if (!f_st->fd)
err(1, "couldn't open %s for reading", path);
assert(t->curblock + t->ms_block == f->block);
}
nread = fread(buf, 1, t->block_size, f_st->fd);
f_st->pos += t->block_size;
if (nread < 0)
warn("problem reading from %s", path);
else if (nread != t->block_size && f_st->pos < f_st->data_len)
warnx("incomplete read from %s", path);
if (f_st->pos >= f_st->data_len) {
fclose(f_st->fd);
f_st->fd = 0;
f_st->pos = 0;
f_st->file++;
if (f_st->file >= t->filelist_len)
next_state(t);
}
}
}
@ -790,7 +824,7 @@ bs_read(struct burn_source *bs, unsigned char *buf, int size)
warnx("you must read data in block-sized chunks (%d bytes)",
(int)t->block_size);
return 0;
} else if (t->curblock >= t->vol_space_size) {
} else if (t->curblock + t->ms_block >= t->vol_space_size) {
return 0;
}
if (t->state_data_valid)

View File

@ -98,6 +98,9 @@ struct ecma119_write_target
*/
ino_t ino;
uint32_t ms_block; /**< if != 0, nwa for multisession */
struct data_source* src;
int curblock;
uint16_t block_size;
uint32_t path_table_size;

View File

@ -125,7 +125,7 @@ create_image(struct iso_tree_node *image,
int used_partition;
/* read the MBR on disc and get the type of the partition */
fd = open(((struct iso_tree_node_file*)image)->path, O_RDONLY);
fd = open(((struct iso_tree_node_file*)image)->loc.path, O_RDONLY);
if ( fd == -1 ) {
fprintf(stderr, "Can't open image file\n");
return NULL;
@ -344,10 +344,10 @@ patch_boot_file(struct el_torito_boot_image *img)
memset(&info, 0, sizeof(info));
/* open image */
fd = open(img->image->path, O_RDWR);
fd = open(img->image->loc.path, O_RDWR);
if ( fd == -1 ) {
//TODO what do do? exit or just continue?
fprintf(stderr, "Can't patch boot image %s\n", img->image->path);
fprintf(stderr, "Can't patch boot image %s\n", img->image->loc.path);
close(fd);
return;
}
@ -364,7 +364,7 @@ patch_boot_file(struct el_torito_boot_image *img)
if ( len != 0 ) {
/* error reading file, or file length not multiple of 4 */
//TODO what do do? exit or just continue?
fprintf(stderr, "Can't patch boot image %s\n", img->image->path);
fprintf(stderr, "Can't patch boot image %s\n", img->image->loc.path);
close(fd);
return;
}

View File

@ -9,15 +9,6 @@ iso_exclude_add_path(struct iso_hash_table *table, const char *path)
table->num += iso_hash_insert(table->table, path);
}
/*void
iso_exclude_remove_path(struct iso_hash_table *table, const char *path)
{
if (!table->num || !path)
return;
table->num -= iso_hash_remove(table->table, path);
}*/
void
iso_exclude_empty(struct iso_hash_table *table)
{

View File

@ -22,13 +22,6 @@ int iso_exclude_lookup(struct iso_hash_table *table, const char *path);
*/
void iso_exclude_add_path(struct iso_hash_table *table, const char *path);
/**
* Remove a path that was set to be ignored when adding a directory recusively.
*
* \param path The path, on the local filesystem, of the file.
*/
//void iso_exclude_remove_path(struct iso_hash_table *table, const char *path);
/**
* Remove all paths that were set to be ignored when adding a directory recusively.
*/

View File

@ -8,17 +8,30 @@
#include "file.h"
#include "tree.h"
//TODO: refactor both hash and this hash table into a single one!!
//TODO: refactor both hash and this hash table into a single one??
struct iso_file *
iso_file_new(struct iso_tree_node_file *f)
{
struct iso_file *file = calloc(1, sizeof(struct iso_file));
file->path = f->path; /*TODO strdup? it needs to be free on clear then */
if (f->node.procedence == LIBISO_NEW) {
file->path = f->loc.path; /*TODO strdup? it needs to be free on clear then */
file->real_dev = f->node.attrib.st_dev;
file->real_ino = f->node.attrib.st_ino;
} else {
file->block = f->loc.block;
file->prev_img = 1;
file->real_dev = 0; /* we use 0 as dev for prev. session files */
/* don't take care about inode number read from RR TX, block
* number is good enouht for this. Moreover, when we are modifying
* an image, we will modify file->block with the block where the
* file needs to be written in the new image. So, we store the block
* in original image here, because we will need to use it for
* reading file contents */
file->real_ino = f->loc.block;
}
file->size = f->node.attrib.st_size;
file->nlink = 1;
file->real_dev = f->node.attrib.st_dev;
file->real_ino = f->node.attrib.st_ino;
file->sort_weight = f->sort_weight;
return file;
}
@ -98,6 +111,13 @@ static int
iso_table_compare_files(struct iso_file_table *ft,
struct iso_file *f1, struct iso_file *f2)
{
assert(ft && f1 && f2);
if (f1->prev_img || f2->prev_img) {
if (f1->prev_img && f2->prev_img)
return f1->real_ino != f2->real_ino;
else
return 1;
}
if (ft->cache_inodes) {
return (f1->real_dev != f2->real_dev) || (f1->real_ino != f2->real_ino);
} else {
@ -111,8 +131,12 @@ iso_file_table_add_file(struct iso_file_table *ft, struct iso_file *f)
struct iso_file_hash_node *node;
unsigned int hash_num;
assert(ft && f);
/* find the hash number */
if (ft->cache_inodes)
if (f->prev_img)
hash_num = f->real_ino % FILE_HASH_NODES;
else if (ft->cache_inodes)
hash_num = iso_file_table_hash_inode(f->real_dev, f->real_ino);
else
hash_num = iso_file_table_hash(f->path);
@ -146,6 +170,27 @@ iso_file_table_add_file(struct iso_file_table *ft, struct iso_file *f)
return 1;
}
/** 0 on equal, != 0 otherwise */
static int
iso_table_compare_node_file(struct iso_file_table *ft,
struct iso_tree_node_file *f1, struct iso_file *f2)
{
assert(ft && f1 && f2);
if (f1->node.procedence || f2->prev_img) {
if (f1->node.procedence && f2->prev_img)
return f1->loc.block != f2->real_ino;
else
return 1;
}
if (ft->cache_inodes) {
return (f1->node.attrib.st_dev != f2->real_dev)
|| (f1->node.attrib.st_ino != f2->real_ino);
} else {
return strcmp(f1->loc.path, f2->path);
}
}
struct iso_file *
iso_file_table_lookup(struct iso_file_table *ft, struct iso_tree_node_file *f)
{
@ -153,32 +198,30 @@ iso_file_table_lookup(struct iso_file_table *ft, struct iso_tree_node_file *f)
unsigned int hash_num;
int equal;
assert(ft && f);
/* find the hash number */
if ( ft->cache_inodes )
if (f->node.procedence == LIBISO_PREVIMG)
hash_num = f->loc.block % FILE_HASH_NODES;
else if ( ft->cache_inodes )
hash_num = iso_file_table_hash_inode(f->node.attrib.st_dev,
f->node.attrib.st_ino);
else
hash_num = iso_file_table_hash(f->path);
hash_num = iso_file_table_hash(f->loc.path);
node = ft->table[hash_num];
if (!node)
return NULL;
equal = ft->cache_inodes ?
((f->node.attrib.st_dev == node->file->real_dev)
&& (f->node.attrib.st_ino == node->file->real_ino))
: !strcmp(f->path, node->file->path);
equal = !iso_table_compare_node_file(ft, f, node->file);
if (equal)
return node->file;
while (node->next) {
node = node->next;
equal = ft->cache_inodes ?
((f->node.attrib.st_dev == node->file->real_dev)
&& (f->node.attrib.st_ino == node->file->real_ino))
: !strcmp(f->path, node->file->path);
equal = !iso_table_compare_node_file(ft, f, node->file);
if (equal)
return node->file;
}

View File

@ -17,14 +17,16 @@
#ifndef FILE_H_
#define FILE_H_
#include <stdint.h>
#define FILE_HASH_NODES 2048
struct iso_file {
unsigned int prev_img:1; /**< if the file comes from a previous image */
char *path; /**< Path of the file on local filesystem */
off_t size; /**< size of this file */
ino_t ino; /**< This will be the inode number on CD of the file (RR) */
nlink_t nlink; /**< Number of hard links of the file on CD (RR) */
size_t block; /**< Block where this file is to be written on image */
uint32_t block; /**< Block where this file is to be written on image */
dev_t real_dev;
ino_t real_ino; /**< for lookup by inode caching */
int sort_weight;

View File

@ -13,6 +13,7 @@
#define LIBISO_LIBISOFS_H
#include <sys/types.h>
#include <stdint.h>
/* #include <libburn.h> */
struct burn_source;
@ -31,15 +32,43 @@ struct iso_volset;
/**
* A node in the filesystem tree.
*
* This is opaque struct that represent any kind of nodes. When needed,
* you can get the type with iso_tree_node_get_type and cast it to the
* appropiate subtype:
*
* iso_tree_node_dir
* iso_tree_node_file
* iso_tree_node_symlink
*
* \see tree.h
*/
struct iso_tree_node;
/**
* El-Torito boot image
* \see eltorito.h
* The type of an iso_tree_node.
* When an user gets an iso_tree_node from libisofs, (s)he can use
* iso_tree_node_get_type to get the current type of the node, and then
* cast to the appropriate subtype. For example:
*
* struct iso_tree_node *node = iso... TODO
* if ( iso_tree_node_get_type(node) == LIBISO_NODE_DIR ) {
* struct iso_tree_node_dir *dir = (struct iso_tree_node_dir *)node;
* ...
* }
*
* Useful macros are provided.
*/
struct el_torito_boot_image;
enum iso_tree_node_type {
LIBISO_NODE_DIR,
LIBISO_NODE_FILE,
LIBISO_NODE_SYMLINK,
LIBISO_NODE_BOOTCATALOG
};
#define LIBISO_ISDIR(n) (iso_tree_node_get_type(n) == LIBISO_NODE_DIR)
#define LIBISO_ISREG(n) (iso_tree_node_get_type(n) == LIBISO_NODE_FILE)
#define LIBISO_ISLNK(n) (iso_tree_node_get_type(n) == LIBISO_NODE_SYMLINK)
/**
* A directory in the filesystem tree.
@ -48,6 +77,44 @@ struct el_torito_boot_image;
*/
struct iso_tree_node_dir;
/**
* A node in the filesystem tree that represents a regular file
*/
struct iso_tree_node_file;
/**
* A node in the filesystem tree that represents a symbolic link
*/
struct iso_tree_node_symlink;
/**
* A node that represents a boot catalog
* FIXME I'm not very sure how this should be treated.
*/
struct iso_tree_node_boot_catalog;
/**
* El-Torito boot image
* \see eltorito.h
*/
struct el_torito_boot_image;
/** Iterator for dir children. */
struct iso_tree_iter;
/**
* The procedence of the node.
*/
enum tree_node_from {
/** The node has been added by the user */
LIBISO_NEW = 0,
/**
* The node comes from a previous image. That can be from a previous
* session on disc, or from an ISO file we want to modify.
*/
LIBISO_PREVIMG
};
/**
* Extensions addition to ECMA-119 (ISO-9660) image. Usage of at least
* one of these flags is highly recommended if the disc will be used on a
@ -155,6 +222,81 @@ struct ecma119_source_opts {
uid_t uid; /**< uid to use when replace_uid is set. */
char *input_charset; /**< NULL to use default charset */
char *ouput_charset; /**< NULL to use default charset */
uint32_t ms_block;
/**<
* Start block for multisession. When this is greater than 0,
* it's suppossed to be the lba of the next writable address
* on disc; all block lba on image will take this into account,
* and files from a previous session will not be written on
* image. This behavior is only suitable for images to be
* appended to a multisession disc.
* When this is 0, no multisession image will be created. If
* some files are taken from a previous image, its contents
* will be written again to the new image. Use this with new
* images or if you plan to modify an existin image.
*/
struct data_source* src;
/**<
* When modifying a image, this is the source of the original
* image, used to read file contents.
* Otherwise it can be NULL.
*/
};
/**
* FIXME documentar isto!!!
*/
struct ecma119_read_opts {
int tree_to_read;
int block; /** Block where the image begins, usually 0, can be
* different on a multisession disc.
*/
//TODO....
unsigned int norock:1; /*< Do not read Rock Ridge extensions */
//nojoliet
//check -> convert names to lower case
//uid, gid (when no RR)
//file and dir mode (when no RR)
/* modified by the function */
unsigned int hasRR:1; /*< It will be set to 1 if RR extensions are present,
to 0 if not. */
//hasJoliet
int error;
};
/**
* Data source used by libisofs for reading an existing image.
* It contains suitable methods to read arbitrary block. Usually, the block
* size is 2048 bytes.
*/
struct data_source {
/**
* Reference count for the data source. Should be 1 when a new source
* is created. Increment it to take a reference for yourself. Use
* data_source_free to destroy your reference to it.
*/
int refcount;
/**
* Read data from the source.
* @param lba Block to be read.
* @param buffer Buffer where the data will be written. Its size must
* be at least 2048 bytes.
* @return
* 0 if ok, < 0 on error
*/
int (*read_block)(struct data_source *src, int lba, unsigned char *buffer);
/** Get the size (number of block) of the source's data */
int (*get_size)(struct data_source *);
/** Clean up the source specific data */
void (*free_data)(struct data_source *);
/** Source specific data */
void *data;
};
/**
@ -208,6 +350,11 @@ void iso_volume_free(struct iso_volume *volume);
*/
void iso_volset_free(struct iso_volset *volume);
/**
* Get a volume from a volume set.
*/
struct iso_volume *iso_volset_get_volume(struct iso_volset *volset, int volnum);
/**
* Get the root directory for a volume.
*/
@ -219,30 +366,65 @@ struct iso_tree_node_dir *iso_volume_get_root(const struct iso_volume *volume);
void iso_volume_set_volume_id(struct iso_volume *volume,
const char *volume_id);
/**
* Get the volume identifier.
* The returned string is owned by libisofs and should not be freed nor
* changed.
*/
const char *iso_volume_get_volume_id(struct iso_volume *volume);
/**
* Fill in the publisher for a volume.
*/
void iso_volume_set_publisher_id(struct iso_volume *volume,
const char *publisher_id);
/**
* Get the publisher of a volume.
* The returned string is owned by libisofs and should not be freed nor
* changed.
*/
const char *iso_volume_get_publisher_id(struct iso_volume *volume);
/**
* Fill in the data preparer for a volume.
*/
void iso_volume_set_data_preparer_id(struct iso_volume *volume,
const char *data_preparer_id);
/**
* Get the data preparer of a volume.
* The returned string is owned by libisofs and should not be freed nor
* changed.
*/
const char *iso_volume_get_data_preparer_id(struct iso_volume *volume);
/**
* Fill in the system id for a volume. Up to 32 characters.
*/
void iso_volume_set_system_id(struct iso_volume *volume,
const char *system_id);
/**
* Get the system id of a volume.
* The returned string is owned by libisofs and should not be freed nor
* changed.
*/
const char *iso_volume_get_system_id(struct iso_volume *volume);
/**
* Fill in the application id for a volume. Up to 128 chars.
*/
void iso_volume_set_application_id(struct iso_volume *volume,
const char *application_id);
/**
* Get the application id of a volume.
* The returned string is owned by libisofs and should not be freed nor
* changed.
*/
const char *iso_volume_get_application_id(struct iso_volume *volume);
/**
* Fill copyright information for the volume. Usually this refers
* to a file on disc. Up to 37 characters.
@ -250,6 +432,13 @@ void iso_volume_set_application_id(struct iso_volume *volume,
void iso_volume_set_copyright_file_id(struct iso_volume *volume,
const char *copyright_file_id);
/**
* Get the copyright information of a volume.
* The returned string is owned by libisofs and should not be freed nor
* changed.
*/
const char *iso_volume_get_copyright_file_id(struct iso_volume *volume);
/**
* Fill abstract information for the volume. Usually this refers
* to a file on disc. Up to 37 characters.
@ -257,6 +446,13 @@ void iso_volume_set_copyright_file_id(struct iso_volume *volume,
void iso_volume_set_abstract_file_id(struct iso_volume *volume,
const char *abstract_file_id);
/**
* Get the abstract information of a volume.
* The returned string is owned by libisofs and should not be freed nor
* changed.
*/
const char *iso_volume_get_abstract_file_id(struct iso_volume *volume);
/**
* Fill biblio information for the volume. Usually this refers
* to a file on disc. Up to 37 characters.
@ -264,6 +460,13 @@ void iso_volume_set_abstract_file_id(struct iso_volume *volume,
void iso_volume_set_biblio_file_id(struct iso_volume *volume,
const char *biblio_file_id);
/**
* Get the biblio information of a volume.
* The returned string is owned by libisofs and should not be freed nor
* changed.
*/
const char *iso_volume_get_biblio_file_id(struct iso_volume *volume);
/**
* Create a bootable volume by adding a El-Torito boot image.
*
@ -336,13 +539,12 @@ el_torito_set_write_boot_info(struct el_torito_boot_image *bootimg);
* \param path The path, in the image, of the file.
*
* \return The node found or NULL.
*
* TODO we need a way to allow developers know which kind of node is.
* Think about this when designing the read api
*/
struct iso_tree_node *iso_tree_volume_path_to_node(struct iso_volume *volume, const char *path);
/**
* TODO I don't like this kind of functions here. I think it should be
* in genisofs
* Add a file or a directory (recursively) to a volume by specifying its path on the volume.
*
* \param volume The volume to add the file to.
@ -356,6 +558,8 @@ struct iso_tree_node *iso_tree_volume_path_to_node(struct iso_volume *volume, co
// const char *path);
/**
* TODO I don't like this kind of functions here. I think it should be
* in genisofs
* Creates a new, empty directory on the volume.
*
* \param volume The volume to add the directory to.
@ -448,6 +652,9 @@ struct iso_tree_node *iso_tree_add_node(struct iso_tree_node_dir *parent,
const char *path);
/**
* TODO I don't like this kind of functions here. I think it should be
* in genisofs
*
* Recursively add an existing directory to the tree.
* Warning: when using this, you'll lose pointers to files or subdirectories.
* If you want to have pointers to all files and directories,
@ -462,11 +669,23 @@ struct iso_tree_node *iso_tree_add_node(struct iso_tree_node_dir *parent,
void iso_tree_radd_dir(struct iso_tree_node_dir *parent, const char *path,
struct iso_tree_radd_dir_behavior *behavior);
/**
* Get the type of an iso_tree_node
*/
enum iso_tree_node_type iso_tree_node_get_type(struct iso_tree_node *node);
/**
* Set the name of a tree node (using the current locale).
*/
void iso_tree_node_set_name(struct iso_tree_node *node, const char *name);
/**
* Get the name of a tree node (using the current locale).
* The returned string belongs to the node and should not be modified nor
* freed. Use strdup if you really need your own copy.
*/
const char *iso_tree_node_get_name(struct iso_tree_node *node);
/**
* Set if the node will be hidden in RR/ISO tree, Joliet tree or both.
*
@ -485,18 +704,37 @@ void iso_tree_node_set_name(struct iso_tree_node *node, const char *name);
*/
void iso_tree_node_set_hidden(struct iso_tree_node *node, int hide_attrs);
/**
* Check if a node will be hidden in RR/ISO tree, Joliet tree or both.
*
* @return
* 0 if the node won't be hidden, otherwise you can AND the return value
* with hide_node_flag's to get in what trees the node will be hidden.
*/
int iso_tree_node_is_hidden(struct iso_tree_node *node);
/**
* Set the group id for the node. This attribute is only useful when
* Rock Ridge extensions are enabled.
*/
void iso_tree_node_set_gid(struct iso_tree_node *node, gid_t gid);
/**
* Get the group id of the node.
*/
gid_t iso_tree_node_get_gid(struct iso_tree_node *node);
/**
* Set the user id for the node. This attribute is only useful when
* Rock Ridge extensions are enabled.
*/
void iso_tree_node_set_uid(struct iso_tree_node *node, uid_t uid);
/**
* Get the user id of the node.
*/
uid_t iso_tree_node_get_uid(struct iso_tree_node *node);
/**
* Set the permissions for the node. This attribute is only useful when
* Rock Ridge extensions are enabled.
@ -507,6 +745,9 @@ void iso_tree_node_set_uid(struct iso_tree_node *node, uid_t uid);
*/
void iso_tree_node_set_permissions(struct iso_tree_node *node, mode_t mode);
/** Get the permissions for the node */
mode_t iso_tree_node_get_permissions(struct iso_tree_node *node);
/**
* Sets the order in which a node will be written on image. High weihted files
* will be written first, so in a disc them will be written near the center.
@ -519,6 +760,139 @@ void iso_tree_node_set_permissions(struct iso_tree_node *node, mode_t mode);
*/
void iso_tree_node_set_sort_weight(struct iso_tree_node *node, int w);
/**
* Sets the destination of a symbolic link
*/
void iso_tree_node_symlink_set_dest(struct iso_tree_node_symlink *node, const char *dest);
/**
* Get the destination of a symbolic link.
* The returned string is owned by libisofs and should not be freed nor modified.
*/
const char *iso_tree_node_symlink_get_dest(struct iso_tree_node_symlink *node);
/**
* Get an iterator for the children of the given dir.
* You can iterate over the children with iso_tree_iter_next. When finished,
* you should free the iterator with iso_tree_iter_free.
* You musn't delete a child of the same dir, using iso_tree_node_take() or
* iso_tree_node_remove(), while you're using the iterator. You can use
* iso_tree_node_take_iter() or iso_tree_node_remove_iter() instead.
*
* The usage of an iterator is:
*
* struct iso_tree_iter *iter;
* struct iso_tree_node *node;
* iter = iso_tree_node_children(dir);
* while ( (node = iso_tree_iter_next(iter)) != NULL ) {
* // do something with the child
* }
* iso_tree_iter_free(iter);
*
* An iterator is intended to be used in a single iteration over the
* children of a dir. Thus, it should be treated as a temporary object,
* and free as soon as possible.
*/
struct iso_tree_iter *iso_tree_node_children(struct iso_tree_node_dir *dir);
/**
* Get the next child.
* Take care that the node is owned by libisofs, and will be freed whit the
* tree it belongs. If you want your own ref to it, call iso_tree_node_ref()
* on it.
* This returns NULL if no more children are available.
*/
struct iso_tree_node *iso_tree_iter_next(struct iso_tree_iter *iter);
/** Free an iteration */
void iso_tree_iter_free(struct iso_tree_iter *iter);
/**
* Removes a child from a directory.
* The child is not freed, so you will become the owner of the node. Later
* you can add the node to another dir (calling iso_tree_add_child), or free
* it if you don't need it (with iso_tree_free).
*
* @return 0 on success, -1 if the node doesn't belong to the dir.
*/
int iso_tree_node_take(struct iso_tree_node_dir *dir,
struct iso_tree_node *node);
/**
* Removes a child from a directory and free (unref) it.
* If you want to keep the child alive, you need to iso_tree_node_ref() it
* before this call, but in that case iso_tree_node_take() is a better
* alternative.
*
* @return 0 on success, -1 if the node doesn't belong to the dir (in this
* last case the node is not freed).
*/
int iso_tree_node_remove(struct iso_tree_node_dir *dir,
struct iso_tree_node *node);
/**
* Removes a child from a directory during an iteration, without freeing it.
* It's like iso_tree_node_take(), but to be used during a directory
* iteration.
* The node removed will be the last returned by the iteration.
*
* The behavior on two call to this function without calling iso_tree_iter_next
* between then is undefined, and should never occur. (TODO protect against this?)
*
* @return 0 on success, < 0 on an invalid usage, i.e., if the user call this
* before an inicial iso_tree_iter_next() or if last
* iso_tree_iter_next() has returned NULL.
*/
int iso_tree_node_take_iter(struct iso_tree_iter *iter);
/**
* Removes a child from a directory during an iteration and free it.
* It's like iso_tree_node_remove(), but to be used during a directory
* iteration.
* The node removed will be the last returned by the iteration.
*
* The behavior on two call to this function without calling iso_tree_iter_next
* between then is undefined, and should never occur. (TODO protect against this?)
*
* @return 0 on success, < 0 on an invalid usage, i.e., if the user call this
* before an inicial iso_tree_iter_next() or if last
* iso_tree_iter_next() has returned NULL.
*/
int iso_tree_node_remove_iter(struct iso_tree_iter *iter);
/*
* Get the parent of the given iso tree node.
* This returns NULL if the node is the root of the tree, or is a node
* that doesn't pertain to any tree (it was removed/take)
*/
struct iso_tree_node_dir *iso_tree_node_get_parent(struct iso_tree_node *node);
/**
* Adds a child to a directory.
* The child will be freed when the parent is freed, so you must be the
* owner of the child (maybe calling iso_tree_node_ref) before calling this.
*
* \pre parent has no child with the same name as \p child
*/
void iso_tree_add_child(struct iso_tree_node_dir *parent,
struct iso_tree_node *child);
/**
* Increments the reference counting of the given node.
* If you call this, you must remember call iso_tree_free when the
* node is no more needed.
*/
void iso_tree_node_ref(struct iso_tree_node *node);
/**
* Recursively free a directory.
*
* \param root The root of the directory heirarchy to free.
*
* \pre \p root is non-NULL.
*/
void iso_tree_free(struct iso_tree_node *root);
/**
* Recursively print a directory to stdout.
* \param spaces The initial number of spaces on the left. Set to 0 if you
@ -541,4 +915,22 @@ void iso_tree_print(const struct iso_tree_node *root, int spaces);
struct burn_source* iso_source_new_ecma119(struct iso_volset *volumeset,
struct ecma119_source_opts *opts);
/**
* Creates a new data source from the given file.
*
* Returns NULL on error
*/
struct data_source *data_source_from_file(const char *path);
/** Free a given data source (decrease its refcount and maybe free it) */
void data_source_free(struct data_source*);
/**
* Read an existing ISO image.
*
* TODO documentar
*/
struct iso_volset *iso_volset_read(struct data_source *src,
struct ecma119_read_opts *opts);
#endif /* LIBISO_LIBISOFS_H */

View File

@ -14,7 +14,7 @@
#include <unistd.h>
#include <sys/stat.h>
/** See IEEE P1281 Draft Version 1.12/5.5 FIXME: this is rockridge */
/** See IEEE P1281 Draft Version 1.12/5.5 */
void
rrip_add_ER(struct ecma119_write_target *t, struct ecma119_tree_node *dir)
{

View File

@ -53,6 +53,7 @@ iso_tree_new_root()
root = calloc(1, sizeof(struct iso_tree_node_dir));
set_default_stat(&root->node.attrib);
root->node.refcount = 1;
root->node.attrib.st_mode = S_IFDIR | 0777;
root->node.type = LIBISO_NODE_DIR;
return root;
@ -85,8 +86,9 @@ iso_tree_add_file(struct iso_tree_node_dir *parent, const char *path)
f = calloc(1, sizeof(struct iso_tree_node_file));
/* fill fields */
f->node.refcount = 1;
f->node.attrib = st;
f->path = strdup(path);
f->loc.path = strdup(path);
f->node.type = LIBISO_NODE_FILE;
p = strdup(path); /* because basename() might modify its arg */
@ -111,7 +113,8 @@ iso_tree_add_symlink(struct iso_tree_node_dir *parent,
/* fill fields */
set_default_stat(&link->node.attrib);
link->node.attrib.st_mode |= S_IFLNK;//TODO Not needed
link->node.refcount = 1;
link->node.attrib.st_mode |= S_IFLNK;
link->node.name = strdup(name);
link->node.type = LIBISO_NODE_SYMLINK;
link->dest = strdup(dest);
@ -132,6 +135,7 @@ iso_tree_add_dir(struct iso_tree_node_dir *parent,
dir = calloc(1, sizeof(struct iso_tree_node_dir));
dir->node.refcount = 1;
dir->node.attrib = parent->node.attrib;
dir->node.type = LIBISO_NODE_DIR;
dir->node.name = strdup(name);
@ -140,6 +144,13 @@ iso_tree_add_dir(struct iso_tree_node_dir *parent,
return dir;
}
enum iso_tree_node_type
iso_tree_node_get_type(struct iso_tree_node *node)
{
assert(node);
return node->type;
}
void
iso_tree_node_set_name(struct iso_tree_node *node, const char *name)
{
@ -147,6 +158,13 @@ iso_tree_node_set_name(struct iso_tree_node *node, const char *name)
node->name = strdup(name);
}
const char *
iso_tree_node_get_name(struct iso_tree_node *node)
{
assert(node);
return node->name;
}
void
iso_tree_node_set_hidden(struct iso_tree_node *node, int hide_attrs)
{
@ -154,6 +172,13 @@ iso_tree_node_set_hidden(struct iso_tree_node *node, int hide_attrs)
node->hide_flags = hide_attrs;
}
int
iso_tree_node_is_hidden(struct iso_tree_node *node)
{
assert(node);
return node->hide_flags;
}
void
iso_tree_node_set_gid(struct iso_tree_node *node, gid_t gid)
{
@ -161,6 +186,13 @@ iso_tree_node_set_gid(struct iso_tree_node *node, gid_t gid)
node->attrib.st_gid = gid;
}
gid_t
iso_tree_node_get_gid(struct iso_tree_node *node)
{
assert(node);
return node->attrib.st_gid;
}
void
iso_tree_node_set_uid(struct iso_tree_node *node, uid_t uid)
{
@ -168,6 +200,13 @@ iso_tree_node_set_uid(struct iso_tree_node *node, uid_t uid)
node->attrib.st_uid = uid;
}
uid_t
iso_tree_node_get_uid(struct iso_tree_node *node)
{
assert(node);
return node->attrib.st_uid;
}
void
iso_tree_node_set_permissions(struct iso_tree_node *node, mode_t mode)
{
@ -176,6 +215,13 @@ iso_tree_node_set_permissions(struct iso_tree_node *node, mode_t mode)
(mode & ~S_IFMT);
}
mode_t
iso_tree_node_get_permissions(struct iso_tree_node *node)
{
assert(node);
return node->attrib.st_mode & ~S_IFMT;
}
void
iso_tree_node_set_sort_weight(struct iso_tree_node *node, int w)
{
@ -194,6 +240,22 @@ iso_tree_node_set_sort_weight(struct iso_tree_node *node, int w)
}
}
void
iso_tree_node_symlink_set_dest(struct iso_tree_node_symlink *node,
const char *dest)
{
assert(node && dest);
free(node->dest);
node->dest = strdup(dest);
}
const char *
iso_tree_node_symlink_get_dest(struct iso_tree_node_symlink *node)
{
assert(node);
return node->dest;
}
struct iso_tree_node*
iso_tree_add_node(struct iso_tree_node_dir *parent,
const char *path)
@ -255,28 +317,172 @@ iso_tree_add_node(struct iso_tree_node_dir *parent,
return node;
}
struct iso_tree_iter *
iso_tree_node_children(struct iso_tree_node_dir *dir)
{
struct iso_tree_iter *iter;
assert(dir);
iter = malloc(sizeof(struct iso_tree_iter));
iter->dir = dir;
iter->index = -1;
return iter;
}
struct iso_tree_node *
iso_tree_iter_next(struct iso_tree_iter *iter)
{
assert(iter);
if ( ++iter->index < iter->dir->nchildren )
return iter->dir->children[iter->index];
else
return NULL;
}
void
iso_tree_iter_free(struct iso_tree_iter *iter)
{
free(iter);
}
int
iso_tree_node_take(struct iso_tree_node_dir *dir, struct iso_tree_node *node)
{
int i;
assert(dir && node);
/* search for the node in the dir */
for (i = 0; i < dir->nchildren; ++i) {
if ( dir->children[i] == node )
break;
}
if (i < dir->nchildren) {
int j;
for (j = i+1; j < dir->nchildren; ++j) {
dir->children[j-1] = dir->children[j];
}
--dir->nchildren;
dir->children = realloc(dir->children, dir->nchildren * sizeof(void*));
node->parent = NULL;
return 0;
} else {
/* the node doesn't exist on dir */
return -1;
}
}
int
iso_tree_node_remove(struct iso_tree_node_dir *dir, struct iso_tree_node *node)
{
int res;
assert(dir && node);
res = iso_tree_node_take(dir, node);
if (!res)
iso_tree_free(node);
return res;
}
int
iso_tree_node_take_iter(struct iso_tree_iter *iter)
{
int j;
struct iso_tree_node_dir *dir;
struct iso_tree_node *node;
assert(iter);
dir = iter->dir;
if (iter->index < 0)
return -1; /* index before beginning */
if (iter->index >= dir->nchildren)
return -2; /* index after end */
node = dir->children[iter->index];
node->parent = NULL;
for (j = iter->index+1; j < dir->nchildren; ++j) {
dir->children[j-1] = dir->children[j];
}
--dir->nchildren;
dir->children = realloc(dir->children, dir->nchildren * sizeof(void*));
/* update iter index */
--iter->index;
return 0;
}
int
iso_tree_node_remove_iter(struct iso_tree_iter *iter)
{
int j;
struct iso_tree_node_dir *dir;
struct iso_tree_node *node;
assert(iter);
dir = iter->dir;
if (iter->index < 0)
return -1; /* index before beginning */
if (iter->index >= dir->nchildren)
return -2; /* index after end */
node = dir->children[iter->index];
for (j = iter->index+1; j < dir->nchildren; ++j) {
dir->children[j-1] = dir->children[j];
}
--dir->nchildren;
dir->children = realloc(dir->children, dir->nchildren * sizeof(void*));
/* update iter index */
--iter->index;
/* and free node */
node->parent = NULL;
iso_tree_free(node);
return 0;
}
struct iso_tree_node_dir *
iso_tree_node_get_parent(struct iso_tree_node *node)
{
assert(node);
return node->parent;
}
void
iso_tree_node_ref(struct iso_tree_node *node)
{
++node->refcount;
}
void
iso_tree_free(struct iso_tree_node *root)
{
if ( ISO_ISDIR(root) ) {
size_t i;
struct iso_tree_node_dir *dir;
dir = (struct iso_tree_node_dir *) root;
for (i=0; i < dir->nchildren; i++) {
iso_tree_free(dir->children[i]);
if (--root->refcount < 1) {
if ( ISO_ISDIR(root) ) {
size_t i;
struct iso_tree_node_dir *dir;
dir = (struct iso_tree_node_dir *) root;
for (i=0; i < dir->nchildren; i++) {
iso_tree_free(dir->children[i]);
}
free(dir->children);
} else if ( ISO_ISLNK(root) ) {
struct iso_tree_node_symlink *link;
link = (struct iso_tree_node_symlink *) root;
free(link->dest);
} else if ( ISO_ISREG(root) ) {
struct iso_tree_node_file *file;
file = (struct iso_tree_node_file *) root;
if (root->procedence == LIBISO_NEW)
free(file->loc.path);
}
free(dir->children);
} else if ( ISO_ISLNK(root) ) {
struct iso_tree_node_symlink *link;
link = (struct iso_tree_node_symlink *) root;
free(link->dest);
} else if ( ISO_ISREG(root) ) {
struct iso_tree_node_file *file;
file = (struct iso_tree_node_file *) root;
free(file->path);
free(root->name);
free(root);
}
free(root->name);
free(root);
}
static void
@ -352,8 +558,6 @@ iso_tree_radd_dir(struct iso_tree_node_dir *parent, const char *path,
/* clear hashtable */
iso_exclude_empty(&table);
return dir;
}
void

View File

@ -8,7 +8,7 @@
* (for multisession).
*
* This tree preserves as much information as it can about the files; names
* are stored in wchar_t and we preserve POSIX attributes. This tree does
* are stored in UTF-8 and we preserve POSIX attributes. This tree does
* *not* include information that is necessary for writing out, for example,
* an ISO level 1 tree. That information will go in a different tree because
* the structure is sufficiently different.
@ -20,42 +20,29 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <wchar.h>
#include "libisofs.h"
//enum file_location {
// LIBISO_FILESYS,
// LIBISO_PREVSESSION,
// LIBISO_NONE /**< for files/dirs that were added with
// * iso_tree_add_new_XXX. */
//};
/**
* This tells us where to read the data from a file. Either we read from the
* local filesystem or we just point to the block on a previous session.
*/
//struct iso_file_location
//{
// enum file_location type;
// /* union {*/
// char *path; /* in the current locale */
// uint32_t block;
// /* };*/
//};
enum iso_tree_node_type {
LIBISO_NODE_DIR,
LIBISO_NODE_FILE,
LIBISO_NODE_SYMLINK,
LIBISO_NODE_BOOTCATALOG
};
/**
* A node in the filesystem tree.
*/
struct iso_tree_node
{
/*
* Reference counter:
* - When created, refcount is set to 1
* - One node is automatically free when free the tree (i.e., dir) it
* belongs, and the tree is automatically freed when the volume it
* belongs is also freed.
* - If the user deon't add the tree to a volume, (s)he has to free the
* tree.
* - If the user doesn't add a node to a tree (dir), for example after
* taken it with iso_tree_node_take(), it should free the node when
* no more needed.
* - If the user wants an own ref, it should call iso_tree_node_ref()
* function to get that ref, and free the node when no more needed.
*/
int refcount;
struct iso_tree_node_dir *parent;
char *name;
struct stat attrib; /**< The POSIX attributes of this node as
@ -63,7 +50,8 @@ struct iso_tree_node
int hide_flags; /**< If the node is to be hidden in RR/ISO or
* Joilet tree */
enum iso_tree_node_type type;
enum tree_node_from procedence; /**< Procedence of the node. */
enum iso_tree_node_type type; /**< Type of the node. */
};
/**
@ -73,20 +61,16 @@ struct iso_tree_node_file
{
struct iso_tree_node node;
char *path; /**< the path of the file on local filesystem */
int sort_weight; /**< It sorts the order in which the file data is
* written to the CD image. Higher weighting files
* are written at the beginning of image */
/* when read from an existing ISO image, we need to store the
* block where file contents are written, and not the path.
* Maybe instead of a char *path we will need to go back to
* struct iso_file_location loc;
*/
/* struct iso_file_location loc; */
/**< Only used for regular files and symbolic
* links (ie. files for which we might have to
* copy data). */
union {
char *path; /**< the path of the file on local filesystem */
uint32_t block; /**< If the file is from a previous session.
* Maybe we can put this in iso_tree_node later.
*/
} loc;
};
/**
@ -112,19 +96,13 @@ struct iso_tree_node_dir
};
/**
* Recursively free a directory.
*
* \param root The root of the directory heirarchy to free.
*
* \pre \p root is non-NULL.
* An iterator for directory children.
*/
void iso_tree_free(struct iso_tree_node *root);
/**
* Adds a child to a directory
*/
void iso_tree_add_child(struct iso_tree_node_dir *parent,
struct iso_tree_node *child);
struct iso_tree_iter
{
struct iso_tree_node_dir *dir;
int index;
};
/**
* A function that prints verbose information about a directory.

View File

@ -546,6 +546,7 @@ iso_r_fileid(const char *src_arg, const char *icharset, int flag)
char *dest;
char *dot;
int lname, lext, lnname, lnext, pos, i;
size_t max;
size_t size = flag & (1<<1) ? 37 : 33;
@ -570,7 +571,7 @@ iso_r_fileid(const char *src_arg, const char *icharset, int flag)
/* no relaxed filenames */
dot = strrchr(src, '.');
size_t max = size == 37 ? 36 : 30;
max = size == 37 ? 36 : 30;
/* Since the maximum length can be divided freely over the name and
extension, we need to calculate their new lengths (lnname and
lnext). If the original filename is too long, we start by trimming
@ -713,13 +714,12 @@ time_t iso_datetime_read_7(const uint8_t *buf)
struct tm tm;
tm.tm_year = buf[0];
tm.tm_mon = buf[1] + 1;
tm.tm_mon = buf[1] - 1;
tm.tm_mday = buf[2];
tm.tm_hour = buf[3];
tm.tm_min = buf[4];
tm.tm_sec = buf[5];
return mktime(&tm) - buf[6] * 60 * 60;
return timegm(&tm) - buf[6] * 60 * 15;
}
void iso_datetime_17(unsigned char *buf, time_t t)
@ -771,7 +771,7 @@ time_t iso_datetime_read_17(const uint8_t *buf)
tm.tm_year -= 1900;
tm.tm_mon -= 1;
return mktime(&tm) - buf[16] * 60 * 60;
return timegm(&tm) - buf[16] * 60 * 15;
}
size_t ucslen(const uint16_t *str)
@ -832,11 +832,24 @@ uint32_t iso_read_msb(const uint8_t *buf, int bytes)
return ret;
}
uint32_t iso_read_bb(const uint8_t *buf, int bytes)
uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error)
{
uint32_t v1 = iso_read_lsb(buf, bytes);
uint32_t v2 = iso_read_msb(buf+bytes, bytes);
assert(v1 == v2);
if (error) {
uint32_t v2 = iso_read_msb(buf+bytes, bytes);
if (v1 != v2)
*error = 1;
}
return v1;
}
char *strcopy(const char *buf, size_t len)
{
char *str;
str = malloc( (len+1) * sizeof(char) );
strncpy(str, buf, len);
str[len] = '\0';
return str;
}

View File

@ -112,7 +112,12 @@ void iso_bb(uint8_t *buf, uint32_t num, int bytes);
uint32_t iso_read_lsb(const uint8_t *buf, int bytes);
uint32_t iso_read_msb(const uint8_t *buf, int bytes);
uint32_t iso_read_bb(const uint8_t *buf, int bytes);
/**
* if error != NULL it will be set to 1 if LSB and MSB integers
* don't match
*/
uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error);
/** Records the date/time into a 7 byte buffer (9.1.5) */
void iso_datetime_7(uint8_t *buf, time_t t);
@ -133,4 +138,12 @@ size_t ucslen(const uint16_t *str);
*/
int ucscmp(const uint16_t *s1, const uint16_t *s2);
/**
* Copy up to \p len chars from \p buf and return this newly allocated
* string. The new string is null-terminated.
* TODO it would be great to return NULL is the original string was all
* white spaces.
*/
char *strcopy(const char *buf, size_t len);
#endif /* LIBISO_UTIL_H */

View File

@ -1,6 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* vim: set ts=8 sts=8 sw=8 noet : */
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>
@ -38,6 +39,16 @@ iso_volset_free(struct iso_volset *volset)
}
}
struct iso_volume *
iso_volset_get_volume(struct iso_volset *volset, int volnum)
{
assert(volset);
if (volnum < volset->volset_size)
return volset->volume[volnum];
else
return NULL;
}
struct iso_volume*
iso_volume_new(const char *volume_id,
const char *publisher_id,
@ -95,65 +106,130 @@ iso_volume_free(struct iso_volume *volume)
struct iso_tree_node_dir *
iso_volume_get_root(const struct iso_volume *volume)
{
assert(volume);
return volume->root;
}
void iso_volume_set_volume_id(struct iso_volume *volume,
const char *volume_id)
{
assert(volume);
free(volume->volume_id);
volume->volume_id = strdup(volume_id);
}
const char *
iso_volume_get_volume_id(struct iso_volume *volume)
{
assert(volume);
return volume->volume_id;
}
void iso_volume_set_publisher_id(struct iso_volume *volume,
const char *publisher_id)
{
assert(volume);
free(volume->publisher_id);
volume->publisher_id = strdup(publisher_id);
}
const char *
iso_volume_get_publisher_id(struct iso_volume *volume)
{
assert(volume);
return volume->publisher_id;
}
void iso_volume_set_data_preparer_id(struct iso_volume *volume,
const char *data_preparer_id)
{
assert(volume);
free(volume->data_preparer_id);
volume->data_preparer_id = strdup(data_preparer_id);
}
const char *
iso_volume_get_data_preparer_id(struct iso_volume *volume)
{
assert(volume);
return volume->data_preparer_id;
}
void iso_volume_set_system_id(struct iso_volume *volume,
const char *system_id)
{
assert(volume);
free(volume->system_id);
volume->system_id = strdup(system_id);
}
const char *
iso_volume_get_system_id(struct iso_volume *volume)
{
assert(volume);
return volume->system_id;
}
void iso_volume_set_application_id(struct iso_volume *volume,
const char *application_id)
{
assert(volume);
free(volume->application_id);
volume->application_id = strdup(application_id);
}
const char *
iso_volume_get_application_id(struct iso_volume *volume)
{
assert(volume);
return volume->application_id;
}
void iso_volume_set_copyright_file_id(struct iso_volume *volume,
const char *copyright_file_id)
{
assert(volume);
free(volume->copyright_file_id);
volume->copyright_file_id = strdup(copyright_file_id);
}
const char *
iso_volume_get_copyright_file_id(struct iso_volume *volume)
{
assert(volume);
return volume->copyright_file_id;
}
void iso_volume_set_abstract_file_id(struct iso_volume *volume,
const char *abstract_file_id)
{
assert(volume);
free(volume->abstract_file_id);
volume->abstract_file_id = strdup(abstract_file_id);
}
const char *
iso_volume_get_abstract_file_id(struct iso_volume *volume)
{
assert(volume);
return volume->abstract_file_id;
}
void iso_volume_set_biblio_file_id(struct iso_volume *volume,
const char *biblio_file_id)
{
assert(volume);
free(volume->biblio_file_id);
volume->biblio_file_id = strdup(biblio_file_id);
}
const char *
iso_volume_get_biblio_file_id(struct iso_volume *volume)
{
assert(volume);
return volume->biblio_file_id;
}
struct iso_tree_node *
iso_tree_volume_path_to_node(struct iso_volume *volume, const char *path)
{

View File

@ -43,6 +43,7 @@ void help()
int main(int argc, char **argv)
{
struct ecma119_source_opts opts;
struct iso_volset *volset;
struct iso_volume *volume;
struct iso_tree_node_dir *root;
@ -50,6 +51,7 @@ int main(int argc, char **argv)
unsigned char buf[2048];
FILE *fd;
int c;
int constraints;
struct iso_tree_radd_dir_behavior behav = {0,0,0};
int level=1, flags=0;
char *boot_img = NULL;
@ -104,15 +106,15 @@ int main(int argc, char **argv)
if ( boot_img ) {
/* adds El-Torito boot info. Tunned for isolinux */
struct el_torito_boot_image *bootimg;
struct iso_tree_node_dir *boot = (struct iso_tree_node_dir *)
iso_tree_volume_path_to_node(volume, "isolinux");
struct iso_tree_node *img = iso_tree_volume_path_to_node(volume, boot_img);
if (!img) {
err(1, "boot image patch is not valid");
}
struct el_torito_boot_image *bootimg =
iso_volume_create_boot_catalog(volume, img, ELTORITO_NO_EMUL,
boot, "boot.cat");
bootimg = iso_volume_create_boot_catalog(volume, img, ELTORITO_NO_EMUL,
boot, "boot.cat");
el_torito_set_load_size(bootimg, 4);
el_torito_set_write_boot_info(bootimg);
}
@ -123,12 +125,16 @@ int main(int argc, char **argv)
iso_volume_set_application_id(volume, "Libburnia");
iso_volume_set_copyright_file_id(volume, "LICENSE");
int constraints = ECMA119_OMIT_VERSION_NUMBERS |
constraints = ECMA119_OMIT_VERSION_NUMBERS |
ECMA119_37_CHAR_FILENAMES | ECMA119_NO_DIR_REALOCATION |
ECMA119_RELAXED_FILENAMES;
struct ecma119_source_opts opts = {0, level, flags, constraints, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, "UTF-8", "UTF-8"};
memset(&opts, 0, sizeof(struct ecma119_source_opts));
opts.level = level;
opts.flags = flags;
opts.relaxed_constraints = 0;//constraints;
opts.input_charset = "UTF-8";
opts.ouput_charset = "UTF-8";
src = iso_source_new_ecma119(volset, &opts);

View File

@ -8,6 +8,8 @@ static void create_test_suite()
add_file_hashtable_suite();
add_ecma119_tree_suite();
add_volume_suite();
add_data_source_suite();
add_isoread_suite();
}
int main(int argc, char **argv)

View File

@ -21,4 +21,8 @@ void add_ecma119_tree_suite();
void add_volume_suite();
void add_data_source_suite();
void add_isoread_suite();
#endif /*TEST_H_*/

View File

@ -1,17 +1,12 @@
/*
* Unit test for ecma119_tree.h
*/
//FIXME not implemented yet!!
#include "libisofs.h"
#include "tree.h"
#include "test.h"
//#include "ecma119_tree.h"
/*
* Also including C file, testing internal functions
*/
//#include "ecma119_tree.c"
#include "ecma119.h"
#include "ecma119_tree.h"
#include <assert.h>
#include <stdio.h>
@ -19,16 +14,109 @@
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
struct ecma119_write_target t;
static void test_calc_dirent_len()
static void reset_write_target()
{
/* inititalize t with default values */
t.root = NULL;
t.joliet_root = NULL;
t.volset = NULL;
t.volnum = time(NULL);
t.now;
t.total_size = 0;
t.vol_space_size = 0;
t.rockridge = 0;
t.joliet = 0;
t.iso_level = 1;
t.eltorito = 0;
t.relaxed_constraints = 0;
t.catalog = NULL;
t.replace_mode = 0;
t.dir_mode = 0777;
t.file_mode = 0777;
t.gid = 0;
t.uid = 0;
t.input_charset = "UTF-8";
t.ouput_charset = "UTF-8";
t.cache_inodes = 0;
t.sort_files = 0;
t.ino = 0;
t.curblock = 0;
t.block_size = 2048;
t.path_table_size = 0;
t.path_table_size_joliet = 0;
t.l_path_table_pos = 0;
t.m_path_table_pos = 0;
t.l_path_table_pos_joliet = 0;
t.m_path_table_pos_joliet = 0;
t.total_dir_size = 0;
t.total_dir_size_joliet = 0;
t.dirlist = NULL;
t.pathlist = NULL;
t.dirlist_len = 0;
t.file_table = NULL;
t.filelist = NULL;
t.filelist_len = 0;
t.curfile = 0;
t.dirlist_joliet = NULL;
t.pathlist_joliet = NULL;
t.dirlist_len_joliet = 0;
t.state = ECMA119_WRITE_SYSTEM_AREA;
}
void test_create_tree_only_root()
{
struct iso_tree_node *root;
struct ecma119_tree_node *node;
reset_write_target();
root = (struct iso_tree_node*) iso_tree_new_root();
node = ecma119_tree_create(&t, root);
CU_ASSERT_PTR_NOT_NULL(node);
/* root has no name */
CU_ASSERT_PTR_NULL(node->iso_name);
CU_ASSERT_PTR_NULL(node->full_name);
/* target root has been set */
CU_ASSERT_PTR_EQUAL(t.root, node);
CU_ASSERT_PTR_EQUAL(node->target, &t);
CU_ASSERT_PTR_NULL(node->parent);
CU_ASSERT_EQUAL(node->attrib.st_mode, root->attrib.st_mode);
CU_ASSERT_EQUAL(node->attrib.st_uid, root->attrib.st_uid);
CU_ASSERT_EQUAL(node->attrib.st_gid, root->attrib.st_gid);
/* the node is a directory */
CU_ASSERT_EQUAL(node->type, ECMA119_DIR);
CU_ASSERT_EQUAL(node->info.dir.nchildren, 0);
iso_tree_free((struct iso_tree_node *)root);
ecma119_tree_free(node);
}
void add_ecma119_tree_suite()
{
CU_pSuite pSuite = CU_add_suite("Ecma119TreeSuite", NULL, NULL);
//CU_add_test(pSuite, "test of calc_dirent_len()", test_calc_dirent_len);
CU_add_test(pSuite, "test of ecma119_tree_create() with only root dir", test_create_tree_only_root);
//CU_add_test(pSuite, "test of create_dir()", test_create_dir);
}

View File

@ -21,7 +21,7 @@ static void test_iso_file_new()
file->node.attrib.st_size = 12;
file->node.attrib.st_dev = 15;
file->node.attrib.st_ino = 204;
file->path = "/tmp/filename";
file->loc.path = "/tmp/filename";
file->sort_weight = 1;
iso = iso_file_new(file);
@ -56,7 +56,7 @@ static void test_add_lookup()
file1->node.name = "fileName";
file1->node.attrib.st_dev = 15;
file1->node.attrib.st_ino = 204;
file1->path = "/tmp/filename";
file1->loc.path = "/tmp/filename";
iso1 = iso_file_new(file1);
@ -72,7 +72,7 @@ static void test_add_lookup()
file2->node.name = "fileName2";
file2->node.attrib.st_dev = 152;
file2->node.attrib.st_ino = 2042;
file2->path = "/tmp/filename2";
file2->loc.path = "/tmp/filename2";
iso3 = iso_file_new(file2);
r = iso_file_table_add_file(table, iso3);
@ -128,7 +128,7 @@ static void test_cache_inodes()
file1->node.name = "fileName";
file1->node.attrib.st_dev = 15;
file1->node.attrib.st_ino = 204;
file1->path = "/tmp/filename";
file1->loc.path = "/tmp/filename";
iso1 = iso_file_new(file1);
@ -140,7 +140,7 @@ static void test_cache_inodes()
file2->node.name = "another file";
file2->node.attrib.st_dev = 15;
file2->node.attrib.st_ino = 204;
file2->path = "/tmp/another";
file2->loc.path = "/tmp/another";
iso2 = iso_file_new(file2);
/* ensure it's not added again... */
@ -159,7 +159,7 @@ static void test_cache_inodes()
file2->node.name = "different file";
file2->node.attrib.st_dev = 16; /* different dev id */
file2->node.attrib.st_ino = 204;
file2->path = "/tmp/different";
file2->loc.path = "/tmp/different";
iso2 = iso_file_new(file2);
r = iso_file_table_add_file(table, iso2);
@ -195,7 +195,7 @@ static void test_no_cache_inodes()
file1->node.name = "fileName";
file1->node.attrib.st_dev = 15;
file1->node.attrib.st_ino = 204;
file1->path = "/tmp/filename";
file1->loc.path = "/tmp/filename";
iso1 = iso_file_new(file1);
@ -207,7 +207,7 @@ static void test_no_cache_inodes()
file2->node.name = "another file";
file2->node.attrib.st_dev = 15;
file2->node.attrib.st_ino = 204;
file2->path = "/tmp/another";
file2->loc.path = "/tmp/another";
iso2 = iso_file_new(file2);
/* ensure is added */
@ -222,7 +222,7 @@ static void test_no_cache_inodes()
file3->node.name = "different file";
file3->node.attrib.st_dev = 15;
file3->node.attrib.st_ino = 204;
file3->path = "/tmp/filename";
file3->loc.path = "/tmp/filename";
iso3 = iso_file_new(file3);
r = iso_file_table_add_file(table, iso3);
@ -237,12 +237,78 @@ static void test_no_cache_inodes()
free(table);
}
static void test_prev_img_files()
{
struct iso_file_table *table;
struct iso_tree_node_file *file1;
struct iso_tree_node_file *file2;
struct iso_tree_node_file *file3;
struct iso_file *iso1;
struct iso_file *iso2;
struct iso_file *iso3;
int r;
table = iso_file_table_new(0);
CU_ASSERT_PTR_NOT_NULL( table );
CU_ASSERT_FALSE( table->cache_inodes );
CU_ASSERT_EQUAL(table->count, 0);
file1 = calloc(1, sizeof(struct iso_tree_node_file) );
file1->node.name = "fileName";
file1->node.procedence = LIBISO_PREVIMG;
file1->node.attrib.st_dev = 0;
file1->node.attrib.st_ino = 204;
file1->loc.block = 567;
iso1 = iso_file_new(file1);
r = iso_file_table_add_file(table, iso1);
CU_ASSERT_EQUAL(r, 1);
/* another file, different but with the same inode id */
file2 = calloc(1, sizeof(struct iso_tree_node_file) );
file2->node.name = "another file";
file2->node.procedence = LIBISO_PREVIMG;
file2->node.attrib.st_dev = 0;
file2->node.attrib.st_ino = 204;
file2->loc.block = 567;
iso2 = iso_file_new(file2);
/* ensure is not added */
r = iso_file_table_add_file(table, iso2);
CU_ASSERT_EQUAL(r, 0);
iso3 = iso_file_table_lookup(table, file2);
CU_ASSERT_PTR_EQUAL(iso3, iso1);
/* and now a file added new */
file3 = calloc(1, sizeof(struct iso_tree_node_file) );
file3->node.name = "different file";
file3->node.attrib.st_dev = 0;
file3->node.attrib.st_ino = 204;
file3->loc.path = "/tmp/filename";
iso3 = iso_file_new(file3);
/* assert it's added */
r = iso_file_table_add_file(table, iso3);
CU_ASSERT_EQUAL(r, 1);
iso1 = iso_file_table_lookup(table, file3);
CU_ASSERT_PTR_EQUAL(iso1, iso3);
iso_file_table_clear(table);
free(file1);
free(file2);
free(file3);
free(table);
}
void add_file_hashtable_suite()
{
CU_pSuite pSuite = CU_add_suite("FileHashtableSuite", NULL, NULL);
CU_add_test(pSuite, "test of iso_file_new()", test_iso_file_new);
CU_add_test(pSuite, "test of add and lookup", test_add_lookup);
CU_add_test(pSuite, "test with cache_inodes", test_cache_inodes);
CU_add_test(pSuite, "test without cache_inodes", test_no_cache_inodes);
CU_add_test(pSuite, "iso_file_new()", test_iso_file_new);
CU_add_test(pSuite, "add and lookup", test_add_lookup);
CU_add_test(pSuite, "with cache_inodes", test_cache_inodes);
CU_add_test(pSuite, "with files from previous img", test_prev_img_files);
}

View File

@ -2,7 +2,6 @@
* Unit test for tree.h
*/
#include "libisofs.h"
#include "tree.h"
#include "test.h"
@ -56,7 +55,7 @@ static void test_add_file() {
CU_ASSERT_EQUAL(root->nchildren, 1);
CU_ASSERT_PTR_EQUAL(root->children[0], (struct iso_tree_node *)file);
CU_ASSERT_STRING_EQUAL( file->node.name, "README" );
CU_ASSERT_STRING_EQUAL( file->path, "/tmp/libisofs_test/README" );
CU_ASSERT_STRING_EQUAL( file->loc.path, "/tmp/libisofs_test/README" );
CU_ASSERT( S_ISREG(file->node.attrib.st_mode) );
iso_tree_free((struct iso_tree_node *)root);
}
@ -116,7 +115,7 @@ static void test_add_node() {
CU_ASSERT( S_ISREG(node->attrib.st_mode) );
CU_ASSERT( ISO_ISREG(node) );
CU_ASSERT_STRING_EQUAL( node->name, "README" );
CU_ASSERT_STRING_EQUAL( ((struct iso_tree_node_file *) node)->path,
CU_ASSERT_STRING_EQUAL( ((struct iso_tree_node_file *) node)->loc.path,
"/tmp/libisofs_test/README" );
/* test no exiting file */
@ -140,38 +139,6 @@ static void test_add_node() {
iso_tree_free((struct iso_tree_node *)root);
}
static void test_radd_dir() {
struct iso_tree_node_dir *root;
struct iso_tree_node_dir *child;
struct iso_tree_node_file *file;
struct iso_tree_radd_dir_behavior behavior = {0,0,0};
//TODO write really full test
root = iso_tree_new_root();
CU_ASSERT_PTR_NOT_NULL(root);
iso_tree_radd_dir(root, "/tmp/libisofs_test", &behavior);
/* test _root_ children */
/*
child = (struct iso_tree_node_dir *)root->children[0];
CU_ASSERT( S_ISDIR(child->node.attrib.st_mode) );
CU_ASSERT_EQUAL( child->nchildren, 2);
CU_ASSERT_STRING_EQUAL( child->node.name, "dir1" );
child = (struct iso_tree_node_dir *)root->children[1];
CU_ASSERT( S_ISDIR(child->node.attrib.st_mode) );
CU_ASSERT_EQUAL( child->nchildren, 0);
CU_ASSERT_STRING_EQUAL( child->node.name, "dir2" );
file = (struct iso_tree_node_file *)root->children[2];
CU_ASSERT( S_ISREG(file->node.attrib.st_mode) );
CU_ASSERT_STRING_EQUAL( file->node.name, "README" );
*/
//iso_tree_print( (struct iso_tree_node *)root, 4 );
}
static void test_set_name() {
struct iso_tree_node_dir *root;
struct iso_tree_node *node;
@ -202,6 +169,33 @@ static void test_set_name() {
iso_tree_free((struct iso_tree_node *)root);
}
static void test_get_name() {
struct iso_tree_node_dir *root;
struct iso_tree_node *node;
root = iso_tree_new_root();
/* test on a dir */
node = iso_tree_add_node(root, "/tmp/libisofs_test/dir1");
CU_ASSERT_STRING_EQUAL( iso_tree_node_get_name(node), "dir1");
iso_tree_node_set_name(node, "newname");
CU_ASSERT_STRING_EQUAL( iso_tree_node_get_name(node), "newname");
/* test on a link */
node = iso_tree_add_node(root, "/tmp/libisofs_test/link to readme");
CU_ASSERT_STRING_EQUAL( iso_tree_node_get_name(node), "link to readme");
iso_tree_node_set_name(node, "new link name");
CU_ASSERT_STRING_EQUAL( iso_tree_node_get_name(node), "new link name");
/* test on a file */
node = iso_tree_add_node(root, "/tmp/libisofs_test/README");
CU_ASSERT_STRING_EQUAL( iso_tree_node_get_name(node), "README" );
iso_tree_node_set_name(node, "new file name");
CU_ASSERT_STRING_EQUAL( iso_tree_node_get_name(node), "new file name");
iso_tree_free((struct iso_tree_node *)root);
}
static void test_set_hidden() {
struct iso_tree_node_dir *root;
struct iso_tree_node *node;
@ -244,6 +238,45 @@ static void test_set_hidden() {
iso_tree_free((struct iso_tree_node *)root);
}
static void test_is_hidden() {
struct iso_tree_node_dir *root;
struct iso_tree_node *node;
root = iso_tree_new_root();
/* test on a dir */
node = iso_tree_add_node(root, "/tmp/libisofs_test/dir1");
CU_ASSERT_FALSE(iso_tree_node_is_hidden(node));
iso_tree_node_set_hidden(node, LIBISO_HIDE_ON_RR);
CU_ASSERT_EQUAL(iso_tree_node_is_hidden(node), LIBISO_HIDE_ON_RR);
iso_tree_node_set_hidden(node, LIBISO_HIDE_ON_JOLIET);
CU_ASSERT_EQUAL(iso_tree_node_is_hidden(node), LIBISO_HIDE_ON_JOLIET);
iso_tree_node_set_hidden(node, LIBISO_HIDE_ON_RR|LIBISO_HIDE_ON_JOLIET);
CU_ASSERT_EQUAL(iso_tree_node_is_hidden(node), LIBISO_HIDE_ON_RR|LIBISO_HIDE_ON_JOLIET);
/* test on a link */
node = iso_tree_add_node(root, "/tmp/libisofs_test/link to readme");
CU_ASSERT_FALSE(iso_tree_node_is_hidden(node));
iso_tree_node_set_hidden(node, LIBISO_HIDE_ON_RR);
CU_ASSERT_EQUAL(iso_tree_node_is_hidden(node), LIBISO_HIDE_ON_RR);
iso_tree_node_set_hidden(node, LIBISO_HIDE_ON_JOLIET);
CU_ASSERT_EQUAL(iso_tree_node_is_hidden(node), LIBISO_HIDE_ON_JOLIET);
iso_tree_node_set_hidden(node, LIBISO_HIDE_ON_RR|LIBISO_HIDE_ON_JOLIET);
CU_ASSERT_EQUAL(iso_tree_node_is_hidden(node), LIBISO_HIDE_ON_RR|LIBISO_HIDE_ON_JOLIET);
/* test on a file */
node = iso_tree_add_node(root, "/tmp/libisofs_test/README");
CU_ASSERT_FALSE(iso_tree_node_is_hidden(node));
iso_tree_node_set_hidden(node, LIBISO_HIDE_ON_RR);
CU_ASSERT_EQUAL(iso_tree_node_is_hidden(node), LIBISO_HIDE_ON_RR);
iso_tree_node_set_hidden(node, LIBISO_HIDE_ON_JOLIET);
CU_ASSERT_EQUAL(iso_tree_node_is_hidden(node), LIBISO_HIDE_ON_JOLIET);
iso_tree_node_set_hidden(node, LIBISO_HIDE_ON_RR|LIBISO_HIDE_ON_JOLIET);
CU_ASSERT_EQUAL(iso_tree_node_is_hidden(node), LIBISO_HIDE_ON_RR|LIBISO_HIDE_ON_JOLIET);
iso_tree_free((struct iso_tree_node *)root);
}
static void test_set_gid() {
struct iso_tree_node_dir *root;
struct iso_tree_node *node;
@ -275,6 +308,34 @@ static void test_set_gid() {
iso_tree_free((struct iso_tree_node *)root);
}
static void test_get_gid() {
struct iso_tree_node_dir *root;
struct iso_tree_node *node;
gid_t mygid = getgid();
root = iso_tree_new_root();
/* test on a dir */
node = iso_tree_add_node(root, "/tmp/libisofs_test/dir1");
CU_ASSERT_EQUAL(iso_tree_node_get_gid(node), mygid);
iso_tree_node_set_gid(node, 1234);
CU_ASSERT_EQUAL(iso_tree_node_get_gid(node), 1234);
/* test on a link */
node = iso_tree_add_node(root, "/tmp/libisofs_test/link to readme");
CU_ASSERT_EQUAL(iso_tree_node_get_gid(node), mygid);
iso_tree_node_set_gid(node, 1234);
CU_ASSERT_EQUAL(iso_tree_node_get_gid(node), 1234);
/* test on a file */
node = iso_tree_add_node(root, "/tmp/libisofs_test/README");
CU_ASSERT_EQUAL(iso_tree_node_get_gid(node), mygid);
iso_tree_node_set_gid(node, 1234);
CU_ASSERT_EQUAL(iso_tree_node_get_gid(node), 1234);
iso_tree_free((struct iso_tree_node *)root);
}
static void test_set_uid() {
struct iso_tree_node_dir *root;
struct iso_tree_node *node;
@ -308,6 +369,34 @@ static void test_set_uid() {
iso_tree_free((struct iso_tree_node *)root);
}
static void test_get_uid() {
struct iso_tree_node_dir *root;
struct iso_tree_node *node;
uid_t myuid = getuid();
root = iso_tree_new_root();
/* test on a dir */
node = iso_tree_add_node(root, "/tmp/libisofs_test/dir1");
CU_ASSERT_EQUAL(iso_tree_node_get_uid(node), myuid);
iso_tree_node_set_uid(node, 1234);
CU_ASSERT_EQUAL(iso_tree_node_get_uid(node), 1234);
/* test on a link */
node = iso_tree_add_node(root, "/tmp/libisofs_test/link to readme");
CU_ASSERT_EQUAL(iso_tree_node_get_uid(node), myuid);
iso_tree_node_set_uid(node, 1234);
CU_ASSERT_EQUAL(iso_tree_node_get_uid(node), 1234);
/* test on a file */
node = iso_tree_add_node(root, "/tmp/libisofs_test/README");
CU_ASSERT_EQUAL(iso_tree_node_get_uid(node), myuid);
iso_tree_node_set_uid(node, 1234);
CU_ASSERT_EQUAL(iso_tree_node_get_uid(node), 1234);
iso_tree_free((struct iso_tree_node *)root);
}
static void test_set_permissions() {
struct iso_tree_node_dir *root;
struct iso_tree_node *node;
@ -350,6 +439,45 @@ static void test_set_permissions() {
iso_tree_free((struct iso_tree_node *)root);
}
static void test_get_permissions() {
struct iso_tree_node_dir *root;
struct iso_tree_node *node;
root = iso_tree_new_root();
/* test on a dir */
node = iso_tree_add_node(root, "/tmp/libisofs_test/dir1");
CU_ASSERT_EQUAL(iso_tree_node_get_permissions(node), 0755);
iso_tree_node_set_permissions(node, 0777);
CU_ASSERT_EQUAL(iso_tree_node_get_permissions(node), 0777);
iso_tree_node_set_permissions(node, 0744);
CU_ASSERT_EQUAL(iso_tree_node_get_permissions(node), 0744);
iso_tree_node_set_permissions(node, 0411);
CU_ASSERT_EQUAL(iso_tree_node_get_permissions(node), 0411);
/* test on a link */
node = iso_tree_add_node(root, "/tmp/libisofs_test/link to readme");
CU_ASSERT_EQUAL(iso_tree_node_get_permissions(node), 0777);
iso_tree_node_set_permissions(node, 0555);
CU_ASSERT_EQUAL(iso_tree_node_get_permissions(node), 0555);
iso_tree_node_set_permissions(node, 0744);
CU_ASSERT_EQUAL(iso_tree_node_get_permissions(node), 0744);
iso_tree_node_set_permissions(node, 0411);
CU_ASSERT_EQUAL(iso_tree_node_get_permissions(node), 0411);
/* test on a file */
node = iso_tree_add_node(root, "/tmp/libisofs_test/README");
CU_ASSERT_EQUAL(iso_tree_node_get_permissions(node), 0555);
iso_tree_node_set_permissions(node, 0777);
CU_ASSERT_EQUAL(iso_tree_node_get_permissions(node), 0777);
iso_tree_node_set_permissions(node, 0744);
CU_ASSERT_EQUAL(iso_tree_node_get_permissions(node), 0744);
iso_tree_node_set_permissions(node, 0411);
CU_ASSERT_EQUAL(iso_tree_node_get_permissions(node), 0411);
iso_tree_free((struct iso_tree_node *)root);
}
static void test_set_sort_weight() {
struct iso_tree_node_dir *root;
struct iso_tree_node_dir *dir;
@ -375,6 +503,519 @@ static void test_set_sort_weight() {
iso_tree_free((struct iso_tree_node *)root);
}
static void test_set_dest() {
struct iso_tree_node_dir *root;
struct iso_tree_node *node;
struct iso_tree_node_symlink *link;
root = iso_tree_new_root();
node = iso_tree_add_node(root, "/tmp/libisofs_test/link to readme");
link = (struct iso_tree_node_symlink *) node;
CU_ASSERT_STRING_EQUAL( link->dest, "/tmp/libisofs_test/README");
iso_tree_node_symlink_set_dest(link, "/tmp/inexistent");
CU_ASSERT_STRING_EQUAL( link->dest, "/tmp/inexistent");
iso_tree_free((struct iso_tree_node *)root);
}
static void test_get_dest() {
struct iso_tree_node_dir *root;
struct iso_tree_node *node;
struct iso_tree_node_symlink *link;
root = iso_tree_new_root();
node = iso_tree_add_node(root, "/tmp/libisofs_test/link to readme");
link = (struct iso_tree_node_symlink *) node;
CU_ASSERT_STRING_EQUAL( iso_tree_node_symlink_get_dest(link), "/tmp/libisofs_test/README");
iso_tree_node_symlink_set_dest(link, "/tmp/inexistent");
CU_ASSERT_STRING_EQUAL( iso_tree_node_symlink_get_dest(link), "/tmp/inexistent");
iso_tree_free((struct iso_tree_node *)root);
}
static void test_get_node_type() {
struct iso_tree_node_dir *root;
struct iso_tree_node *node;
root = iso_tree_new_root();
/* test on a dir */
node = iso_tree_add_node(root, "/tmp/libisofs_test/dir1");
CU_ASSERT_EQUAL(iso_tree_node_get_type(node), LIBISO_NODE_DIR);
/* test on a link */
node = iso_tree_add_node(root, "/tmp/libisofs_test/link to readme");
CU_ASSERT_EQUAL(iso_tree_node_get_type(node), LIBISO_NODE_SYMLINK);
/* test on a file */
node = iso_tree_add_node(root, "/tmp/libisofs_test/README");
CU_ASSERT_EQUAL(iso_tree_node_get_type(node), LIBISO_NODE_FILE);
iso_tree_free((struct iso_tree_node *)root);
}
static void test_children_iter() {
struct iso_tree_node_dir *root;
struct iso_tree_iter *iter;
struct iso_tree_node *child;
struct iso_tree_node *node1, *node2, *node3;
root = iso_tree_new_root();
node1 = iso_tree_add_node(root, "/tmp/libisofs_test/dir1");
node2 = iso_tree_add_node(root, "/tmp/libisofs_test/link to readme");
node3 = iso_tree_add_node(root, "/tmp/libisofs_test/README");
/* get the iterator */
iter = iso_tree_node_children(root);
CU_ASSERT_PTR_NOT_NULL(iter);
/* test correct iteration */
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node1);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node2);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node3);
/* and NULL when no more children */
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NULL(child);
iso_tree_iter_free(iter);
/* now an iter on a empty dir */
iter = iso_tree_node_children((struct iso_tree_node_dir *)node1);
CU_ASSERT_PTR_NOT_NULL(iter);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NULL(child);
iso_tree_free((struct iso_tree_node *)root);
}
static void test_tree_node_take() {
int res;
struct iso_tree_node_dir *root;
struct iso_tree_iter *iter;
struct iso_tree_node *child;
struct iso_tree_node *node1, *node2, *node3;
root = iso_tree_new_root();
node1 = iso_tree_add_node(root, "/tmp/libisofs_test/dir1");
node2 = iso_tree_add_node(root, "/tmp/libisofs_test/link to readme");
node3 = iso_tree_add_node(root, "/tmp/libisofs_test/README");
/* we take a ref to each node to test current reference behavior */
iso_tree_node_ref(node1);
iso_tree_node_ref(node2);
iso_tree_node_ref(node3);
/* remove node2 */
res = iso_tree_node_take(root, node2);
CU_ASSERT_EQUAL(res, 0);
CU_ASSERT_EQUAL(root->nchildren, 2);
CU_ASSERT_PTR_NULL(node2->parent);
/* node2 should keep both refs */
CU_ASSERT_EQUAL(node2->refcount, 2);
/* test iteration */
iter = iso_tree_node_children(root);
CU_ASSERT_PTR_NOT_NULL(iter);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node1);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node3);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NULL(child);
iso_tree_iter_free(iter);
/* try to remove again node2 */
res = iso_tree_node_take(root, node2);
CU_ASSERT_EQUAL(res, -1);
CU_ASSERT_EQUAL(root->nchildren, 2);
iso_tree_free(node2);
/* ok, now remove node1, and then node3 */
res = iso_tree_node_take(root, node1);
CU_ASSERT_EQUAL(res, 0);
CU_ASSERT_EQUAL(root->nchildren, 1);
CU_ASSERT_EQUAL(node1->refcount, 2);
CU_ASSERT_PTR_NULL(node1->parent);
iter = iso_tree_node_children(root);
CU_ASSERT_PTR_NOT_NULL(iter);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node3);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NULL(child);
iso_tree_iter_free(iter);
res = iso_tree_node_take(root, node3);
CU_ASSERT_EQUAL(res, 0);
CU_ASSERT_EQUAL(root->nchildren, 0);
CU_ASSERT_EQUAL(node3->refcount, 2);
CU_ASSERT_PTR_NULL(node3->parent);
iter = iso_tree_node_children(root);
CU_ASSERT_PTR_NOT_NULL(iter);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NULL(child);
iso_tree_iter_free(iter);
/* and try to remove on an empty dir */
res = iso_tree_node_take(root, node3);
CU_ASSERT_EQUAL(res, -1);
iso_tree_free(node1);
iso_tree_free(node3);
iso_tree_free((struct iso_tree_node *)root);
iso_tree_free(node1);
iso_tree_free(node2);
iso_tree_free(node3);
}
static void test_tree_node_remove() {
int res;
struct iso_tree_node_dir *root;
struct iso_tree_iter *iter;
struct iso_tree_node *child;
struct iso_tree_node *node1, *node2, *node3;
root = iso_tree_new_root();
node1 = iso_tree_add_node(root, "/tmp/libisofs_test/dir1");
node2 = iso_tree_add_node(root, "/tmp/libisofs_test/link to readme");
node3 = iso_tree_add_node(root, "/tmp/libisofs_test/README");
/* we take a ref to each node to test current reference behavior */
iso_tree_node_ref(node1);
iso_tree_node_ref(node2);
iso_tree_node_ref(node3);
/* remove node2 */
res = iso_tree_node_remove(root, node2);
CU_ASSERT_EQUAL(res, 0);
CU_ASSERT_EQUAL(root->nchildren, 2);
CU_ASSERT_PTR_NULL(node2->parent);
/* node2 should be unref */
CU_ASSERT_EQUAL(node2->refcount, 1);
/* test iteration */
iter = iso_tree_node_children(root);
CU_ASSERT_PTR_NOT_NULL(iter);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node1);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node3);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NULL(child);
iso_tree_iter_free(iter);
/* try to remove again node2 */
res = iso_tree_node_remove(root, node2);
CU_ASSERT_EQUAL(res, -1);
CU_ASSERT_EQUAL(root->nchildren, 2);
CU_ASSERT_EQUAL(node2->refcount, 1);
/* ok, now remove node1, and then node3 */
res = iso_tree_node_remove(root, node1);
CU_ASSERT_EQUAL(res, 0);
CU_ASSERT_EQUAL(root->nchildren, 1);
CU_ASSERT_EQUAL(node1->refcount, 1);
CU_ASSERT_PTR_NULL(node1->parent);
iter = iso_tree_node_children(root);
CU_ASSERT_PTR_NOT_NULL(iter);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node3);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NULL(child);
iso_tree_iter_free(iter);
res = iso_tree_node_remove(root, node3);
CU_ASSERT_EQUAL(res, 0);
CU_ASSERT_EQUAL(root->nchildren, 0);
CU_ASSERT_EQUAL(node3->refcount, 1);
CU_ASSERT_PTR_NULL(node3->parent);
iter = iso_tree_node_children(root);
CU_ASSERT_PTR_NOT_NULL(iter);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NULL(child);
iso_tree_iter_free(iter);
/* and try to remove on an empty dir */
res = iso_tree_node_remove(root, node3);
CU_ASSERT_EQUAL(res, -1);
CU_ASSERT_EQUAL(node3->refcount, 1);
iso_tree_free((struct iso_tree_node *)root);
iso_tree_free(node1);
iso_tree_free(node2);
iso_tree_free(node3);
}
static void test_tree_node_take_iter() {
int res;
struct iso_tree_node_dir *root;
struct iso_tree_iter *iter;
struct iso_tree_node *child;
struct iso_tree_node *node1, *node2, *node3;
root = iso_tree_new_root();
node1 = iso_tree_add_node(root, "/tmp/libisofs_test/dir1");
node2 = iso_tree_add_node(root, "/tmp/libisofs_test/link to readme");
node3 = iso_tree_add_node(root, "/tmp/libisofs_test/README");
/* we take a ref to each node to test current reference behavior */
iso_tree_node_ref(node1);
iso_tree_node_ref(node2);
iso_tree_node_ref(node3);
/* begin iteration */
iter = iso_tree_node_children(root);
CU_ASSERT_PTR_NOT_NULL(iter);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node1);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node2);
/* ok, take node 2 */
res = iso_tree_node_take_iter(iter);
CU_ASSERT_EQUAL(res, 0);
CU_ASSERT_EQUAL(root->nchildren, 2);
CU_ASSERT_EQUAL(node2->refcount, 2);
CU_ASSERT_PTR_NULL(node2->parent);
/* the iter have to work after remove */
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node3);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NULL(child);
iso_tree_iter_free(iter);
/* ok, now remove before the begining */
iter = iso_tree_node_children(root);
CU_ASSERT_PTR_NOT_NULL(iter);
res = iso_tree_node_take_iter(iter);
CU_ASSERT_TRUE(res < 0);
/* and the iter still works */
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node1);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node3);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NULL(child);
/* and now try to remove at the end */
res = iso_tree_node_take_iter(iter);
CU_ASSERT_TRUE(res < 0);
iso_tree_iter_free(iter);
/* ok, now remove all during iteration */
iter = iso_tree_node_children(root);
CU_ASSERT_PTR_NOT_NULL(iter);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node1);
res = iso_tree_node_take_iter(iter);
CU_ASSERT_EQUAL(res, 0);
CU_ASSERT_EQUAL(root->nchildren, 1);
CU_ASSERT_EQUAL(node1->refcount, 2);
CU_ASSERT_PTR_NULL(node1->parent);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node3);
res = iso_tree_node_take_iter(iter);
CU_ASSERT_EQUAL(res, 0);
CU_ASSERT_EQUAL(root->nchildren, 0);
CU_ASSERT_EQUAL(node3->refcount, 2);
CU_ASSERT_PTR_NULL(node3->parent);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NULL(child);
iso_tree_iter_free(iter);
iso_tree_free(node1);
iso_tree_free(node2);
iso_tree_free(node3);
iso_tree_free((struct iso_tree_node *)root);
iso_tree_free(node1);
iso_tree_free(node2);
iso_tree_free(node3);
}
static void test_tree_node_remove_iter() {
int res;
struct iso_tree_node_dir *root;
struct iso_tree_iter *iter;
struct iso_tree_node *child;
struct iso_tree_node *node1, *node2, *node3;
root = iso_tree_new_root();
node1 = iso_tree_add_node(root, "/tmp/libisofs_test/dir1");
node2 = iso_tree_add_node(root, "/tmp/libisofs_test/link to readme");
node3 = iso_tree_add_node(root, "/tmp/libisofs_test/README");
/* we take a ref to each node to test current reference behavior */
iso_tree_node_ref(node1);
iso_tree_node_ref(node2);
iso_tree_node_ref(node3);
/* begin iteration */
iter = iso_tree_node_children(root);
CU_ASSERT_PTR_NOT_NULL(iter);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node1);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node2);
/* ok, remove node 2 */
res = iso_tree_node_remove_iter(iter);
CU_ASSERT_EQUAL(res, 0);
CU_ASSERT_EQUAL(root->nchildren, 2);
CU_ASSERT_EQUAL(node2->refcount, 1);
CU_ASSERT_PTR_NULL(node2->parent);
/* the iter have to work after remove */
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node3);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NULL(child);
iso_tree_iter_free(iter);
/* ok, now remove before the begining */
iter = iso_tree_node_children(root);
CU_ASSERT_PTR_NOT_NULL(iter);
res = iso_tree_node_remove_iter(iter);
CU_ASSERT_TRUE(res < 0);
/* and the iter still works */
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node1);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node3);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NULL(child);
/* and now try to remove at the end */
res = iso_tree_node_remove_iter(iter);
CU_ASSERT_TRUE(res < 0);
iso_tree_iter_free(iter);
/* ok, now remove all during iteration */
iter = iso_tree_node_children(root);
CU_ASSERT_PTR_NOT_NULL(iter);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node1);
res = iso_tree_node_remove_iter(iter);
CU_ASSERT_EQUAL(res, 0);
CU_ASSERT_EQUAL(root->nchildren, 1);
CU_ASSERT_EQUAL(node1->refcount, 1);
CU_ASSERT_PTR_NULL(node1->parent);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NOT_NULL(child);
CU_ASSERT_PTR_EQUAL(child, node3);
res = iso_tree_node_remove_iter(iter);
CU_ASSERT_EQUAL(res, 0);
CU_ASSERT_EQUAL(root->nchildren, 0);
CU_ASSERT_EQUAL(node3->refcount, 1);
CU_ASSERT_PTR_NULL(node3->parent);
child = iso_tree_iter_next(iter);
CU_ASSERT_PTR_NULL(child);
iso_tree_iter_free(iter);
iso_tree_free((struct iso_tree_node *)root);
iso_tree_free(node1);
iso_tree_free(node2);
iso_tree_free(node3);
}
static void test_tree_node_get_parent() {
struct iso_tree_node_dir *root;
struct iso_tree_node_dir *parent;
struct iso_tree_node *node1, *node2, *node3;
root = iso_tree_new_root();
node1 = iso_tree_add_node(root, "/tmp/libisofs_test/dir1");
node2 = iso_tree_add_node(root, "/tmp/libisofs_test/link to readme");
node3 = iso_tree_add_node( (struct iso_tree_node_dir*)node1,
"/tmp/libisofs_test/README");
parent = iso_tree_node_get_parent((struct iso_tree_node *)root);
CU_ASSERT_PTR_NULL(parent);
parent = iso_tree_node_get_parent(node1);
CU_ASSERT_PTR_NOT_NULL(parent);
CU_ASSERT_PTR_EQUAL(parent, root);
parent = iso_tree_node_get_parent(node2);
CU_ASSERT_PTR_NOT_NULL(parent);
CU_ASSERT_PTR_EQUAL(parent, root);
parent = iso_tree_node_get_parent(node3);
CU_ASSERT_PTR_NOT_NULL(parent);
CU_ASSERT_PTR_EQUAL(parent, node1);
iso_tree_node_take(root, node1);
parent = iso_tree_node_get_parent(node1);
CU_ASSERT_PTR_NULL(parent);
iso_tree_free((struct iso_tree_node *)root);
iso_tree_free(node1);
}
void add_tree_suite()
{
CU_pSuite pSuite = CU_add_suite("TreeSuite", NULL, NULL);
@ -384,12 +1025,27 @@ void add_tree_suite()
CU_add_test(pSuite, "test of iso_tree_add_file()", test_add_file);
CU_add_test(pSuite, "test of iso_tree_add_symlink()", test_add_symlink);
CU_add_test(pSuite, "test of iso_tree_add_node()", test_add_node);
CU_add_test(pSuite, "test of iso_tree_radd_dir()", test_radd_dir);
CU_add_test(pSuite, "test of iso_tree_node_set_name()", test_set_name);
CU_add_test(pSuite, "test of iso_tree_node_get_name()", test_get_name);
CU_add_test(pSuite, "test of iso_tree_node_set_hidden()", test_set_hidden);
CU_add_test(pSuite, "test of iso_tree_node_is_hidden()", test_is_hidden);
CU_add_test(pSuite, "test of iso_tree_node_set_gid()", test_set_gid);
CU_add_test(pSuite, "test of iso_tree_node_get_gid()", test_get_gid);
CU_add_test(pSuite, "test of iso_tree_node_set_uid()", test_set_uid);
CU_add_test(pSuite, "test of iso_tree_node_get_uid()", test_get_uid);
CU_add_test(pSuite, "test of iso_tree_node_set_permissions()", test_set_permissions);
CU_add_test(pSuite, "test of iso_tree_node_get_permissions()", test_get_permissions);
CU_add_test(pSuite, "test of iso_tree_node_set_sort_weight()", test_set_sort_weight);
CU_add_test(pSuite, "test of iso_tree_node_symlink_set_dest()", test_set_dest);
CU_add_test(pSuite, "test of iso_tree_node_symlink_get_dest()", test_get_dest);
CU_add_test(pSuite, "test of iso_tree_node_get_type()", test_get_node_type);
CU_add_test(pSuite, "test of children iteration", test_children_iter);
CU_add_test(pSuite, "test of iso_tree_node_take()", test_tree_node_take);
CU_add_test(pSuite, "test of iso_tree_node_remove()", test_tree_node_remove);
CU_add_test(pSuite, "test of iso_tree_node_take_iter()", test_tree_node_take_iter);
CU_add_test(pSuite, "test of iso_tree_node_remove_iter()", test_tree_node_remove_iter);
CU_add_test(pSuite, "test of iso_tree_node_get_parent()", test_tree_node_get_parent);
}

View File

@ -4,8 +4,10 @@
* This test utiliy functions
*
*/
#include "test.h"
#include <time.h>
#include <locale.h>
#include "test.h"
#include "util.h"
static void test_div_up()
@ -56,6 +58,122 @@ static void test_iso_lsb_msb()
CU_ASSERT_EQUAL( buf[1], 0x04 );
}
static void test_iso_read_lsb_msb()
{
uint8_t buf[4];
uint32_t num;
buf[0] = 0x04;
buf[1] = 0x03;
buf[2] = 0x02;
buf[3] = 0x01;
num = iso_read_lsb(buf, 4);
CU_ASSERT_EQUAL(num, 0x01020304);
num = iso_read_msb(buf, 4);
CU_ASSERT_EQUAL(num, 0x04030201);
num = iso_read_lsb(buf, 2);
CU_ASSERT_EQUAL(num, 0x0304);
num = iso_read_msb(buf, 2);
CU_ASSERT_EQUAL(num, 0x0403);
}
static void test_iso_bb()
{
uint8_t buf[8];
uint32_t num;
num = 0x01020304;
iso_bb(buf, num, 4);
CU_ASSERT_EQUAL( buf[0], 0x04 );
CU_ASSERT_EQUAL( buf[1], 0x03 );
CU_ASSERT_EQUAL( buf[2], 0x02 );
CU_ASSERT_EQUAL( buf[3], 0x01 );
CU_ASSERT_EQUAL( buf[4], 0x01 );
CU_ASSERT_EQUAL( buf[5], 0x02 );
CU_ASSERT_EQUAL( buf[6], 0x03 );
CU_ASSERT_EQUAL( buf[7], 0x04 );
iso_bb(buf, num, 2);
CU_ASSERT_EQUAL( buf[0], 0x04 );
CU_ASSERT_EQUAL( buf[1], 0x03 );
CU_ASSERT_EQUAL( buf[2], 0x03 );
CU_ASSERT_EQUAL( buf[3], 0x04 );
}
static void test_iso_read_bb()
{
uint8_t buf[8];
uint32_t num;
int error = 0;
buf[0] = 0x04;
buf[1] = 0x03;
buf[2] = 0x02;
buf[3] = 0x01;
buf[4] = 0x01;
buf[5] = 0x02;
buf[6] = 0x03;
buf[7] = 0x04;
num = iso_read_bb(buf, 4, &error);
CU_ASSERT_EQUAL( num, 0x01020304 );
CU_ASSERT_FALSE(error);
num = iso_read_bb(buf, 4, NULL);
CU_ASSERT_EQUAL( num, 0x01020304 );
buf[2] = 3;
num = iso_read_bb(buf, 4, &error);
/* return the LSB */
CU_ASSERT_EQUAL( num, 0x01030304 );
CU_ASSERT_TRUE(error);
num = iso_read_bb(buf, 4, NULL);
/* return the LSB */
CU_ASSERT_EQUAL( num, 0x01030304 );
error = 0;
buf[3] = 0x04;
num = iso_read_bb(buf, 2, &error);
CU_ASSERT_EQUAL( num, 0x0304 );
CU_ASSERT_FALSE(error);
num = iso_read_bb(buf, 2, NULL);
CU_ASSERT_EQUAL( num, 0x0304 );
}
static void test_iso_datetime_7()
{
uint8_t buf[7];
time_t t, t2;
struct tm tp;
strptime("01-03-1976 13:27:45", "%d-%m-%Y %T", &tp);
t = mktime(&tp);
iso_datetime_7(buf, t);
CU_ASSERT_EQUAL( buf[0], 76 ); /* year since 1900 */
CU_ASSERT_EQUAL( buf[1], 3 ); /* month */
CU_ASSERT_EQUAL( buf[2], 1 ); /* day */
CU_ASSERT_EQUAL( buf[3], 13 ); /* hour */
CU_ASSERT_EQUAL( buf[4], 27 ); /* minute */
CU_ASSERT_EQUAL( buf[5], 45 ); /* second */
/* the offset depends on current timezone and it's not easy to test */
//CU_ASSERT_EQUAL( buf[6], 4 ); /* 15 min offset */
/* check that reading returns the same time */
t2 = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(t2, t);
//TODO check with differnt timezones for reading and writting
}
static void test_iso_1_dirid()
{
CU_ASSERT_STRING_EQUAL( iso_1_dirid("dir1", "UTF-8"), "DIR1" );
@ -253,13 +371,17 @@ void add_util_suite()
{
CU_pSuite pSuite = CU_add_suite("UtilSuite", NULL, NULL);
CU_add_test(pSuite, "test of div_up()", test_div_up);
CU_add_test(pSuite, "test of round_up()", test_round_up);
CU_add_test(pSuite, "test of iso_lsb_msb()", test_iso_lsb_msb);
CU_add_test(pSuite, "test of iso_1_dirid()", test_iso_1_dirid);
CU_add_test(pSuite, "test of iso_2_dirid()", test_iso_2_dirid);
CU_add_test(pSuite, "test of iso_r_dirid()", test_iso_r_dirid);
CU_add_test(pSuite, "test of iso_1_fileid()", test_iso_1_fileid);
CU_add_test(pSuite, "test of iso_2_fileid()", test_iso_2_fileid);
CU_add_test(pSuite, "test of iso_r_fileid()", test_iso_r_fileid);
CU_add_test(pSuite, "div_up()", test_div_up);
CU_add_test(pSuite, "round_up()", test_round_up);
CU_add_test(pSuite, "iso_lsb() and iso_msb()", test_iso_lsb_msb);
CU_add_test(pSuite, "iso_read_lsb() and iso_read_msb()", test_iso_read_lsb_msb);
CU_add_test(pSuite, "iso_bb()", test_iso_bb);
CU_add_test(pSuite, "iso_read_bb()", test_iso_read_bb);
CU_add_test(pSuite, "iso_datetime_7()", test_iso_datetime_7);
CU_add_test(pSuite, "iso_1_dirid()", test_iso_1_dirid);
CU_add_test(pSuite, "iso_2_dirid()", test_iso_2_dirid);
CU_add_test(pSuite, "iso_r_dirid()", test_iso_r_dirid);
CU_add_test(pSuite, "iso_1_fileid()", test_iso_1_fileid);
CU_add_test(pSuite, "iso_2_fileid()", test_iso_2_fileid);
CU_add_test(pSuite, "iso_r_fileid()", test_iso_r_fileid);
}

View File

@ -105,6 +105,20 @@ static void test_iso_volume_set_volume_id()
iso_volume_free(volume);
}
static void test_iso_volume_get_volume_id()
{
struct iso_volume *volume;
volume = iso_volume_new("volume_id", "publisher_id", "data_preparer_id");
CU_ASSERT_STRING_EQUAL( iso_volume_get_volume_id(volume), "volume_id" );
char *volid = "new volume id";
iso_volume_set_volume_id(volume, volid);
CU_ASSERT_STRING_EQUAL( iso_volume_get_volume_id(volume), "new volume id" );
iso_volume_free(volume);
}
static void test_iso_volume_set_publisher_id()
{
struct iso_volume *volume;
@ -121,6 +135,20 @@ static void test_iso_volume_set_publisher_id()
iso_volume_free(volume);
}
static void test_iso_volume_get_publisher_id()
{
struct iso_volume *volume;
volume = iso_volume_new("volume_id", "publisher_id", "data_preparer_id");
CU_ASSERT_STRING_EQUAL( iso_volume_get_publisher_id(volume), "publisher_id" );
char *pubid = "new publisher id";
iso_volume_set_publisher_id(volume, pubid);
CU_ASSERT_STRING_EQUAL( iso_volume_get_publisher_id(volume), "new publisher id" );
iso_volume_free(volume);
}
static void test_iso_volume_set_data_preparer_id()
{
struct iso_volume *volume;
@ -137,6 +165,20 @@ static void test_iso_volume_set_data_preparer_id()
iso_volume_free(volume);
}
static void test_iso_volume_get_data_preparer_id()
{
struct iso_volume *volume;
volume = iso_volume_new("volume_id", "publisher_id", "data_preparer_id");
CU_ASSERT_STRING_EQUAL( iso_volume_get_data_preparer_id(volume), "data_preparer_id" );
char *dpid = "new data preparer id";
iso_volume_set_data_preparer_id(volume, dpid);
CU_ASSERT_STRING_EQUAL( iso_volume_get_data_preparer_id(volume), "new data preparer id" );
iso_volume_free(volume);
}
static void test_iso_volume_set_system_id()
{
struct iso_volume *volume;
@ -153,6 +195,20 @@ static void test_iso_volume_set_system_id()
iso_volume_free(volume);
}
static void test_iso_volume_get_system_id()
{
struct iso_volume *volume;
volume = iso_volume_new("volume_id", "publisher_id", "data_preparer_id");
CU_ASSERT_PTR_NULL(iso_volume_get_system_id(volume));
char *sysid = "new system id";
iso_volume_set_system_id(volume, sysid);
CU_ASSERT_STRING_EQUAL( iso_volume_get_system_id(volume), "new system id" );
iso_volume_free(volume);
}
static void test_iso_volume_set_application_id()
{
struct iso_volume *volume;
@ -169,6 +225,50 @@ static void test_iso_volume_set_application_id()
iso_volume_free(volume);
}
static void test_iso_volume_get_application_id()
{
struct iso_volume *volume;
volume = iso_volume_new("volume_id", "publisher_id", "data_preparer_id");
CU_ASSERT_PTR_NULL(iso_volume_get_application_id(volume));
char *appid = "new application id";
iso_volume_set_application_id(volume, appid);
CU_ASSERT_STRING_EQUAL( iso_volume_get_application_id(volume), "new application id" );
iso_volume_free(volume);
}
static void test_iso_volume_set_copyright_file_id()
{
struct iso_volume *volume;
volume = iso_volume_new("volume_id", "publisher_id", "data_preparer_id");
CU_ASSERT_PTR_NULL(volume->copyright_file_id);
char *copid = "new copyright id";
iso_volume_set_copyright_file_id(volume, copid);
CU_ASSERT_STRING_EQUAL( volume->copyright_file_id, "new copyright id" );
/* check string was strdup'ed */
CU_ASSERT_PTR_NOT_EQUAL( volume->copyright_file_id, copid );
iso_volume_free(volume);
}
static void test_iso_volume_get_copyright_file_id()
{
struct iso_volume *volume;
volume = iso_volume_new("volume_id", "publisher_id", "data_preparer_id");
CU_ASSERT_PTR_NULL(iso_volume_get_copyright_file_id(volume));
char *copid = "new copyright id";
iso_volume_set_copyright_file_id(volume, copid);
CU_ASSERT_STRING_EQUAL( iso_volume_get_copyright_file_id(volume), "new copyright id" );
iso_volume_free(volume);
}
static void test_iso_volume_set_abstract_file_id()
{
struct iso_volume *volume;
@ -185,6 +285,20 @@ static void test_iso_volume_set_abstract_file_id()
iso_volume_free(volume);
}
static void test_iso_volume_get_abstract_file_id()
{
struct iso_volume *volume;
volume = iso_volume_new("volume_id", "publisher_id", "data_preparer_id");
CU_ASSERT_PTR_NULL(iso_volume_get_abstract_file_id(volume));
char *absid = "new abstract id";
iso_volume_set_abstract_file_id(volume, absid);
CU_ASSERT_STRING_EQUAL(iso_volume_get_abstract_file_id(volume), "new abstract id");
iso_volume_free(volume);
}
static void test_iso_volume_set_biblio_file_id()
{
struct iso_volume *volume;
@ -201,6 +315,20 @@ static void test_iso_volume_set_biblio_file_id()
iso_volume_free(volume);
}
static void test_iso_volume_get_biblio_file_id()
{
struct iso_volume *volume;
volume = iso_volume_new("volume_id", "publisher_id", "data_preparer_id");
CU_ASSERT_PTR_NULL(iso_volume_get_biblio_file_id(volume));
char *bibid = "new biblio id";
iso_volume_set_biblio_file_id(volume, bibid);
CU_ASSERT_STRING_EQUAL(iso_volume_get_biblio_file_id(volume), "new biblio id");
iso_volume_free(volume);
}
static void test_iso_volset_new()
{
struct iso_volume *volume;
@ -228,11 +356,20 @@ void add_volume_suite()
CU_add_test(pSuite, "test of iso_volume_new_with_root()", test_iso_volume_new_with_root);
CU_add_test(pSuite, "test of iso_volume_get_root()", test_iso_volume_get_root);
CU_add_test(pSuite, "test of iso_volume_set_volume_id()", test_iso_volume_set_volume_id);
CU_add_test(pSuite, "test of iso_volume_get_volume_id()", test_iso_volume_get_volume_id);
CU_add_test(pSuite, "test of iso_volume_set_publisher_id()", test_iso_volume_set_publisher_id);
CU_add_test(pSuite, "test of iso_volume_get_publisher_id()", test_iso_volume_get_publisher_id);
CU_add_test(pSuite, "test of iso_volume_set_data_preparer_id()", test_iso_volume_set_data_preparer_id);
CU_add_test(pSuite, "test of iso_volume_get_data_preparer_id()", test_iso_volume_get_data_preparer_id);
CU_add_test(pSuite, "test of iso_volume_set_system_id()", test_iso_volume_set_system_id);
CU_add_test(pSuite, "test of iso_volume_get_system_id()", test_iso_volume_get_system_id);
CU_add_test(pSuite, "test of iso_volume_set_application_id()", test_iso_volume_set_application_id);
CU_add_test(pSuite, "test of iso_volume_get_application_id()", test_iso_volume_get_application_id);
CU_add_test(pSuite, "test of iso_volume_set_copyright_file_id()", test_iso_volume_set_copyright_file_id);
CU_add_test(pSuite, "test of iso_volume_get_copyright_file_id()", test_iso_volume_get_copyright_file_id);
CU_add_test(pSuite, "test of iso_volume_set_abstract_file_id()", test_iso_volume_set_abstract_file_id);
CU_add_test(pSuite, "test of iso_volume_get_abstract_file_id()", test_iso_volume_get_abstract_file_id);
CU_add_test(pSuite, "test of iso_volume_set_biblio_file_id()", test_iso_volume_set_biblio_file_id);
CU_add_test(pSuite, "test of iso_volume_get_biblio_file_id()", test_iso_volume_get_biblio_file_id);
CU_add_test(pSuite, "test of iso_volset_new()", test_iso_volset_new);
}