From 16cbb18f153db31d6d5d2b9773a512e25fd9e6b1 Mon Sep 17 00:00:00 2001 From: Mario Danic Date: Tue, 14 Nov 2006 00:52:32 +0000 Subject: [PATCH] Removed remaining signs of libisofs in libburn tree --- libisofs-1.pc.in | 11 - libisofs/Makefile | 4 - libisofs/Makefile.am | 49 --- libisofs/ecma119.c | 694 ---------------------------------------- libisofs/ecma119.h | 267 ---------------- libisofs/ecma119_tree.c | 312 ------------------ libisofs/ecma119_tree.h | 95 ------ libisofs/exclude.c | 42 --- libisofs/exclude.h | 12 - libisofs/hash.c | 158 --------- libisofs/hash.h | 46 --- libisofs/joliet.c | 379 ---------------------- libisofs/joliet.h | 84 ----- libisofs/libisofs.h | 225 ------------- libisofs/rockridge.c | 300 ----------------- libisofs/rockridge.h | 26 -- libisofs/susp.c | 280 ---------------- libisofs/susp.h | 62 ---- libisofs/tree.c | 223 ------------- libisofs/tree.h | 159 --------- libisofs/util.c | 584 --------------------------------- libisofs/util.h | 121 ------- libisofs/volume.c | 189 ----------- libisofs/volume.h | 45 --- test/iso.c | 107 ------- test/iso.py | 297 ----------------- 26 files changed, 4771 deletions(-) delete mode 100644 libisofs-1.pc.in delete mode 100755 libisofs/Makefile delete mode 100755 libisofs/Makefile.am delete mode 100755 libisofs/ecma119.c delete mode 100755 libisofs/ecma119.h delete mode 100644 libisofs/ecma119_tree.c delete mode 100644 libisofs/ecma119_tree.h delete mode 100644 libisofs/exclude.c delete mode 100644 libisofs/exclude.h delete mode 100644 libisofs/hash.c delete mode 100644 libisofs/hash.h delete mode 100644 libisofs/joliet.c delete mode 100644 libisofs/joliet.h delete mode 100755 libisofs/libisofs.h delete mode 100755 libisofs/rockridge.c delete mode 100755 libisofs/rockridge.h delete mode 100755 libisofs/susp.c delete mode 100755 libisofs/susp.h delete mode 100755 libisofs/tree.c delete mode 100755 libisofs/tree.h delete mode 100755 libisofs/util.c delete mode 100755 libisofs/util.h delete mode 100755 libisofs/volume.c delete mode 100755 libisofs/volume.h delete mode 100644 test/iso.c delete mode 100644 test/iso.py diff --git a/libisofs-1.pc.in b/libisofs-1.pc.in deleted file mode 100644 index 32f3070..0000000 --- a/libisofs-1.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libisofs -Description: ISO9660 filesystem creation library -Version: @VERSION@ -Requires: -Libs: -L${libdir} -lisofs -Cflags: -I${includedir}/libburn diff --git a/libisofs/Makefile b/libisofs/Makefile deleted file mode 100755 index 062350d..0000000 --- a/libisofs/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -all clean: - $(MAKE) -C .. -$(MAKEFLAGS) $@ - -.PHONY: all clean diff --git a/libisofs/Makefile.am b/libisofs/Makefile.am deleted file mode 100755 index e2f197e..0000000 --- a/libisofs/Makefile.am +++ /dev/null @@ -1,49 +0,0 @@ -pkgconfigdir=$(libdir)/pkgconfig -libincludedir=$(includedir)/libburn - -##bin_PROGRAMS = test - -lib_LTLIBRARIES = libisofs.la - -libisofs_la_SOURCES = \ - tree.h \ - tree.c \ - volume.h \ - volume.c \ - util.h \ - util.c \ - ecma119.c \ - ecma119.h \ - ecma119_tree.c \ - ecma119_tree.h \ - susp.h \ - susp.c \ - rockridge.h \ - rockridge.c \ - joliet.c \ - joliet.h - -libinclude_HEADERS = libisofs.h - -##test_SOURCES = test.c -##test_LDADD = libisofs.la - -##noinst_PROGRAMS = test -##test_SOURCES = test.c -##test_LDADD = $(libisofs_la_OBJECTS) - -##INCLUDES = -I../burn/libburn - -## ========================================================================= ## -indent_files = $(libisofs_la_SOURCES) - -indent: $(indent_files) - indent -bad -bap -nbbb -nbbo -nbc -bli0 -br -bls \ - -cdw -ce -cli0 -ncs -nbfda -i8 -l79 -lc79 \ - -lp -saf -sai -nprs -npsl -saw -sob -ss -ut \ - -sbi0 -nsc -ts8 -npcs -ncdb -fca \ - $^ - -.PHONY: indent - -## ========================================================================= ## diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c deleted file mode 100755 index a1ac681..0000000 --- a/libisofs/ecma119.c +++ /dev/null @@ -1,694 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ -/* vim: set noet ts=8 sts=8 sw=8 : */ - -#include -#include -#include -#include -#include -#include - -#include "ecma119.h" -#include "ecma119_tree.h" -#include "susp.h" -#include "rockridge.h" -#include "joliet.h" -#include "volume.h" -#include "tree.h" -#include "util.h" -#include "libisofs.h" -#include "libburn/libburn.h" - -/* burn-source compatible stuff */ -static int -bs_read(struct burn_source *bs, unsigned char *buf, int size); -static off_t -bs_get_size(struct burn_source *bs); -static void -bs_free_data(struct burn_source *bs); - -typedef void (*write_fn)(struct ecma119_write_target*, uint8_t*); - -/* return true if the given state is only required for Joliet volumes */ -static int -is_joliet_state(enum ecma119_write_state); - -static void -next_state(struct ecma119_write_target *t); - -/* write t->state_data to the buf, one block at a time */ -static void -write_data_chunk(struct ecma119_write_target *t, uint8_t *buf); - -/* writing functions. All these functions assume the buf is large enough */ -static void -write_pri_vol_desc(struct ecma119_write_target *t, uint8_t *buf); -static void -write_vol_desc_terminator(struct ecma119_write_target *t, uint8_t *buf); -static void -write_path_table(struct ecma119_write_target *t, int l_type, uint8_t *buf); -static void -write_l_path_table(struct ecma119_write_target *t, uint8_t *buf); -static void -write_m_path_table(struct ecma119_write_target *t, uint8_t *buf); -static void -write_one_dir_record(struct ecma119_write_target *t, - struct ecma119_tree_node *dir, - int file_id, - uint8_t *buf); -static void -write_one_dir(struct ecma119_write_target *t, - struct ecma119_tree_node *dir, - uint8_t *buf); -static void -write_dirs(struct ecma119_write_target *t, uint8_t *buf); - -/* wrapper functions for writing */ -static void wr_system_area(struct ecma119_write_target*, uint8_t*); -static void wr_pri_vol_desc(struct ecma119_write_target*, uint8_t*); -static void wr_vol_desc_term(struct ecma119_write_target*, uint8_t*); -static void wr_l_path_table(struct ecma119_write_target*, uint8_t*); -static void wr_m_path_table(struct ecma119_write_target*, uint8_t*); -static void wr_dir_records(struct ecma119_write_target*, uint8_t*); -static void wr_files(struct ecma119_write_target*, uint8_t*); - -static const write_fn writers[] = -{ - NULL, - wr_system_area, - wr_pri_vol_desc, - joliet_wr_sup_vol_desc, - wr_vol_desc_term, - wr_l_path_table, - wr_m_path_table, - joliet_wr_l_path_table, - joliet_wr_m_path_table, - wr_dir_records, - joliet_wr_dir_records, - wr_files -}; - -/* When a writer is created, we - * 1) create an ecma119 tree - * 2) add SUSP fields (if necessary) - * 3) calculate the size and position of all nodes in the tree - * 4) finalize SUSP fields (if necessary) - */ - -static void -add_susp_fields_rec(struct ecma119_write_target *t, - struct ecma119_tree_node *node) -{ - size_t i; - - if (!node->iso_self) - return; - - rrip_add_PX(t, node); - rrip_add_NM(t, node); - rrip_add_TF(t, node); - if (node->iso_self->attrib.st_rdev) - rrip_add_PN(t, node); - if (S_ISLNK(node->iso_self->attrib.st_mode)) - rrip_add_SL(t, node); - if (node->type == ECMA119_FILE && node->file.real_me) - rrip_add_CL(t, node); - if (node->type == ECMA119_DIR - && node->dir.real_parent != node->parent) { - rrip_add_RE(t, node); - rrip_add_PL(t, node); - } - susp_add_CE(t, node); - - if (node->type == ECMA119_DIR) { - for (i = 0; i < node->dir.nchildren; i++) { - add_susp_fields_rec(t, node->dir.children[i]); - } - } -} - -static void -add_susp_fields(struct ecma119_write_target *t) -{ - susp_add_SP(t, t->root); - rrip_add_ER(t, t->root); - add_susp_fields_rec(t, t->root); -} - -/** - * Fill out the dir.len and dir.CE_len fields for each - * ecma119_tree_node that is a directory. Also calculate the total number of - * directories and the number of files for which we need to write out data. - * (dirlist_len and filelist_len) - */ -static void -calc_dir_size(struct ecma119_write_target *t, - struct ecma119_tree_node *dir) -{ - size_t i; - - assert(dir->type == ECMA119_DIR); - - t->dirlist_len++; - dir->dir.len = 34 + dir->dir.self_susp.non_CE_len - + 34 + dir->dir.parent_susp.non_CE_len; - dir->dir.CE_len = dir->dir.self_susp.CE_len - + dir->dir.parent_susp.CE_len; - for (i = 0; i < dir->dir.nchildren; i++) { - struct ecma119_tree_node *ch = dir->dir.children[i]; - - dir->dir.len += ch->dirent_len + ch->susp.non_CE_len; - dir->dir.CE_len += ch->susp.CE_len; - } - t->total_dir_size += round_up(dir->dir.len + dir->dir.CE_len, - t->block_size); - - for (i = 0; i < dir->dir.nchildren; i++) { - struct ecma119_tree_node *ch = dir->dir.children[i]; - struct iso_tree_node *iso = ch->iso_self; - if (ch->type == ECMA119_DIR) { - calc_dir_size(t, ch); - } else if (iso && iso->attrib.st_size - && iso->loc.type == LIBISO_FILESYS - && iso->loc.path) { - t->filelist_len++; - } - } -} - -/** - * Fill out the block field in each ecma119_tree_node that is a directory and - * fill out t->dirlist. - */ -static void -calc_dir_pos(struct ecma119_write_target *t, - struct ecma119_tree_node *dir) -{ - size_t i; - - assert(dir->type == ECMA119_DIR); - - /* we don't need to set iso_self->block since each tree writes - * its own directories */ - dir->block = t->curblock; - t->curblock += div_up(dir->dir.len + dir->dir.CE_len, t->block_size); - t->dirlist[t->curfile++] = dir; - for (i = 0; i < dir->dir.nchildren; i++) { - struct ecma119_tree_node *ch = dir->dir.children[i]; - if (ch->type == ECMA119_DIR) - calc_dir_pos(t, ch); - } - - /* reset curfile when we're finished */ - if (!dir->parent) { - t->curfile = 0; - } -} - -/** - * Fill out the block field for each ecma119_tree_node that is a file and fill - * out t->filelist. - */ -static void -calc_file_pos(struct ecma119_write_target *t, - struct ecma119_tree_node *dir) -{ - size_t i; - - assert(dir->type == ECMA119_DIR); - - for (i = 0; i < dir->dir.nchildren; i++) { - struct ecma119_tree_node *ch = dir->dir.children[i]; - if (ch->type == ECMA119_FILE && ch->iso_self) { - struct iso_tree_node *iso = ch->iso_self; - off_t size = iso->attrib.st_size; - - iso->block = ch->block = t->curblock; - t->curblock += div_up(size, t->block_size); - if (size && iso->loc.type == LIBISO_FILESYS - && iso->loc.path) - t->filelist[t->curfile++] = ch; - } - } - - for (i = 0; i < dir->dir.nchildren; i++) { - struct ecma119_tree_node *ch = dir->dir.children[i]; - if (ch->type == ECMA119_DIR) - calc_file_pos(t, ch); - } - - /* reset curfile when we're finished */ - if (!dir->parent) { - t->curfile = 0; - } -} - -struct ecma119_write_target* -ecma119_target_new(struct iso_volset *volset, - int volnum, - int level, - int flags) -{ - struct ecma119_write_target *t = - calloc(1, sizeof(struct ecma119_write_target)); - size_t i, j, cur; - struct iso_tree_node *iso_root = volset->volume[volnum]->root; - - volset->refcount++; - t->root = ecma119_tree_create(t, iso_root); - t->joliet = (flags & ECMA119_JOLIET) ? 1 : 0; - if (t->joliet) - t->joliet_root = joliet_tree_create(t, iso_root); - t->volset = volset; - t->volnum = volnum; - t->now = time(NULL); - - t->rockridge = (flags & ECMA119_ROCKRIDGE) ? 1 : 0; - t->iso_level = level; - t->block_size = 2048; - - if (t->rockridge) - add_susp_fields(t); - calc_dir_size(t, t->root); - if (t->joliet) { - joliet_calc_dir_size(t, t->joliet_root); - t->pathlist_joliet = calloc(1, sizeof(void*) * t->dirlist_len); - t->dirlist_joliet = calloc(1, sizeof(void*) * t->dirlist_len); - } - - t->dirlist = calloc(1, sizeof(void*) * t->dirlist_len); - t->pathlist = calloc(1, sizeof(void*) * t->dirlist_len); - t->filelist = calloc(1, sizeof(void*) * t->filelist_len); - - /* fill out the pathlist */ - t->pathlist[0] = t->root; - t->path_table_size = 10; /* root directory record */ - cur = 1; - for (i = 0; i < t->dirlist_len; i++) { - struct ecma119_tree_node *dir = t->pathlist[i]; - for (j = 0; j < dir->dir.nchildren; j++) { - struct ecma119_tree_node *ch = dir->dir.children[j]; - if (ch->type == ECMA119_DIR) { - size_t len = 8 + strlen(ch->name); - t->pathlist[cur++] = ch; - t->path_table_size += len + len % 2; - } - } - } - - t->curblock = 16 /* system area */ - + 1 /* volume desc */ - + 1; /* volume desc terminator */ - - if (t->joliet) /* supplementary vol desc */ - t->curblock += div_up (2048, t->block_size); - - t->l_path_table_pos = t->curblock; - t->curblock += div_up(t->path_table_size, t->block_size); - t->m_path_table_pos = t->curblock; - t->curblock += div_up(t->path_table_size, t->block_size); - if (t->joliet) { - joliet_prepare_path_tables(t); - t->l_path_table_pos_joliet = t->curblock; - t->curblock += div_up(t->path_table_size_joliet, t->block_size); - t->m_path_table_pos_joliet = t->curblock; - t->curblock += div_up(t->path_table_size_joliet, t->block_size); - } - - calc_dir_pos(t, t->root); - if (t->joliet) - joliet_calc_dir_pos(t, t->joliet_root); - calc_file_pos(t, t->root); - if (t->joliet) - joliet_update_file_pos (t, t->joliet_root); - - if (t->rockridge) { - susp_finalize(t, t->root); - rrip_finalize(t, t->root); - } - - t->total_size = t->curblock * t->block_size; - t->vol_space_size = t->curblock; - - /* prepare for writing */ - t->curblock = 0; - t->state = ECMA119_WRITE_SYSTEM_AREA; - - return t; -} - -static int -is_joliet_state(enum ecma119_write_state state) -{ - return state == ECMA119_WRITE_SUP_VOL_DESC_JOLIET - || state == ECMA119_WRITE_L_PATH_TABLE_JOLIET - || state == ECMA119_WRITE_M_PATH_TABLE_JOLIET - || state == ECMA119_WRITE_DIR_RECORDS_JOLIET; -} - -static void -next_state(struct ecma119_write_target *t) -{ - t->state++; - while (!t->joliet && is_joliet_state(t->state)) - t->state++; - - printf ("now in state %d, curblock=%d\n", (int)t->state, (int)t->curblock); -} - -static void -wr_system_area(struct ecma119_write_target *t, uint8_t *buf) -{ - memset(buf, 0, t->block_size); - if (t->curblock == 15) { - next_state(t); - } -} -static void -wr_pri_vol_desc(struct ecma119_write_target *t, uint8_t *buf) -{ - ecma119_start_chunking(t, write_pri_vol_desc, 2048, buf); -} - -static void -wr_vol_desc_term(struct ecma119_write_target *t, uint8_t *buf) -{ - ecma119_start_chunking(t, write_vol_desc_terminator, 2048, buf); -} - -static void -wr_l_path_table(struct ecma119_write_target *t, uint8_t *buf) -{ - ecma119_start_chunking(t, write_l_path_table, t->path_table_size, buf); -} - -static void -wr_m_path_table(struct ecma119_write_target *t, uint8_t *buf) -{ - ecma119_start_chunking(t, write_m_path_table, t->path_table_size, buf); -} - -static void -wr_dir_records(struct ecma119_write_target *t, uint8_t *buf) -{ - ecma119_start_chunking(t, write_dirs, t->total_dir_size, buf); -} - -static void -wr_files(struct ecma119_write_target *t, uint8_t *buf) -{ - struct state_files *f_st = &t->state_files; - size_t nread; - struct ecma119_tree_node *f = t->filelist[f_st->file]; - const char *path = f->iso_self->loc.path; - - if (!f_st->fd) { - f_st->data_len = f->iso_self->attrib.st_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); - } - - 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); - } -} - -static void -write_pri_vol_desc(struct ecma119_write_target *t, uint8_t *buf) -{ - struct ecma119_pri_vol_desc *vol = (struct ecma119_pri_vol_desc*)buf; - struct iso_volume *volume = t->volset->volume[t->volnum]; - char *vol_id = str2ascii(volume->volume_id); - char *pub_id = str2ascii(volume->publisher_id); - char *data_id = str2ascii(volume->data_preparer_id); - char *volset_id = str2ascii(t->volset->volset_id); - - vol->vol_desc_type[0] = 1; - memcpy(vol->std_identifier, "CD001", 5); - vol->vol_desc_version[0] = 1; - memcpy(vol->system_id, "SYSID", 5); - if (vol_id) - strncpy((char*)vol->volume_id, vol_id, 32); - iso_bb(vol->vol_space_size, t->vol_space_size, 4); - iso_bb(vol->vol_set_size, t->volset->volset_size, 2); - iso_bb(vol->vol_seq_number, t->volnum + 1, 2); - iso_bb(vol->block_size, t->block_size, 2); - iso_bb(vol->path_table_size, t->path_table_size, 4); - iso_lsb(vol->l_path_table_pos, t->l_path_table_pos, 4); - iso_msb(vol->m_path_table_pos, t->m_path_table_pos, 4); - - write_one_dir_record(t, t->root, 3, vol->root_dir_record); - - strncpy((char*)vol->vol_set_id, volset_id, 128); - strncpy((char*)vol->publisher_id, pub_id, 128); - strncpy((char*)vol->data_prep_id, data_id, 128); - strncpy((char*)vol->application_id, "APPID", 128); - - iso_datetime_17(vol->vol_creation_time, t->now); - iso_datetime_17(vol->vol_modification_time, t->now); - iso_datetime_17(vol->vol_effective_time, t->now); - vol->file_structure_version[0] = 1; - - free(vol_id); - free(volset_id); - free(pub_id); - free(data_id); -} - -static void -write_vol_desc_terminator(struct ecma119_write_target *t, uint8_t *buf) -{ - struct ecma119_vol_desc_terminator *vol = - (struct ecma119_vol_desc_terminator*) buf; - - vol->vol_desc_type[0] = 255; - memcpy(vol->std_identifier, "CD001", 5); - vol->vol_desc_version[0] = 1; -} - -static void -write_path_table(struct ecma119_write_target *t, int l_type, uint8_t *buf) -{ - void (*write_int)(uint8_t*, uint32_t, int) = l_type ? iso_lsb - : iso_msb; - size_t i; - struct ecma119_path_table_record *rec; - struct ecma119_tree_node *dir; - int parent = 0; - - for (i = 0; i < t->dirlist_len; i++) { - dir = t->pathlist[i]; - while ((i) && t->pathlist[parent] != dir->parent) - parent++; - assert(parent < i || i == 0); - - rec = (struct ecma119_path_table_record*) buf; - rec->len_di[0] = dir->parent ? (uint8_t) strlen(dir->name) : 1; - rec->len_xa[0] = 0; - write_int(rec->block, dir->block, 4); - write_int(rec->parent, parent + 1, 2); - if (dir->parent) - memcpy(rec->dir_id, dir->name, rec->len_di[0]); - buf += 8 + rec->len_di[0] + (rec->len_di[0] % 2); - } -} - -static void -write_l_path_table(struct ecma119_write_target *t, uint8_t *buf) -{ - write_path_table(t, 1, buf); -} - -static void -write_m_path_table(struct ecma119_write_target *t, uint8_t *buf) -{ - write_path_table(t, 0, buf); -} - -/* if file_id is >= 0, we use it instead of the filename. As a magic number, - * file_id == 3 means that we are writing the root directory record (in order - * to distinguish it from the "." entry in the root directory) */ -static void -write_one_dir_record(struct ecma119_write_target *t, - struct ecma119_tree_node *node, - int file_id, - uint8_t *buf) -{ - uint8_t len_dr = (file_id >= 0) ? 34 : node->dirent_len; - uint8_t len_fi = (file_id >= 0) ? 1 : strlen(node->name); - uint8_t f_id = (uint8_t) ((file_id == 3) ? 0 : file_id); - uint8_t *name = (file_id >= 0) ? &f_id : (uint8_t*)node->name; - uint32_t len = (node->type == ECMA119_DIR) ? node->dir.len - : node->file.real_me ? 0 : node->iso_self->attrib.st_size; - struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf; - - /* we don't write out susp fields for the root node */ - if (t->rockridge) { - if (file_id == 0) { - susp_write(t, &node->dir.self_susp, &buf[len_dr]); - len_dr += node->dir.self_susp.non_CE_len; - } else if (file_id == 1) { - susp_write(t, &node->dir.parent_susp, &buf[len_dr]); - len_dr += node->dir.parent_susp.non_CE_len; - } else if (file_id < 0) { - susp_write(t, &node->susp, &buf[len_dr]); - len_dr += node->susp.non_CE_len; - } - } - if (file_id == 1 && node->parent) - node = node->parent; - - rec->len_dr[0] = len_dr; - iso_bb(rec->block, node->block, 4); - iso_bb(rec->length, len, 4); - iso_datetime_7(rec->recording_time, t->now); - rec->flags[0] = (node->type == ECMA119_DIR) ? 2 : 0; - iso_bb(rec->vol_seq_number, t->volnum + 1, 2); - rec->len_fi[0] = len_fi; - memcpy(rec->file_id, name, len_fi); -} - -static void -write_one_dir(struct ecma119_write_target *t, - struct ecma119_tree_node *dir, - uint8_t *buf) -{ - size_t i; - uint8_t *orig_buf = buf; - - assert(dir->type == ECMA119_DIR); - /* write the "." and ".." entries first */ - write_one_dir_record(t, dir, 0, buf); - buf += ((struct ecma119_dir_record*) buf)->len_dr[0]; - - write_one_dir_record(t, dir, 1, buf); - buf += ((struct ecma119_dir_record*) buf)->len_dr[0]; - - for (i = 0; i < dir->dir.nchildren; i++) { - write_one_dir_record(t, dir->dir.children[i], -1, buf); - buf += ((struct ecma119_dir_record*) buf)->len_dr[0]; - } - - /* write the susp continuation areas */ - if (t->rockridge) { - susp_write_CE(t, &dir->dir.self_susp, buf); - buf += dir->dir.self_susp.CE_len; - susp_write_CE(t, &dir->dir.parent_susp, buf); - buf += dir->dir.parent_susp.CE_len; - for (i = 0; i < dir->dir.nchildren; i++) { - susp_write_CE(t, &dir->dir.children[i]->susp, buf); - buf += dir->dir.children[i]->susp.CE_len; - } - } - assert (buf - orig_buf == dir->dir.len + dir->dir.CE_len); -} - -static void -write_dirs(struct ecma119_write_target *t, uint8_t *buf) -{ - size_t i; - struct ecma119_tree_node *dir; - for (i = 0; i < t->dirlist_len; i++) { - dir = t->dirlist[i]; - write_one_dir(t, dir, buf); - buf += round_up(dir->dir.len + dir->dir.CE_len, t->block_size); - } -} - -void -ecma119_start_chunking(struct ecma119_write_target *t, - write_fn writer, - off_t data_size, - uint8_t *buf) -{ - if (data_size != t->state_data_size) { - data_size = round_up(data_size, t->block_size); - t->state_data = realloc(t->state_data, data_size); - t->state_data_size = data_size; - } - memset(t->state_data, 0, t->state_data_size); - t->state_data_off = 0; - t->state_data_valid = 1; - writer(t, t->state_data); - write_data_chunk(t, buf); -} - -static void -write_data_chunk(struct ecma119_write_target *t, uint8_t *buf) -{ - memcpy(buf, t->state_data + t->state_data_off, t->block_size); - t->state_data_off += t->block_size; - if (t->state_data_off >= t->state_data_size) { - assert (t->state_data_off <= t->state_data_size); - t->state_data_valid = 0; - next_state(t); - } -} - -static int -bs_read(struct burn_source *bs, unsigned char *buf, int size) -{ - struct ecma119_write_target *t = (struct ecma119_write_target*)bs->data; - if (size != t->block_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) { - return 0; - } - if (t->state_data_valid) - write_data_chunk(t, buf); - else - writers[t->state](t, buf); - t->curblock++; - return size; -} - -static off_t -bs_get_size(struct burn_source *bs) -{ - struct ecma119_write_target *t = (struct ecma119_write_target*)bs->data; - return t->total_size; -} - -static void -bs_free_data(struct burn_source *bs) -{ - struct ecma119_write_target *t = (struct ecma119_write_target*)bs->data; - ecma119_tree_free(t->root); - free(t->dirlist); - free(t->pathlist); - free(t->dirlist_joliet); - free(t->pathlist_joliet); - free(t->filelist); - free(t->state_data); - if (t->state_files.fd) - fclose(t->state_files.fd); -} - -struct burn_source *iso_source_new_ecma119(struct iso_volset *volset, - int volnum, - int level, - int flags) -{ - struct burn_source *ret = calloc(1, sizeof(struct burn_source)); - ret->refcount = 1; - ret->read = bs_read; - ret->get_size = bs_get_size; - ret->free_data = bs_free_data; - ret->data = ecma119_target_new(volset, volnum, level, flags); - return ret; -} diff --git a/libisofs/ecma119.h b/libisofs/ecma119.h deleted file mode 100755 index 7950550..0000000 --- a/libisofs/ecma119.h +++ /dev/null @@ -1,267 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ -/* vim: set noet ts=8 sts=8 sw=8 : */ - -/** - * \file ecma119.h - * - * Structures and definitions used for writing an emca119 (ISO9660) compatible - * volume. - */ - -#ifndef LIBISO_ECMA119_H -#define LIBISO_ECMA119_H - -#include -#include -#include /* for FILE */ -#include -#include "susp.h" - -struct ecma119_tree_node; -struct joliet_tree_node; - -/** - * The possible states that the ecma119 writer can be in. - */ -enum ecma119_write_state -{ - ECMA119_WRITE_BEFORE, - - ECMA119_WRITE_SYSTEM_AREA, - ECMA119_WRITE_PRI_VOL_DESC, - ECMA119_WRITE_SUP_VOL_DESC_JOLIET, - ECMA119_WRITE_VOL_DESC_TERMINATOR, - ECMA119_WRITE_L_PATH_TABLE, - ECMA119_WRITE_M_PATH_TABLE, - ECMA119_WRITE_L_PATH_TABLE_JOLIET, - ECMA119_WRITE_M_PATH_TABLE_JOLIET, - ECMA119_WRITE_DIR_RECORDS, - ECMA119_WRITE_DIR_RECORDS_JOLIET, - ECMA119_WRITE_FILES, - - ECMA119_WRITE_DONE -}; - -/** - * Data describing the state of the ecma119 writer. Everything here should be - * considered private! - */ -struct ecma119_write_target -{ - struct ecma119_tree_node *root; - struct joliet_tree_node *joliet_root; - struct iso_volset *volset; - int volnum; - - time_t now; /**< Time at which writing began. */ - off_t total_size; /**< Total size of the output. This only - * includes the current volume. */ - uint32_t vol_space_size; - - unsigned int rockridge:1; - unsigned int joliet:1; - unsigned int iso_level:2; - - int curblock; - uint16_t block_size; - uint32_t path_table_size; - uint32_t path_table_size_joliet; - uint32_t l_path_table_pos; - uint32_t m_path_table_pos; - uint32_t l_path_table_pos_joliet; - uint32_t m_path_table_pos_joliet; - uint32_t total_dir_size; - uint32_t total_dir_size_joliet; - - struct ecma119_tree_node **dirlist; - /**< A pre-order list of directories - * (this is the order in which we write - * out directory records). - */ - struct ecma119_tree_node **pathlist; - /**< A breadth-first list of - * directories. This is used for - * writing out the path tables. - */ - size_t dirlist_len; /**< The length of the previous 2 lists. - */ - - struct ecma119_tree_node **filelist; - /**< A pre-order list of files with - * non-NULL paths and non-zero sizes. - */ - size_t filelist_len; /* Length of the previous list. */ - - int curfile; /**< Used as a helper field for writing - out filelist and dirlist */ - - /* Joliet versions of the above lists. Since Joliet doesn't require - * directory relocation, the order of these lists might be different - * from the lists above (but they will be the same length). - */ - struct joliet_tree_node **dirlist_joliet; - struct joliet_tree_node **pathlist_joliet; - - enum ecma119_write_state state; /* The current state of the writer. */ - - /* Most writers work by - * 1) making sure state_data is big enough for their data - * 2) writing _all_ their data into state_data - * 3) relying on write_data_chunk to write the data block - * by block. - */ - uint8_t *state_data; - off_t state_data_size; - off_t state_data_off; - int state_data_valid; - - /* for writing out files */ - struct state_files { - off_t pos; /* The number of bytes we have written - * so far in the current file. - */ - off_t data_len;/* The number of bytes in the currently - * open file. - */ - FILE *fd; /* The currently open file. */ - int file; /* The index in filelist that we are - * currently writing (or about to write). */ - } state_files; -}; - -/** - * Create a new ecma119_write_target from the given volume number of the - * given volume set. - * - * \pre \p volnum is less than \p volset-\>volset_size. - * \post For each node in the tree, writer_data has been allocated. - * \post The directory heirarchy has been reorganised to be ecma119-compatible. - */ -struct ecma119_write_target *ecma119_target_new(struct iso_volset *volset, - int volnum, - int level, - int flags); - -#define BP(a,b) [(b) - (a) + 1] - -struct ecma119_pri_vol_desc -{ - uint8_t vol_desc_type BP(1, 1); - uint8_t std_identifier BP(2, 6); - uint8_t vol_desc_version BP(7, 7); - uint8_t unused1 BP(8, 8); - uint8_t system_id BP(9, 40); - uint8_t volume_id BP(41, 72); - uint8_t unused2 BP(73, 80); - uint8_t vol_space_size BP(81, 88); - uint8_t unused3 BP(89, 120); - uint8_t vol_set_size BP(121, 124); - uint8_t vol_seq_number BP(125, 128); - uint8_t block_size BP(129, 132); - uint8_t path_table_size BP(133, 140); - uint8_t l_path_table_pos BP(141, 144); - uint8_t opt_l_path_table_pos BP(145, 148); - uint8_t m_path_table_pos BP(149, 152); - uint8_t opt_m_path_table_pos BP(153, 156); - uint8_t root_dir_record BP(157, 190); - uint8_t vol_set_id BP(191, 318); - uint8_t publisher_id BP(319, 446); - uint8_t data_prep_id BP(447, 574); - uint8_t application_id BP(575, 702); - uint8_t copyright_file_id BP(703, 739); - uint8_t abstract_file_id BP(740, 776); - uint8_t bibliographic_file_id BP(777, 813); - uint8_t vol_creation_time BP(814, 830); - uint8_t vol_modification_time BP(831, 847); - uint8_t vol_expiration_time BP(848, 864); - uint8_t vol_effective_time BP(865, 881); - uint8_t file_structure_version BP(882, 882); - uint8_t reserved1 BP(883, 883); - uint8_t app_use BP(884, 1395); - uint8_t reserved2 BP(1396, 2048); -}; - -struct ecma119_sup_vol_desc -{ - uint8_t vol_desc_type BP(1, 1); - uint8_t std_identifier BP(2, 6); - uint8_t vol_desc_version BP(7, 7); - uint8_t vol_flags BP(8, 8); - uint8_t system_id BP(9, 40); - uint8_t volume_id BP(41, 72); - uint8_t unused2 BP(73, 80); - uint8_t vol_space_size BP(81, 88); - uint8_t esc_sequences BP(89, 120); - uint8_t vol_set_size BP(121, 124); - uint8_t vol_seq_number BP(125, 128); - uint8_t block_size BP(129, 132); - uint8_t path_table_size BP(133, 140); - uint8_t l_path_table_pos BP(141, 144); - uint8_t opt_l_path_table_pos BP(145, 148); - uint8_t m_path_table_pos BP(149, 152); - uint8_t opt_m_path_table_pos BP(153, 156); - uint8_t root_dir_record BP(157, 190); - uint8_t vol_set_id BP(191, 318); - uint8_t publisher_id BP(319, 446); - uint8_t data_prep_id BP(447, 574); - uint8_t application_id BP(575, 702); - uint8_t copyright_file_id BP(703, 739); - uint8_t abstract_file_id BP(740, 776); - uint8_t bibliographic_file_id BP(777, 813); - uint8_t vol_creation_time BP(814, 830); - uint8_t vol_modification_time BP(831, 847); - uint8_t vol_expiration_time BP(848, 864); - uint8_t vol_effective_time BP(865, 881); - uint8_t file_structure_version BP(882, 882); - uint8_t reserved1 BP(883, 883); - uint8_t app_use BP(884, 1395); - uint8_t reserved2 BP(1396, 2048); -}; - -struct ecma119_vol_desc_terminator -{ - uint8_t vol_desc_type BP(1, 1); - uint8_t std_identifier BP(2, 6); - uint8_t vol_desc_version BP(7, 7); - uint8_t reserved BP(8, 2048); -}; - -struct ecma119_dir_record -{ - uint8_t len_dr BP(1, 1); - uint8_t len_xa BP(2, 2); - uint8_t block BP(3, 10); - uint8_t length BP(11, 18); - uint8_t recording_time BP(19, 25); - uint8_t flags BP(26, 26); - uint8_t file_unit_size BP(27, 27); - uint8_t interleave_gap_size BP(28, 28); - uint8_t vol_seq_number BP(29, 32); - uint8_t len_fi BP(33, 33); - uint8_t file_id BP(34, 34); /* 34 to 33+len_fi */ - /* padding field (if len_fi is even) */ - /* system use (len_dr - len_su + 1 to len_dr) */ -}; - -struct ecma119_path_table_record -{ - uint8_t len_di BP(1, 1); - uint8_t len_xa BP(2, 2); - uint8_t block BP(3, 6); - uint8_t parent BP(7, 8); - uint8_t dir_id BP(9, 9); /* 9 to 8+len_di */ - /* padding field (if len_di is odd) */ -}; - -/** - * A utility function for writers that want to write their data all at once - * rather than block-by-block. This creates a buffer of size \p size, passes - * it to the given writer, then hands out block-sized chunks. - */ -void -ecma119_start_chunking(struct ecma119_write_target *t, - void (*)(struct ecma119_write_target*, uint8_t*), - off_t size, - uint8_t *buf); - -#endif /* LIBISO_ECMA119_H */ diff --git a/libisofs/ecma119_tree.c b/libisofs/ecma119_tree.c deleted file mode 100644 index 0cbd387..0000000 --- a/libisofs/ecma119_tree.c +++ /dev/null @@ -1,312 +0,0 @@ -/* vim: set noet ts=8 sts=8 sw=8 : */ - -#include -#include -#include -#include - -#include "ecma119.h" -#include "ecma119_tree.h" -#include "tree.h" -#include "util.h" - -static size_t calc_dirent_len(struct ecma119_tree_node *n) -{ - int ret = n->name ? strlen(n->name) + 33 : 34; - if (ret % 2) ret++; - return ret; -} - -static struct ecma119_tree_node* -create_dir(struct ecma119_write_target *t, - struct ecma119_tree_node *parent, - struct iso_tree_node *iso) -{ - struct ecma119_tree_node *ret; - - assert(t && (!parent || parent->type == ECMA119_DIR) - && iso && S_ISDIR(iso->attrib.st_mode)); - - ret = calloc(1, sizeof(struct ecma119_tree_node)); - ret->name = iso->name ? ((t->iso_level == 1) ? iso_1_dirid(iso->name) - : iso_2_dirid(iso->name)) - : NULL; - ret->dirent_len = calc_dirent_len(ret); - ret->iso_self = iso; - ret->target = t; - ret->type = ECMA119_DIR; - ret->parent = ret->dir.real_parent = parent; - ret->dir.depth = parent ? parent->dir.depth + 1 : 1; - ret->dir.nchildren = iso->nchildren; - ret->dir.children = calloc(1, sizeof(void*) * iso->nchildren); - return ret; -} - -static struct ecma119_tree_node* -create_file(struct ecma119_write_target *t, - struct ecma119_tree_node *parent, - struct iso_tree_node *iso) -{ - struct ecma119_tree_node *ret; - - assert(t && iso && parent && parent->type == ECMA119_DIR); - - ret = calloc(1, sizeof(struct ecma119_tree_node)); - ret->name = iso->name ? ((t->iso_level == 1) ? iso_1_fileid(iso->name) - : iso_2_fileid(iso->name)) - : NULL; - ret->dirent_len = calc_dirent_len(ret); - ret->parent = parent; - ret->iso_self = iso; - ret->target = t; - ret->type = ECMA119_FILE; - return ret; -} - -static struct ecma119_tree_node* -create_tree(struct ecma119_write_target *t, - struct ecma119_tree_node *parent, - struct iso_tree_node *iso) -{ - struct ecma119_tree_node *ret; - size_t i; - - assert(t && iso); - - ret = (S_ISDIR(iso->attrib.st_mode) ? create_dir : create_file) - (t, parent, iso); - for (i = 0; i < iso->nchildren; i++) { - ret->dir.children[i] = create_tree(t, ret, iso->children[i]); - } - return ret; -} - -void -ecma119_tree_free(struct ecma119_tree_node *root) -{ - size_t i; - - if (root->type == ECMA119_DIR) { - for (i=0; i < root->dir.nchildren; i++) { - ecma119_tree_free(root->dir.children[i]); - } - free(root->dir.children); - } - free(root->name); - free(root); -} - -static size_t -max_child_name_len(struct ecma119_tree_node *root) -{ - size_t ret = 0, i; - - assert(root->type == ECMA119_DIR); - for (i=0; i < root->dir.nchildren; i++) { - size_t len = strlen(root->dir.children[i]->name); - ret = MAX(ret, len); - } - return ret; -} - -static void -reparent(struct ecma119_tree_node *child, - struct ecma119_tree_node *parent) -{ - int found = 0; - size_t i; - struct ecma119_tree_node *placeholder; - - assert(child && parent && parent->type == ECMA119_DIR && child->parent); - - /* replace the child in the original parent with a placeholder */ - for (i=0; i < child->parent->dir.nchildren; i++) { - if (child->parent->dir.children[i] == child) { - placeholder = create_file(child->target, - child->parent, - child->iso_self); - placeholder->file.real_me = child; - child->parent->dir.children[i] = placeholder; - found = 1; - break; - } - } - assert(found); - - /* add the child to its new parent */ - child->parent = parent; - parent->dir.nchildren++; - parent->dir.children = realloc( parent->dir.children, - sizeof(void*) * parent->dir.nchildren ); - parent->dir.children[parent->dir.nchildren-1] = child; -} - -/** - * Reorder the tree, if necessary, to ensure that - * - the depth is at most 8 - * - each path length is at most 255 characters - */ -static void -reorder_tree(struct ecma119_tree_node *root, - struct ecma119_tree_node *cur) -{ - size_t max_path; - - assert(root && cur && cur->type == ECMA119_DIR); - - cur->dir.depth = cur->parent ? cur->parent->dir.depth + 1 : 1; - cur->dir.path_len = cur->parent ? cur->parent->dir.path_len - + strlen(cur->name) : 0; - max_path = cur->dir.path_len + cur->dir.depth + max_child_name_len(cur); - - if (cur->dir.depth > 8 || max_path > 255) { - reparent(cur, root); - /* we are appended to the root's children now, so there is no - * need to recurse (the root will hit us again) */ - } else { - size_t i; - - for (i=0; i < cur->dir.nchildren; i++) { - if (cur->dir.children[i]->type == ECMA119_DIR) - reorder_tree(root, cur->dir.children[i]); - } - } -} - -static int -cmp_node(const void *f1, const void *f2) -{ - struct ecma119_tree_node *f = *((struct ecma119_tree_node**)f1); - struct ecma119_tree_node *g = *((struct ecma119_tree_node**)f2); - return strcmp(f->name, g->name); -} - -static void -sort_tree(struct ecma119_tree_node *root) -{ - size_t i; - - assert(root && root->type == ECMA119_DIR); - - qsort(root->dir.children, root->dir.nchildren, sizeof(void*), cmp_node); - for (i=0; i < root->dir.nchildren; i++) { - if (root->dir.children[i]->type == ECMA119_DIR) - sort_tree(root->dir.children[i]); - } -} - -/** - * Change num_change characters of the given filename in order to ensure the - * name is unique. If the name is short enough (depending on the ISO level), - * we can append the characters instead of changing them. - * - * \p seq_num is the index of this file in the sequence of identical filenames. - * - * For example, seq_num=3, num_change=2, name="HELLOTHERE.TXT" changes name to - * "HELLOTHE03.TXT" - */ -static void -mangle_name(char **name, int num_change, int level, int seq_num) -{ - char *dot = strrchr(*name, '.'); - char *semi = strrchr(*name, ';'); - size_t len = strlen(*name); - char base[len+1], ext[len+1]; - char fmt[12]; - size_t baselen, extlen; - - if (num_change >= len) { - return; - } - strncpy(base, *name, len+1); - if (dot) { - base[dot - *name] = '\0'; - strncpy(ext, dot+1, len+1); - if (semi) { - ext[semi - dot - 1] = '\0'; - } - } else { - base[len-2] = '\0'; - ext[0] = '\0'; - } - baselen = strlen(base); - extlen = strlen(ext); - if (level == 1 && baselen + num_change > 8) { - base[8 - num_change] = '\0'; - } else if (level != 1 && baselen + extlen + num_change > 30) { - base[30 - extlen - num_change] = '\0'; - } - - sprintf(fmt, "%%s%%0%1dd.%%s;1", num_change); - *name = realloc(*name, baselen + extlen + num_change + 4); - sprintf(*name, fmt, base, seq_num, ext); -} - -static void -mangle_all(struct ecma119_tree_node *dir) -{ - size_t i, j, k; - struct ecma119_dir_info d = dir->dir; - size_t n_change; - int changed; - - assert(dir->type == ECMA119_DIR); - do { - changed = 0; - for (i=0; i < d.nchildren; i++) { - /* find the number of consecutive equal names */ - j = 1; - while ( i+j < d.nchildren && - !strcmp(d.children[i]->name, - d.children[i+j]->name) ) - j++; - if (j == 1) continue; - - /* mangle the names */ - changed = 1; - n_change = j / 10 + 1; - for (k=0; k < j; k++) { - mangle_name(&(d.children[i+k]->name), - n_change, - dir->target->iso_level, - k); - d.children[i+k]->dirent_len = - calc_dirent_len(d.children[i+k]); - } - - /* skip ahead by the number of mangled names */ - i += j - 1; - } - } while (changed); - - for (i=0; i < d.nchildren; i++) { - if (d.children[i]->type == ECMA119_DIR) - mangle_all(d.children[i]); - } -} - -struct ecma119_tree_node* -ecma119_tree_create(struct ecma119_write_target *t, - struct iso_tree_node *iso_root) -{ - t->root = create_tree(t, NULL, iso_root); - reorder_tree(t->root, t->root); - sort_tree(t->root); - mangle_all(t->root); - return t->root; -} - -void -ecma119_tree_print(struct ecma119_tree_node *root, int spaces) -{ - size_t i; - char sp[spaces+1]; - - memset(sp, ' ', spaces); - sp[spaces] = '\0'; - - printf("%s%s\n", sp, root->name); - if (root->type == ECMA119_DIR) - for (i=0; i < root->dir.nchildren; i++) - ecma119_tree_print(root->dir.children[i], spaces+2); -} diff --git a/libisofs/ecma119_tree.h b/libisofs/ecma119_tree.h deleted file mode 100644 index 1d6023b..0000000 --- a/libisofs/ecma119_tree.h +++ /dev/null @@ -1,95 +0,0 @@ -/* vim: set noet ts=8 sts=8 sw=8 : */ - -/** - * \file ecma119_tree.h - * - * Declarations for creating, modifying and printing filesystem trees that - * are compatible with ecma119. - */ - -#ifndef LIBISO_ECMA119_TREE_H -#define LIBISO_ECMA119_TREE_H - -struct ecma119_write_target; - -enum { - ECMA119_FILE, - ECMA119_DIR -}; - -struct ecma119_dir_info { - struct susp_info self_susp; /**< susp entries for "." */ - struct susp_info parent_susp; /**< susp entries for ".." */ - - size_t len; /**< sum of the lengths of children's - * Directory Records (including SU) */ - size_t CE_len; /**< sum of the lengths of children's - * SUSP CE areas */ - - int depth; - size_t path_len; /**< The length of a path up to, and - * including, this directory. This - * cannot exceed 255. */ - size_t nchildren; - struct ecma119_tree_node **children; - - struct ecma119_tree_node *real_parent; - /**< The parent before relocation */ -}; - -struct ecma119_file_info -{ - struct ecma119_tree_node *real_me; - /**< If this is non-NULL, the file is - * a placeholder for a relocated - * directory and this field points to - * that relocated directory. - */ -}; - -/** - * A node for a tree containing all the information necessary for writing - * an ISO9660 volume. - */ -struct ecma119_tree_node -{ - char *name; /**< in ASCII, conforming to the - * current ISO level. */ - size_t dirent_len; /**< Length of the directory record, - * not including SU. */ - size_t block; - - struct ecma119_tree_node *parent; - struct iso_tree_node *iso_self; - struct ecma119_write_target *target; - - struct susp_info susp; - - int type; /**< file or directory */ - /* union {*/ - struct ecma119_dir_info dir; - struct ecma119_file_info file; - /* };*/ -}; - -/** - * Create a new ecma119_tree that corresponds to the tree represented by - * \p iso_root. - */ -struct ecma119_tree_node* -ecma119_tree_create(struct ecma119_write_target *target, - struct iso_tree_node *iso_root); - -/** - * Free an ecma119 tree. - */ -void -ecma119_tree_free(struct ecma119_tree_node *root); - -/** - * Print an ecma119 tree. - */ -void -ecma119_tree_print(struct ecma119_tree_node *root, int spaces); - -#endif /* LIBISO_ECMA119_TREE_H */ diff --git a/libisofs/exclude.c b/libisofs/exclude.c deleted file mode 100644 index 48e7fa2..0000000 --- a/libisofs/exclude.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "hash.h" -#include "exclude.h" - -static struct iso_hash_node *table[HASH_NODES]={0,}; -static int num=0; - -void -iso_exclude_add_path(const char *path) -{ - if (!path) - return; - - num += iso_hash_insert(table, path); -} - -void -iso_exclude_remove_path(const char *path) -{ - if (!num || !path) - return; - - num -= iso_hash_remove(table, path); -} - -void -iso_exclude_empty(void) -{ - if (!num) - return; - - iso_hash_empty(table); - num=0; -} - -int -iso_exclude_lookup(const char *path) -{ - if (!num || !path) - return 0; - - return iso_hash_lookup(table, path); -} diff --git a/libisofs/exclude.h b/libisofs/exclude.h deleted file mode 100644 index 319c418..0000000 --- a/libisofs/exclude.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef ISO_EXCLUDE_H -#define ISO_EXCLUDE_H - -/** - * Add a path to ignore when adding a directory recursively. - * - * \param path The path, on the local filesystem, of the file. - */ -int -iso_exclude_lookup(const char *path); - -#endif /* ISO_EXCLUDE */ diff --git a/libisofs/hash.c b/libisofs/hash.c deleted file mode 100644 index 1976efa..0000000 --- a/libisofs/hash.c +++ /dev/null @@ -1,158 +0,0 @@ -#include -#include - -#include "hash.h" - -static unsigned int -iso_hash_path(const char *path) -{ - unsigned int hash_num=0; - const char *c; - - c=path; - while(*c) - hash_num = (hash_num << 15) + (hash_num << 3) + (hash_num >> 3) + *c++; - - return hash_num % HASH_NODES; -} - -int -iso_hash_lookup(struct iso_hash_node **table, const char *path) -{ - struct iso_hash_node *node; - unsigned int hash_num; - - hash_num = iso_hash_path(path); - - node=table[hash_num]; - - if (!node) - return 0; - - if (!strcmp(path, node->path)) - return 1; - - while (node->next) { - node=node->next; - - if (!strcmp(path, node->path)) - return 1; - } - - return 0; - } - -static struct iso_hash_node* -iso_hash_node_new (const char *path) -{ - struct iso_hash_node *node; - - /*create an element to be inserted in the hash table */ - node=malloc(sizeof(struct iso_hash_node)); - node->path=strdup(path); - node->next=NULL; - - return node; -} - -int -iso_hash_insert(struct iso_hash_node **table, const char *path) -{ - struct iso_hash_node *node; - unsigned int hash_num; - - /* find the hash number */ - hash_num = iso_hash_path(path); - - /* insert it */ - node = table[hash_num]; - - /* unfortunately, we can't safely consider that a path - * won't be twice in the hash table so make sure it - * doesn't already exists */ - if (!node) { - table[hash_num]=iso_hash_node_new(path); - return 1; - } - - /* if it's already in, we don't do anything */ - if (!strcmp(path, node->path)) - return 0; - - while (node->next) { - node = node->next; - - /* if it's already in, we don't do anything */ - if (!strcmp (path, node->path)) - return 0; - } - - node->next = iso_hash_node_new(path); - return 1; -} - -static void -iso_hash_node_free(struct iso_hash_node *node) -{ - free(node->path); - free(node); -} - -int -iso_hash_remove(struct iso_hash_node **table, const char *path) -{ - unsigned int hash_num; - struct iso_hash_node *node; - - hash_num = iso_hash_path(path); - - node=table[hash_num]; - if (!node) - return 0; - - if (!strcmp(path, node->path)) { - table[hash_num]=node->next; - iso_hash_node_free(node); - return 1; - } - - while (node->next) { - struct iso_hash_node *prev; - - prev = node; - node = node->next; - - if (!strcmp (path, node->path)) { - prev->next=node->next; - iso_hash_node_free(node); - return 1; - } - } - - return 0; -} - -void -iso_hash_empty(struct iso_hash_node **table) -{ - int i; - - for (i=0; i < HASH_NODES; i++) { - struct iso_hash_node *node; - - node=table[i]; - if (!node) - continue; - - table[i]=NULL; - - do { - struct iso_hash_node *next; - - next=node->next; - iso_hash_node_free(node); - node=next; - } while (node); - } -} - diff --git a/libisofs/hash.h b/libisofs/hash.h deleted file mode 100644 index 2d691c7..0000000 --- a/libisofs/hash.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef ISO_HASH_H -#define ISO_HASH_H - -struct iso_hash_node { - struct iso_hash_node *next; - char *path; -}; - -#define HASH_NODES 128 - -/** - * Searches in the hash table if the path exists. - * - * \param table The hash table. - * \param path The path of the file to look for. - * - * \return 1 if the path exists in the hash table, 0 otherwise. - */ -int iso_hash_lookup(struct iso_hash_node **table, const char *path); - -/** - * Insert a new path in the hash table. - * - * \param table The hash table. - * \param path The path of a file to add to the hash table. - * - * \return 1 if the file wasn't already in the hash table, 0 otherwise. - */ -int iso_hash_insert(struct iso_hash_node **table, const char *path); - -/** - * Remove a path from the hash table. - * - * \param table The hash table. - * \param path The path of a file to remove from the hash table. - * - * \return 1 if the file was found and removed, 0 otherwise. - */ -int iso_hash_remove(struct iso_hash_node **table, const char *path); - -/** - * Empty the hash table. - */ -void iso_hash_empty(struct iso_hash_node **table); - -#endif /* ISO_HASH_H */ diff --git a/libisofs/joliet.c b/libisofs/joliet.c deleted file mode 100644 index d64675b..0000000 --- a/libisofs/joliet.c +++ /dev/null @@ -1,379 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ -/* vim: set noet ts=8 sts=8 sw=8 : */ - -#include "joliet.h" -#include "ecma119.h" -#include "ecma119_tree.h" -#include "tree.h" -#include "util.h" -#include "volume.h" - -#include -#include - -static struct joliet_tree_node* -create_node(struct ecma119_write_target *t, - struct joliet_tree_node *parent, - struct iso_tree_node *iso) -{ - struct joliet_tree_node *ret = - calloc(1, sizeof(struct joliet_tree_node)); - - ret->name = iso_j_id(iso->name); - ret->dirent_len = 34 + (ret->name ? ucslen(ret->name) * 2 : 0); - ret->len = iso->attrib.st_size; /* for dirs, we'll change this */ - ret->block = iso->block; /* only actually for files, not dirs */ - ret->parent = parent; - ret->iso_self = iso; - ret->target = t; - ret->nchildren = iso->nchildren; - if (ret->nchildren) - ret->children = calloc(sizeof(void*), ret->nchildren); - return ret; -} - -static struct joliet_tree_node* -create_tree(struct ecma119_write_target *t, - struct joliet_tree_node *parent, - struct iso_tree_node *iso_root) -{ - struct joliet_tree_node *root = create_node(t, parent, iso_root); - size_t i; - - for (i = 0; i < root->nchildren; i++) { - struct iso_tree_node *iso_ch = iso_root->children[i]; - if (ISO_ISDIR(iso_ch)) - root->children[i] = create_tree(t, root, iso_ch); - else - root->children[i] = create_node(t, root, iso_ch); - } - return root; -} - -static int -cmp_node(const void *f1, const void *f2) -{ - struct joliet_tree_node *f = *((struct joliet_tree_node**)f1); - struct joliet_tree_node *g = *((struct joliet_tree_node**)f2); - return ucscmp(f->name, g->name); -} - -static void -sort_tree(struct joliet_tree_node *root) -{ - size_t i; - - assert(root && ISO_ISDIR(root->iso_self)); - - qsort(root->children, root->nchildren, sizeof(void*), cmp_node); - for (i = 0; i < root->nchildren; i++) - if (ISO_ISDIR(root->children[i]->iso_self)) - sort_tree(root->children[i]); -} - -void -joliet_prepare_path_tables(struct ecma119_write_target *t) -{ - size_t cur, i, j; - - t->pathlist_joliet[0] = t->joliet_root; - t->path_table_size_joliet = 10; /* root directory record */ - cur = 1; - - for (i = 0; i < t->dirlist_len; i++) { - struct joliet_tree_node *dir = t->pathlist_joliet[i]; - for (j = 0; j < dir->nchildren; j++) { - struct joliet_tree_node *ch = dir->children[j]; - if (ISO_ISDIR(ch->iso_self)) { - size_t len = 8 + ucslen(ch->name)*2; - t->pathlist_joliet[cur++] = ch; - t->path_table_size_joliet += len; - } - } - } -} - -/** - * Calculate the size of each directory. - */ -void -joliet_calc_dir_size(struct ecma119_write_target *t, - struct joliet_tree_node *root) -{ - size_t i; - struct joliet_tree_node *ch; - - assert(root && ISO_ISDIR(root->iso_self)); - - root->len = 68; /* for "." and ".." entries */ - for (i = 0; i < root->nchildren; i++) { - ch = root->children[i]; - root->len += ch->dirent_len; - if (ISO_ISDIR(ch->iso_self)) - joliet_calc_dir_size(t, ch); - } - t->total_dir_size_joliet += round_up (root->len, t->block_size); -} - -/** - * Calculate the position of each directory. Also fill out t->dirlist_joliet. - */ -void -joliet_calc_dir_pos(struct ecma119_write_target *t, - struct joliet_tree_node *root) -{ - size_t i; - struct joliet_tree_node *ch; - - assert(root && ISO_ISDIR(root->iso_self)); - - root->block = t->curblock; - t->curblock += div_up(root->len, t->block_size); - - t->dirlist_joliet[t->curfile++] = root; - for (i = 0; i < root->nchildren; i++) { - ch = root->children[i]; - if (ISO_ISDIR(ch->iso_self)) - joliet_calc_dir_pos(t, ch); - } - - /* reset curfile when we're finished */ - if (!root->parent) - t->curfile = 0; -} - -void -joliet_update_file_pos(struct ecma119_write_target *t, - struct joliet_tree_node *dir) -{ - size_t i; - - assert(dir && ISO_ISDIR(dir->iso_self)); - for (i = 0; i < dir->nchildren; i++) { - struct joliet_tree_node *ch; - ch = dir->children[i]; - - if (!ISO_ISDIR (ch->iso_self)) { - struct iso_tree_node *iso = ch->iso_self; - ch->block = iso->block; - } - else - joliet_update_file_pos(t, ch); - } - - /* reset curfile when we're finished */ - if (!dir->parent) - t->curfile = 0; -} - -struct joliet_tree_node* -joliet_tree_create(struct ecma119_write_target *t, - struct iso_tree_node *iso_root) -{ - struct joliet_tree_node *root = create_tree(t, NULL, iso_root); - - sort_tree(root); - return root; -} - -/* ugh. this is mostly C&P */ -static void -write_path_table(struct ecma119_write_target *t, - int l_type, - uint8_t *buf) -{ - void (*write_int)(uint8_t*, uint32_t, int) = l_type ? - iso_lsb : iso_msb; - - size_t i; - struct ecma119_path_table_record *rec; - struct joliet_tree_node *dir; - int parent = 0; - - assert (t->joliet); - - for (i = 0; i < t->dirlist_len; i++) { - dir = t->pathlist_joliet[i]; - while ((i) && t->pathlist_joliet[parent] != dir->parent) - parent++; - assert(parent < i || i == 0); - - rec = (struct ecma119_path_table_record*) buf; - rec->len_di[0] = dir->parent ? - (uint8_t) ucslen(dir->name) * 2 : 1; - rec->len_xa[0] = 0; - write_int(rec->block, dir->block, 4); - write_int(rec->parent, parent + 1, 2); - if (dir->parent) - memcpy(rec->dir_id, dir->name, rec->len_di[0]); - buf += 8 + rec->len_di[0] + (rec->len_di[0] % 2); - } - -} - -/* if file_id is >= 0, we use it instead of the filename. As a magic number, - * file_id == 3 means that we are writing the root directory record (in order - * to distinguish it from the "." entry in the root directory) */ -static void -write_one_dir_record(struct ecma119_write_target *t, - struct joliet_tree_node *node, - int file_id, - uint8_t *buf) -{ - uint8_t len_dr = (file_id >= 0) ? 34 : node->dirent_len; - uint8_t len_fi = (file_id >= 0) ? 1 : ucslen(node->name) * 2; - uint8_t f_id = (uint8_t) ((file_id == 3) ? 0 : file_id); - uint8_t *name = (file_id >= 0) ? &f_id : (uint8_t*)node->name; - struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf; - - if (file_id == 1 && node->parent) - node = node->parent; - - rec->len_dr[0] = len_dr; - iso_bb(rec->block, node->block, 4); - iso_bb(rec->length, node->len, 4); - iso_datetime_7(rec->recording_time, t->now); - rec->flags[0] = ISO_ISDIR(node->iso_self) ? 2 : 0; - iso_bb(rec->vol_seq_number, t->volnum + 1, 2); - rec->len_fi[0] = len_fi; - memcpy(rec->file_id, name, len_fi); -} - -static void -write_l_path_table(struct ecma119_write_target *t, uint8_t *buf) -{ - write_path_table (t, 1, buf); -} - -static void -write_m_path_table(struct ecma119_write_target *t, uint8_t *buf) -{ - write_path_table (t, 0, buf); -} - -static void -write_sup_vol_desc(struct ecma119_write_target *t, uint8_t *buf) -{ - struct ecma119_sup_vol_desc *vol = (struct ecma119_sup_vol_desc*)buf; - struct iso_volume *volume = t->volset->volume[t->volnum]; - uint16_t *vol_id = str2ucs(volume->volume_id); - uint16_t *pub_id = str2ucs(volume->publisher_id); - uint16_t *data_id = str2ucs(volume->data_preparer_id); - uint16_t *volset_id = str2ucs(t->volset->volset_id); - int vol_id_len = MIN(32, ucslen(vol_id) * 2); - int pub_id_len = MIN(128, ucslen(pub_id) * 2); - int data_id_len = MIN(128, ucslen(data_id) * 2); - int volset_id_len = MIN(128, ucslen(volset_id) * 2); - - vol->vol_desc_type[0] = 2; - memcpy(vol->std_identifier, "CD001", 5); - vol->vol_desc_version[0] = 1; - memcpy(vol->system_id, "SYSID", 5); - if (vol_id) - memcpy(vol->volume_id, vol_id, vol_id_len); - memcpy(vol->esc_sequences, "%/E", 3); - iso_bb(vol->vol_space_size, t->vol_space_size, 4); - iso_bb(vol->vol_set_size, t->volset->volset_size, 2); - iso_bb(vol->vol_seq_number, t->volnum + 1, 2); - iso_bb(vol->block_size, t->block_size, 2); - iso_bb(vol->path_table_size, t->path_table_size_joliet, 4); - iso_lsb(vol->l_path_table_pos, t->l_path_table_pos_joliet, 4); - iso_msb(vol->m_path_table_pos, t->m_path_table_pos_joliet, 4); - - write_one_dir_record(t, t->joliet_root, 3, vol->root_dir_record); - - memcpy(vol->vol_set_id, volset_id, volset_id_len); - memcpy(vol->publisher_id, pub_id, pub_id_len); - memcpy(vol->data_prep_id, data_id, data_id_len); - /*memcpy(vol->application_id, "APPID", app_id_len);*/ - - iso_datetime_17(vol->vol_creation_time, t->now); - iso_datetime_17(vol->vol_modification_time, t->now); - iso_datetime_17(vol->vol_effective_time, t->now); - vol->file_structure_version[0] = 1; - - free(vol_id); - free(volset_id); - free(pub_id); - free(data_id); - -} - -static void -write_one_dir(struct ecma119_write_target *t, - struct joliet_tree_node *dir, - uint8_t *buf) -{ - size_t i; - uint8_t *orig_buf = buf; - - assert(ISO_ISDIR (dir->iso_self)); - /* write the "." and ".." entries first */ - write_one_dir_record(t, dir, 0, buf); - buf += ((struct ecma119_dir_record*) buf)->len_dr[0]; - - write_one_dir_record(t, dir, 1, buf); - buf += ((struct ecma119_dir_record*) buf)->len_dr[0]; - - for (i = 0; i < dir->nchildren; i++) { - write_one_dir_record(t, dir->children[i], -1, buf); - buf += ((struct ecma119_dir_record*) buf)->len_dr[0]; - } - - assert (buf - orig_buf == dir->len); -} - -static void -write_dirs(struct ecma119_write_target *t, uint8_t *buf) -{ - size_t i; - struct joliet_tree_node *dir; - - assert (t->curblock == t->dirlist_joliet[0]->block); - for (i = 0; i < t->dirlist_len; i++) { - dir = t->dirlist_joliet[i]; - write_one_dir(t, dir, buf); - buf += round_up(dir->len, t->block_size); - } -} - -void -joliet_wr_sup_vol_desc(struct ecma119_write_target *t, - uint8_t *buf) -{ - ecma119_start_chunking(t, - write_sup_vol_desc, - 2048, - buf); -} - -void -joliet_wr_l_path_table(struct ecma119_write_target *t, - uint8_t *buf) -{ - ecma119_start_chunking(t, - write_l_path_table, - t->path_table_size_joliet, - buf); -} - -void -joliet_wr_m_path_table(struct ecma119_write_target *t, - uint8_t *buf) -{ - ecma119_start_chunking(t, - write_m_path_table, - t->path_table_size_joliet, - buf); -} - -void -joliet_wr_dir_records(struct ecma119_write_target *t, - uint8_t *buf) -{ - ecma119_start_chunking(t, - write_dirs, - t->total_dir_size_joliet, - buf); -} - diff --git a/libisofs/joliet.h b/libisofs/joliet.h deleted file mode 100644 index e5b7582..0000000 --- a/libisofs/joliet.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ -/* vim: set noet ts=8 sts=8 sw=8 : */ - -/** - * \file joliet.h - * - * Declare the filesystems trees that are Joliet-compatible and the public - * functions for tying them into an ecma119 volume. - */ - -#ifndef LIBISO_JOLIET_H -#define LIBISO_JOLIET_H - -#include -#include - -struct ecma119_write_target; -struct iso_tree_node; - -struct joliet_tree_node -{ - uint16_t *name; /**< In UCS-2BE. */ - size_t dirent_len; - size_t len; - size_t block; - - struct joliet_tree_node *parent; - struct iso_tree_node *iso_self; - struct ecma119_write_target *target; - - struct joliet_tree_node **children; - size_t nchildren; -}; - -/** - * Create a new joliet_tree that corresponds to the tree represented by - * \p iso_root. - */ -struct joliet_tree_node* -joliet_tree_create(struct ecma119_write_target *target, - struct iso_tree_node *iso_root); - -/** - * Calculate the size of each directory in the joliet heirarchy. - */ -void -joliet_calc_dir_size(struct ecma119_write_target *t, struct joliet_tree_node*); - -/** - * Calculate the position of each directory in the joliet heirarchy. - */ -void -joliet_calc_dir_pos(struct ecma119_write_target *t, struct joliet_tree_node*); - -/** - * Update the position of each file in the joliet hierarchy (to be called - * AFTER the file positions in the iso tree have been set). - */ -void -joliet_update_file_pos(struct ecma119_write_target *t, struct joliet_tree_node*); - -/** - * Calculate the size of the joliet path table and fill in the list of - * directories. - */ -void -joliet_prepare_path_tables(struct ecma119_write_target *t); - -void -joliet_tree_free(struct joliet_tree_node *root); - -void -joliet_wr_sup_vol_desc(struct ecma119_write_target *t, uint8_t *buf); - -void -joliet_wr_l_path_table(struct ecma119_write_target *t, uint8_t *buf); - -void -joliet_wr_m_path_table(struct ecma119_write_target *t, uint8_t *buf); - -void -joliet_wr_dir_records(struct ecma119_write_target *t, uint8_t *buf); - -#endif /* LIBISO_JOLIET_H */ diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h deleted file mode 100755 index 0d29cad..0000000 --- a/libisofs/libisofs.h +++ /dev/null @@ -1,225 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ -/* vim: set noet ts=8 sts=8 sw=8 : */ - -/** - * Create an ISO-9660 data volume with Rock Ridge and Joliet extensions. - * Usage is easy: - * - Create a new volume. - * - Add files and directories. - * - Write the volume to a file or create a burn source for use with Libburn. - */ - -#ifndef LIBISO_LIBISOFS_H -#define LIBISO_LIBISOFS_H - -/* #include */ -struct burn_source; - -/** - * Data volume. - * @see volume.h for details. - */ -struct iso_volume; - -/** - * A set of data volumes. - * @see volume.h for details. - */ -struct iso_volset; - -/** - * A node in the filesystem tree. - * \see tree.h - */ -struct iso_tree_node; - -enum ecma119_extension_flag { - ECMA119_ROCKRIDGE = (1<<0), - ECMA119_JOLIET = (1<<1) -}; - -/** - * Create a new volume. - * The parameters can be set to NULL if you wish to set them later. - */ -struct iso_volume *iso_volume_new(const char *volume_id, - const char *publisher_id, - const char *data_preparer_id); - -struct iso_volume *iso_volume_new_with_root(const char *volume_id, - const char *publisher_id, - const char *data_preparer_id, - struct iso_tree_node *root); - -/** - * Free a volume. - */ -void iso_volume_free(struct iso_volume *volume); - -/** - * Free a set of data volumes. - */ -void iso_volset_free(struct iso_volset *volume); - -/** - * Get the root directory for a volume. - */ -struct iso_tree_node *iso_volume_get_root(const struct iso_volume *volume); - -/** - * Fill in the volume identifier for a volume. - */ -void iso_volume_set_volume_id(struct iso_volume *volume, - const char *volume_id); - -/** - * Fill in the publisher for a volume. - */ -void iso_volume_set_publisher_id(struct iso_volume *volume, - const char *publisher_id); - -/** - * Fill in the data preparer for a volume. - */ -void iso_volume_set_data_preparer_id(struct iso_volume *volume, - const char *data_preparer_id); - -/** - * Locate a node by its path on disc. - * - * \param volume The volume to search in. - * \param path The path, in the image, of the file. - * - * \return The node found or NULL. - * - */ -struct iso_tree_node *iso_tree_volume_path_to_node(struct iso_volume *volume, const char *path); - -/** - * 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. - * \param disc_path The path on the disc at which to add the disc. - * \param path The path, on the local filesystem, of the file. - * - * \return The node for the file or NULL if the parent doesn't exists on the disc. - */ -struct iso_tree_node *iso_tree_volume_add_path(struct iso_volume *volume, - const char *disc_path, - const char *path); - -/** - * Creates a new, empty directory on the volume. - * - * \param volume The volume to add the directory to. - * \param disc_path The path on the volume at which to add the directory. - * - * \return A pointer to the newly created directory. - */ -struct iso_tree_node *iso_tree_volume_add_new_dir(struct iso_volume *volume, - const char *disc_path); - -/** - * Create a new Volume Set consisting of only one volume. - * @param volume The first and only volume for the volset to contain. - * @param volset_id The Volume Set ID. - * @return A new iso_volset. - */ -struct iso_volset *iso_volset_new(struct iso_volume *volume, - const char *volset_id); - -/** - * Add a file to a directory. - * - * \param path The path, on the local filesystem, of the file. - * - * \pre \p parent is NULL or is a directory. - * \pre \p path is non-NULL and is a valid path to a non-directory on the local - * filesystem. - * \return An iso_tree_node whose path is \p path and whose parent is \p parent. - */ -struct iso_tree_node *iso_tree_add_node(struct iso_tree_node *parent, - const char *path); - -/** - * 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, - * use iso_tree_add_file and iso_tree_add_dir. - * - * \param path The path, on the local filesystem, of the directory to add. - * - * \pre \p parent is NULL or is a directory. - * \pre \p path is non-NULL and is a valid path to a directory on the local - * filesystem. - * \return a pointer to the newly created directory. - */ -struct iso_tree_node *iso_tree_radd_dir(struct iso_tree_node *parent, - const char *path); - - -/** - * Add the path of a file or directory to ignore when adding a directory recursively. - * - * \param path The path, on the local filesystem, of the file. - */ -void iso_exclude_add_path(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(const char *path); - -/** - * Remove all paths that were set to be ignored when adding a directory recusively. - */ -void iso_exclude_empty(void); - -/** - * Creates a new, empty directory on the volume. - * - * \pre \p parent is NULL or is a directory. - * \pre \p name is unique among the children and files belonging to \p parent. - * Also, it doesn't contain '/' characters. - * - * \post \p parent contains a child directory whose name is \p name and whose - * POSIX attributes are the same as \p parent's. - * \return a pointer to the newly created directory. - */ -struct iso_tree_node *iso_tree_add_new_dir(struct iso_tree_node *parent, - const char *name); - -/** - * Set the name of a file (using the current locale). - */ -void iso_tree_node_set_name(struct iso_tree_node *file, const char *name); - -/** - * Recursively print a directory to stdout. - * \param spaces The initial number of spaces on the left. Set to 0 if you - * supply a root directory. - */ -void iso_tree_print(const struct iso_tree_node *root, int spaces); - -/** Create a burn_source which can be used as a data source for a track - * - * The volume set used to create the libburn_source can _not_ be modified - * until the libburn_source is freed. - * - * \param volumeset The volume set from which you want to write - * \param volnum The volume in the set which you want to write (usually 0) - * \param level ISO level to write at. - * \param flags Which extensions to support. - * - * \pre \p volumeset is non-NULL - * \pre \p volnum is less than \p volset->volset_size. - * \return A burn_source to be used for the data source for a track - */ -struct burn_source* iso_source_new_ecma119 (struct iso_volset *volumeset, - int volnum, - int level, - int flags); - -#endif /* LIBISO_LIBISOFS_H */ diff --git a/libisofs/rockridge.c b/libisofs/rockridge.c deleted file mode 100755 index 3662ac6..0000000 --- a/libisofs/rockridge.c +++ /dev/null @@ -1,300 +0,0 @@ -/* vim: set noet ts=8 sts=8 sw=8 : */ - -#include "rockridge.h" -#include "util.h" -#include "ecma119.h" -#include "ecma119_tree.h" -#include "tree.h" -#include "susp.h" - -#include -#include -#include -#include -#include -#include - -/* create a PX field from the permissions on the current node. */ -uint8_t *rrip_make_PX(struct ecma119_write_target *t, - struct ecma119_tree_node *node) -{ - uint8_t *PX = malloc(44); - - PX[0] = 'P'; - PX[1] = 'X'; - PX[2] = 44; - PX[3] = 1; - iso_bb(&PX[4], node->iso_self->attrib.st_mode, 4); - iso_bb(&PX[12], node->iso_self->attrib.st_nlink, 4); - iso_bb(&PX[20], node->iso_self->attrib.st_uid, 4); - iso_bb(&PX[28], node->iso_self->attrib.st_gid, 4); - iso_bb(&PX[36], node->iso_self->attrib.st_ino, 4); - return PX; -} - -/** See IEEE 1282 4.1.1 */ -void rrip_add_PX(struct ecma119_write_target *t, struct ecma119_tree_node *node) -{ - susp_append(t, &node->susp, rrip_make_PX(t, node)); - if (node->type == ECMA119_DIR) { - susp_append(t, &node->dir.self_susp, rrip_make_PX(t, node)); - susp_append(t, &node->dir.parent_susp, rrip_make_PX(t, node)); - } -} - -void rrip_add_PN(struct ecma119_write_target *t, struct ecma119_tree_node *node) -{ - uint8_t *PN = malloc(20); - - PN[0] = 'P'; - PN[1] = 'N'; - PN[2] = 20; - PN[3] = 1; - iso_bb(&PN[4], node->iso_self->attrib.st_dev >> 32, 4); - iso_bb(&PN[12], node->iso_self->attrib.st_dev & 0xffffffff, 4); - susp_append(t, &node->susp, PN); -} - -static void rrip_SL_append_comp(int *n, uint8_t ***comps, - char *s, int size, char fl) -{ - uint8_t *comp = malloc(size + 2); - - (*n)++; - comp[0] = fl; - comp[1] = size; - *comps = realloc(*comps, (*n) * sizeof(void*)); - (*comps)[(*n) - 1] = comp; - - if (size) { - memcpy(&comp[2], s, size); - } -} - -static void rrip_SL_add_component(char *prev, char *cur, int *n_comp, - uint8_t ***comps) -{ - int size = cur - prev; - - if (size == 0) { - rrip_SL_append_comp(n_comp, comps, prev, 0, 1 << 3); - return; - } - - if (size == 1 && prev[0] == '.') { - rrip_SL_append_comp(n_comp, comps, prev, 0, 1 << 1); - return; - } - if (size == 2 && !strncmp(prev, "..", 2)) { - rrip_SL_append_comp(n_comp, comps, prev, 0, 1 << 2); - return; - } - - /* we can't make a component any bigger than 250 (is this really a - problem)? because then it won't fit inside the SL field */ - while (size > 248) { - size -= 248; - rrip_SL_append_comp(n_comp, comps, prev, 248, 1 << 0); - } - - rrip_SL_append_comp(n_comp, comps, prev, size, 0); -} - -void rrip_add_SL(struct ecma119_write_target *t, struct ecma119_tree_node *node) -{ - int ret, pathsize = 0; - char *path = NULL, *cur, *prev; - int i, j; - - uint8_t **comp = NULL; - int n_comp = 0; - int total_comp_len = 0; - int written = 0, pos; - - uint8_t *SL; - - do { - pathsize += 128; - path = realloc(path, pathsize); - /* FIXME: what if the file is not on the local fs? */ - ret = readlink(node->iso_self->loc.path, path, pathsize); - } while (ret == pathsize); - if (ret == -1) { - fprintf(stderr, "Error: couldn't read symlink: %s\n", - strerror(errno)); - return; - } - path[ret] = '\0'; - - prev = path; - for (cur = strchr(path, '/'); cur && *cur; cur = strchr(cur, '/')) { - rrip_SL_add_component(prev, cur, &n_comp, &comp); - cur++; - prev = cur; - } - - /* if there was no trailing '/', we need to add the last component. */ - if (prev == path || prev != &path[ret - 1]) { - rrip_SL_add_component(prev, &path[ret], &n_comp, &comp); - } - - for (i = 0; i < n_comp; i++) { - total_comp_len += comp[i][1] + 2; - if (total_comp_len > 250) { - total_comp_len -= comp[i][1] + 2; - SL = malloc(total_comp_len + 5); - SL[0] = 'S'; - SL[1] = 'L'; - SL[2] = total_comp_len + 5; - SL[3] = 1; - SL[4] = 1; /* CONTINUE */ - pos = 5; - for (j = written; j < i; j++) { - memcpy(&SL[pos], comp[j], comp[j][2]); - pos += comp[j][2]; - } - susp_append(t, &node->susp, SL); - written = i - 1; - total_comp_len = comp[i][1]; - } - } - SL = malloc(total_comp_len + 5); - SL[0] = 'S'; - SL[1] = 'L'; - SL[2] = total_comp_len + 5; - SL[3] = 1; - SL[4] = 0; - pos = 5; - - for (j = written; j < n_comp; j++) { - memcpy(&SL[pos], comp[j], comp[j][1] + 2); - pos += comp[j][1] + 2; - } - susp_append(t, &node->susp, SL); - - free(path); - /* free the components */ - for (i = 0; i < n_comp; i++) { - free(comp[i]); - } - free(comp); -} - -static void rrip_add_NM_single(struct ecma119_write_target *t, - struct susp_info *susp, - char *name, int size, int flags) -{ - uint8_t *NM = malloc(size + 5); - - NM[0] = 'N'; - NM[1] = 'M'; - NM[2] = size + 5; - NM[3] = 1; - NM[4] = flags; - if (size) { - memcpy(&NM[5], name, size); - } - susp_append(t, susp, NM); -} - -void -rrip_add_NM(struct ecma119_write_target *t, struct ecma119_tree_node *node) -{ - char *name = iso_p_fileid(node->iso_self->name); - int len = name ? strlen(name) : 0; - char *pos = name; - - if (!len) - return; - - if (node->type == ECMA119_DIR) { - rrip_add_NM_single(t, &node->dir.self_susp, pos, 0, 1 << 1); - rrip_add_NM_single(t, &node->dir.parent_susp, pos, 0, 1 << 2); - } - - while (len > 250) { - rrip_add_NM_single(t, &node->susp, pos, 250, 1); - len -= 250; - pos += 250; - } - rrip_add_NM_single(t, &node->susp, pos, len, 0); -} - -void rrip_add_CL(struct ecma119_write_target *t, struct ecma119_tree_node *node) -{ - uint8_t *CL = calloc(1, 12); - - CL[0] = 'C'; - CL[1] = 'L'; - CL[2] = 12; - CL[3] = 1; - susp_append(t, &node->susp, CL); -} - -void -rrip_add_PL(struct ecma119_write_target *t, struct ecma119_tree_node *node) -{ - uint8_t *PL = calloc(1, 12); - - PL[0] = 'P'; - PL[1] = 'L'; - PL[2] = 12; - PL[3] = 1; - susp_append(t, &node->dir.parent_susp, PL); -} - -void -rrip_add_RE(struct ecma119_write_target *t, struct ecma119_tree_node *node) -{ - uint8_t *RE = malloc(4); - - RE[0] = 'R'; - RE[1] = 'E'; - RE[2] = 4; - RE[3] = 1; - susp_append(t, &node->susp, RE); -} - -void -rrip_add_TF(struct ecma119_write_target *t, struct ecma119_tree_node *node) -{ - uint8_t *TF = malloc(5 + 3 * 7); - - TF[0] = 'T'; - TF[1] = 'F'; - TF[2] = 5 + 3 * 7; - TF[3] = 1; - TF[4] = (1 << 1) | (1 << 2) | (1 << 3) | (1 << 7); - iso_datetime_7(&TF[5], node->iso_self->attrib.st_mtime); - iso_datetime_7(&TF[12], node->iso_self->attrib.st_atime); - iso_datetime_7(&TF[19], node->iso_self->attrib.st_ctime); - susp_append(t, &node->susp, TF); -} - -void -rrip_finalize(struct ecma119_write_target *t, struct ecma119_tree_node *dir) -{ - int i; - - assert(dir->type == ECMA119_DIR); - - if (dir->parent != dir->dir.real_parent) { - uint8_t *PL = susp_find(&dir->dir.parent_susp, "PL"); - - assert(PL); - iso_bb(&PL[4], dir->dir.real_parent->block, 4); - } - - for (i = 0; i < dir->dir.nchildren; i++) { - struct ecma119_tree_node *ch = dir->dir.children[i]; - - if (ch->type == ECMA119_FILE && ch->file.real_me) { - uint8_t *CL = susp_find(&ch->susp, "CL"); - - assert(CL); - iso_bb(&CL[4], ch->file.real_me->block, 4); - } else if (ch->type == ECMA119_DIR) { - rrip_finalize(t, ch); - } - } -} diff --git a/libisofs/rockridge.h b/libisofs/rockridge.h deleted file mode 100755 index 7909a0c..0000000 --- a/libisofs/rockridge.h +++ /dev/null @@ -1,26 +0,0 @@ -/* vim: set noet ts=8 sts=8 sw=8 : */ - -/** Functions and structures used for Rock Ridge support. */ - -#ifndef ISO_ROCKRIDGE_H -#define ISO_ROCKRIDGE_H - -struct ecma119_write_target; -struct ecma119_tree_node; - -void rrip_add_PX(struct ecma119_write_target *, struct ecma119_tree_node *); -void rrip_add_PN(struct ecma119_write_target *, struct ecma119_tree_node *); -void rrip_add_SL(struct ecma119_write_target *, struct ecma119_tree_node *); -void rrip_add_NM(struct ecma119_write_target *, struct ecma119_tree_node *); -void rrip_add_CL(struct ecma119_write_target *, struct ecma119_tree_node *); -void rrip_add_RE(struct ecma119_write_target *, struct ecma119_tree_node *); -void rrip_add_TF(struct ecma119_write_target *, struct ecma119_tree_node *); - -/* This is special because it doesn't modify the susp fields of the directory - * that gets passed to it; it modifies the susp fields of the ".." entry in - * that directory. */ -void rrip_add_PL(struct ecma119_write_target *, struct ecma119_tree_node *); - -void rrip_finalize(struct ecma119_write_target *, struct ecma119_tree_node *); - -#endif /* ISO_ROCKRIDGE_H */ diff --git a/libisofs/susp.c b/libisofs/susp.c deleted file mode 100755 index 0d2d6c5..0000000 --- a/libisofs/susp.c +++ /dev/null @@ -1,280 +0,0 @@ -/* vim: set noet ts=8 sts=8 sw=8 : */ - -#include "susp.h" -#include "util.h" -#include "ecma119.h" -#include "ecma119_tree.h" - -#include -#include -#include - -void susp_insert(struct ecma119_write_target *t, - struct susp_info *susp, - uint8_t *data, - int pos) -{ - int i; - - if (pos < 0) { - pos = susp->n_susp_fields; - } - - assert(pos <= susp->n_susp_fields); - susp->n_susp_fields++; - susp->susp_fields = realloc(susp->susp_fields, - sizeof(void*) * susp->n_susp_fields); - - for (i = susp->n_susp_fields-1; i > pos; i--) { - susp->susp_fields[i] = susp->susp_fields[i - 1]; - } - susp->susp_fields[pos] = data; -} - -void susp_append(struct ecma119_write_target *t, - struct susp_info *susp, - uint8_t *data) -{ - susp_insert(t, susp, data, susp->n_susp_fields); -} - -uint8_t *susp_find(struct susp_info *susp, const char *name) -{ - int i; - - for (i = 0; i < susp->n_susp_fields; i++) { - if (!strncmp((char *)susp->susp_fields[i], name, 2)) { - return susp->susp_fields[i]; - } - } - return NULL; -} - -/** Utility function for susp_add_CE because susp_add_CE needs to act 3 times - * on directories (for the "." and ".." entries. - * - * \param len The amount of space available for the System Use area. - */ -#define CE_LEN 28 -static unsigned char *susp_add_single_CE(struct ecma119_write_target *t, - struct susp_info *susp, - int len) -{ - int susp_length = 0, tmp_len; - int i; - unsigned char *CE; - - for (i = 0; i < susp->n_susp_fields; i++) { - susp_length += susp->susp_fields[i][2]; - } - if (susp_length <= len) { - /* no need for a CE field */ - susp->non_CE_len = susp_length; - susp->n_fields_fit = susp->n_susp_fields; - return NULL; - } - - tmp_len = susp_length; - for (i = susp->n_susp_fields - 1; i >= 0; i--) { - tmp_len -= susp->susp_fields[i][2]; - if (tmp_len + CE_LEN <= len) { - susp->non_CE_len = tmp_len + CE_LEN; - susp->CE_len = susp_length - tmp_len; - - /* i+1 because we have to count the CE field */ - susp->n_fields_fit = i + 1; - - CE = calloc(1, CE_LEN); - /* we don't fill in the BLOCK LOCATION or OFFSET - fields yet. */ - CE[0] = 'C'; - CE[1] = 'E'; - CE[2] = (char)CE_LEN; - CE[3] = (char)1; - iso_bb(&CE[20], susp_length - tmp_len, 4); - - return CE; - } - } - assert(0); - return NULL; -} - -static void -try_add_CE(struct ecma119_write_target *t, - struct susp_info *susp, - size_t dirent_len) -{ - uint8_t *CE = susp_add_single_CE(t, susp, 255 - dirent_len); - if (CE) - susp_insert(t, susp, CE, susp->n_fields_fit - 1); -} - -/** See IEEE P1281 Draft Version 1.12/5.2. Because this function depends on the - * length of the other SUSP fields, it should always be calculated last. */ -void -susp_add_CE(struct ecma119_write_target *t, struct ecma119_tree_node *node) -{ - try_add_CE(t, &node->susp, node->dirent_len); - if (node->type == ECMA119_DIR) { - try_add_CE(t, &node->dir.self_susp, 34); - try_add_CE(t, &node->dir.parent_susp, 34); - } -} - -/** See IEEE P1281 Draft Version 1.12/5.3 */ -void -susp_add_SP(struct ecma119_write_target *t, struct ecma119_tree_node *dir) -{ - unsigned char *SP = malloc(7); - - assert(dir->type == ECMA119_DIR); - - SP[0] = 'S'; - SP[1] = 'P'; - SP[2] = (char)7; - SP[3] = (char)1; - SP[4] = 0xbe; - SP[5] = 0xef; - SP[6] = 0; - susp_append(t, &dir->dir.self_susp, SP); -} - -#if 0 -/** See IEEE P1281 Draft Version 1.12/5.4 */ -static void susp_add_ST(struct ecma119_write_target *t, - struct iso_tree_node *node) -{ - unsigned char *ST = malloc(4); - - ST[0] = 'S'; - ST[1] = 'T'; - ST[2] = (char)4; - ST[3] = (char)1; - susp_append(t, node, ST); -} -#endif - -/** See IEEE P1281 Draft Version 1.12/5.5 FIXME: this is rockridge */ -void -rrip_add_ER(struct ecma119_write_target *t, struct ecma119_tree_node *dir) -{ - unsigned char *ER = malloc(182); - - assert(dir->type == ECMA119_DIR); - - ER[0] = 'E'; - ER[1] = 'R'; - ER[2] = 182; - ER[3] = 1; - ER[4] = 9; - ER[5] = 72; - ER[6] = 93; - ER[7] = 1; - memcpy(&ER[8], "IEEE_1282", 9); - memcpy(&ER[17], "THE IEEE 1282 PROTOCOL PROVIDES SUPPORT FOR POSIX " - "FILE SYSTEM SEMANTICS.", 72); - memcpy(&ER[89], "PLEASE CONTACT THE IEEE STANDARDS DEPARTMENT, " - "PISCATAWAY, NJ, USA FOR THE 1282 SPECIFICATION.", 93); - susp_append(t, &dir->dir.self_susp, ER); -} - -/* calculate the location of the CE areas. Since CE areas don't need to be - * aligned to a block boundary, we contatenate all CE areas from a single - * directory and dump them immediately after all the directory records. - * - * Requires that the following be known: - * - position of the current directory (dir->block) - * - length of the current directory (dir->dir.len) - * - sum of the children's CE lengths (dir->dir.CE_len) - */ -static void -susp_fin_1_CE(struct ecma119_write_target *t, - struct susp_info *susp, - size_t block, - size_t *offset) -{ - uint8_t *CE = susp->susp_fields[susp->n_fields_fit - 1]; - - if (!susp->CE_len) { - return; - } - iso_bb(&CE[4], block + (*offset) / t->block_size, 4); - iso_bb(&CE[12], (*offset) % t->block_size, 4); - *offset += susp->CE_len; -} - -static void susp_fin_CE(struct ecma119_write_target *t, - struct ecma119_tree_node *dir) -{ - int i; - size_t CE_offset = dir->dir.len; - - assert(dir->type == ECMA119_DIR); - - susp_fin_1_CE(t, &dir->dir.self_susp, dir->block, &CE_offset); - susp_fin_1_CE(t, &dir->dir.parent_susp, dir->block, &CE_offset); - - for (i = 0; i < dir->dir.nchildren; i++) { - struct ecma119_tree_node *ch = dir->dir.children[i]; - susp_fin_1_CE(t, &ch->susp, dir->block, &CE_offset); - } - assert(CE_offset == dir->dir.len + dir->dir.CE_len); -} - -void -susp_finalize(struct ecma119_write_target *t, struct ecma119_tree_node *dir) -{ - int i; - - assert(dir->type = ECMA119_DIR); - - if (dir->dir.depth != 1) { - susp_fin_CE(t, dir); - } - - for (i = 0; i < dir->dir.nchildren; i++) { - if (dir->dir.children[i]->type == ECMA119_DIR) - susp_finalize(t, dir->dir.children[i]); - } -} - -void susp_write(struct ecma119_write_target *t, - struct susp_info *susp, - unsigned char *buf) -{ - int i; - int pos = 0; - - for (i = 0; i < susp->n_fields_fit; i++) { - memcpy(&buf[pos], susp->susp_fields[i], - susp->susp_fields[i][2]); - pos += susp->susp_fields[i][2]; - } -} - -void susp_write_CE(struct ecma119_write_target *t, struct susp_info *susp, - unsigned char *buf) -{ - int i; - int pos = 0; - - for (i = susp->n_fields_fit; i < susp->n_susp_fields; i++) { - memcpy(&buf[pos], susp->susp_fields[i], - susp->susp_fields[i][2]); - pos += susp->susp_fields[i][2]; - } -} - -void susp_free_fields(struct susp_info *susp) -{ - int i; - - for (i=0; in_susp_fields; i++) { - free(susp->susp_fields[i]); - } - if (susp->susp_fields) { - free(susp->susp_fields); - } - memset(susp, 0, sizeof(struct susp_info)); -} diff --git a/libisofs/susp.h b/libisofs/susp.h deleted file mode 100755 index 31dd2cf..0000000 --- a/libisofs/susp.h +++ /dev/null @@ -1,62 +0,0 @@ -/* vim: set noet ts=8 sts=8 sw=8 : */ - -/** Functions and structures used for SUSP (IEEE 1281). - */ - -#ifndef __ISO_SUSP -#define __ISO_SUSP - -#include - -/* SUSP is only present in standard ecma119 */ -struct ecma119_write_target; -struct ecma119_tree_node; - -/** This contains the information that needs to go in the SUSP area of a file. - */ -struct susp_info -{ - int n_susp_fields; /**< Number of SUSP fields */ - uint8_t **susp_fields; /**< Data for each SUSP field */ - - /* the next 3 relate to CE and are filled out by susp_add_CE. */ - int n_fields_fit; /**< How many of the above SUSP fields fit - * within this node's dirent. */ - int non_CE_len; /**< Length of the part of the SUSP area that - * fits in the dirent. */ - int CE_len; /**< Length of the part of the SUSP area that - * will go in a CE area. */ -}; - -void susp_add_CE(struct ecma119_write_target *, struct ecma119_tree_node *); - -/* these next 2 are special because they don't modify the susp fields of the - * directory; they modify the susp fields of the - * "." entry in the directory. */ -void susp_add_SP(struct ecma119_write_target *, struct ecma119_tree_node *); -void rrip_add_ER(struct ecma119_write_target *, struct ecma119_tree_node *); - -/** Once all the directories and files are laid out, recurse through the tree - * and finalize all SUSP CE entries. */ -void susp_finalize(struct ecma119_write_target *, struct ecma119_tree_node *); - -void susp_append(struct ecma119_write_target *, - struct susp_info *, - uint8_t *); -void susp_insert(struct ecma119_write_target *, - struct susp_info *, - uint8_t *, - int pos); -uint8_t *susp_find(struct susp_info *, - const char *); - -void susp_write(struct ecma119_write_target *, - struct susp_info *, - uint8_t *); -void susp_write_CE(struct ecma119_write_target *, - struct susp_info *, - uint8_t *); - -void susp_free_fields(struct susp_info *); - -#endif /* __ISO_SUSP */ diff --git a/libisofs/tree.c b/libisofs/tree.c deleted file mode 100755 index 57aa0df..0000000 --- a/libisofs/tree.c +++ /dev/null @@ -1,223 +0,0 @@ -/* vim: set noet ts=8 sts=8 sw=8 : */ - -/** - * \file tree.c - * - * Implement filesystem trees. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tree.h" -#include "util.h" -#include "volume.h" -#include "exclude.h" - -static void -set_default_stat(struct stat *s) -{ - time_t now = time(NULL); - - memset(s, 0, sizeof(struct stat)); - s->st_mode = 0777 | S_IFREG; - s->st_atime = s->st_mtime = s->st_ctime = now; -} - -static struct stat -get_attrib(const struct iso_tree_node *node) -{ - struct stat st; - - if (node) { - return node->attrib; - } - set_default_stat(&st); - return st; -} - -static void -append_node(struct iso_tree_node *parent, - struct iso_tree_node *child) -{ - assert((!parent || S_ISDIR(parent->attrib.st_mode)) && child); - if (!parent) - return; - - parent->nchildren++; - parent->children = - realloc(parent->children, parent->nchildren * sizeof(void*)); - parent->children[parent->nchildren-1] = child; -} - -struct iso_tree_node* -iso_tree_new_root(struct iso_volume *vol) -{ - assert(vol); - - if (vol->root) { - iso_tree_free(vol->root); - } - - vol->root = calloc(1, sizeof(struct iso_tree_node)); - vol->root->volume = vol; - set_default_stat(&vol->root->attrib); - vol->root->attrib.st_mode = S_IFDIR | 0777; - vol->root->loc.type = LIBISO_NONE; - return vol->root; -} - -struct iso_tree_node* -iso_tree_add_new_file(struct iso_tree_node *parent, const char *name) -{ - struct iso_tree_node *f = calloc(1, sizeof(struct iso_tree_node)); - - assert((!parent || S_ISDIR(parent->attrib.st_mode)) && name); - - f->volume = parent ? parent->volume : NULL; - f->parent = parent; - f->name = parent ? strdup(name) : NULL; - f->attrib = get_attrib(parent); - f->attrib.st_mode = 0777 | S_IFREG; - f->loc.type = LIBISO_NONE; - append_node(parent, f); - return f; -} - -struct iso_tree_node* -iso_tree_add_new_dir(struct iso_tree_node *parent, const char *name) -{ - struct iso_tree_node *d = iso_tree_add_new_file(parent, name); - - assert((!parent || S_ISDIR(parent->attrib.st_mode)) && name); - - d->attrib.st_mode = (d->attrib.st_mode & ~S_IFMT) | S_IFDIR; - return d; -} - -struct iso_tree_node* -iso_tree_add_node(struct iso_tree_node *parent, const char *path) -{ - char *p; - struct stat st; - struct iso_tree_node *ret; - - assert((!parent || S_ISDIR(parent->attrib.st_mode)) && path); - - if (lstat(path, &st) == -1) - return NULL; - - p = strdup(path); /* because basename() might modify its arg */ - - /* it doesn't matter if we add a file or directory since we modify - * attrib anyway. */ - ret = iso_tree_add_new_file(parent, basename(p)); - ret->attrib = st; - ret->loc.type = LIBISO_FILESYS; - ret->loc.path = strdup(path); - free(p); - - return ret; -} - -struct iso_tree_node* -iso_tree_radd_dir (struct iso_tree_node *parent, const char *path) -{ - struct iso_tree_node *new; - DIR *dir; - struct dirent *ent; - - assert((!parent || S_ISDIR(parent->attrib.st_mode)) && path); - - new = iso_tree_add_node(parent, path); - if (!new || !S_ISDIR(new->attrib.st_mode)) { - return new; - } - - dir = opendir(path); - if (!dir) { - warn("couldn't open directory %s: %s\n", path, strerror(errno)); - return new; - } - - while ((ent = readdir(dir))) { - char child[strlen(ent->d_name) + strlen(path) + 2]; - - if (strcmp(ent->d_name, ".") == 0 || - strcmp(ent->d_name, "..") == 0) - continue; - - sprintf(child, "%s/%s", path, ent->d_name); - - /* see if this child is excluded. */ - if (iso_exclude_lookup(child)) - continue; - - iso_tree_radd_dir(new, child); - } - closedir(dir); - - return new; -} - -void -iso_tree_free(struct iso_tree_node *root) -{ - size_t i; - - for (i=0; i < root->nchildren; i++) { - iso_tree_free(root->children[i]); - } - free(root->name); - free(root->children); - free(root); -} - -void -iso_tree_print(const struct iso_tree_node *root, int spaces) -{ - size_t i; - char sp[spaces+1]; - - memset(sp, ' ', spaces); - sp[spaces] = '\0'; - - printf("%s%sn", sp, root->name); - for (i=0; i < root->nchildren; i++) { - iso_tree_print(root->children[i], spaces+2); - } -} - -void -iso_tree_print_verbose(const struct iso_tree_node *root, - print_dir_callback dir, - print_file_callback file, - void *callback_data, - int spaces) -{ - size_t i; - - (S_ISDIR(root->attrib.st_mode) ? dir : file) - (root, callback_data, spaces); - for (i=0; i < root->nchildren; i++) { - iso_tree_print_verbose(root->children[i], dir, - file, callback_data, spaces+2); - } -} - -void -iso_tree_node_set_name(struct iso_tree_node *file, const char *name) -{ - free(file->name); - file->name = strdup(name); -} diff --git a/libisofs/tree.h b/libisofs/tree.h deleted file mode 100755 index e0e0460..0000000 --- a/libisofs/tree.h +++ /dev/null @@ -1,159 +0,0 @@ -/* vim: set noet ts=8 sts=8 sw=8 : */ - -/** - * \file tree.h - * - * Declare the structure of a libisofs filesystem tree. The files in this - * tree can come from either the local filesystem or from another .iso image - * (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 - * *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. - */ - -#ifndef LIBISO_TREE_H -#define LIBISO_TREE_H - -#include -#include -#include -#include - -#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; - /* };*/ -}; - -/** - * A node in the filesystem tree. - */ -struct iso_tree_node -{ - struct iso_volume *volume; - struct iso_tree_node *parent; - char *name; - struct stat attrib; /**< The POSIX attributes of this node as - * documented in "man 2 stat". */ - struct iso_file_location loc; - /**< Only used for regular files and symbolic - * links (ie. files for which we might have to - * copy data). */ - - size_t nchildren; /**< The number of children of this - * directory (if this is a directory). */ - struct iso_tree_node **children; - - size_t block; /**< The block at which this file will - * reside on disk. We store this here as - * well as in the various mangled trees - * because many different trees might point - * to the same file and they need to share the - * block location. */ -}; - -/** - * Create a new root directory for a volume. - * - * \param vol The volume for which to create a new root directory. - * - * \pre \p vol is non-NULL. - * \post \p vol has a non-NULL, empty root directory with permissions 777. - * \return \p vol's new non-NULL, empty root directory. - */ -struct iso_tree_node *iso_tree_new_root(struct iso_volume *vol); - -/** - * Create a new, empty, file. - * - * \param parent The parent directory of the new file. If this is null, create - * and return a new file node without adding it to any tree. - * \param name The name of the new file, encoded in the current locale. - * \pre \p name is non-NULL and it does not match any other file or directory - * name in \p parent. - * \post \p parent (if non-NULL) contains a file with the following properties: - * - the file's name is \p name (converted to wchar_t) - * - the file's POSIX permissions are the same as \p parent's - * - the file is a regular file - * - the file is empty - * - * \return \p parent's newly created file. - */ -struct iso_tree_node *iso_tree_add_new_file(struct iso_tree_node *parent, - const char *name); - -/** - * 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); - -/** - * A function that prints verbose information about a directory. - * - * \param dir The directory about which to print information. - * \param data Unspecified function-dependent data. - * \param spaces The number of spaces to prepend to the output. - * - * \see iso_tree_print_verbose - */ -typedef void (*print_dir_callback) (const struct iso_tree_node *dir, - void *data, - int spaces); -/** - * A function that prints verbose information about a file. - * - * \param dir The file about which to print information. - * \param data Unspecified function-dependent data. - * \param spaces The number of spaces to prepend to the output. - * - * \see iso_tree_print_verbose - */ -typedef void (*print_file_callback) (const struct iso_tree_node *file, - void *data, - int spaces); - -/** - * Recursively print a directory heirarchy. For each node in the directory - * heirarchy, call a callback function to print information more verbosely. - * - * \param root The root of the directory heirarchy to print. - * \param dir The callback function to call for each directory in the tree. - * \param file The callback function to call for each file in the tree. - * \param callback_data The data to pass to the callback functions. - * \param spaces The number of spaces to prepend to the output. - * - * \pre \p root is not NULL. - * \pre Neither of the callback functions modifies the directory heirarchy. - */ -void iso_tree_print_verbose(const struct iso_tree_node *root, - print_dir_callback dir, - print_file_callback file, - void *callback_data, - int spaces); - -#define ISO_ISDIR(n) S_ISDIR(n->attrib.st_mode) - -#endif /* LIBISO_TREE_H */ diff --git a/libisofs/util.c b/libisofs/util.c deleted file mode 100755 index 2187b6f..0000000 --- a/libisofs/util.c +++ /dev/null @@ -1,584 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ -/* vim: set noet ts=8 sts=8 sw=8 : */ - -/** - * Utility functions for the Libisofs library. - */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "util.h" - -/* avoids warning and names in iso, joliet and rockridge can't be > 255 bytes - * anyway. There are at most 31 characters in iso level 1, 255 for rockridge, - * 64 characters (* 2 since UCS) for joliet. */ -#define NAME_BUFFER_SIZE 255 - -int div_up(int n, int div) -{ - return (n + div - 1) / div; -} - -int round_up(int n, int mul) -{ - return div_up(n, mul) * mul; -} - -/* this function must always return a name - * since the caller never checks if a NULL - * is returned. It also avoids some warnings. */ -char *str2ascii(const char *src_arg) -{ - wchar_t wsrc_[NAME_BUFFER_SIZE]; - char *src = (char*)wsrc_; - char *ret_; - char *ret; - mbstate_t state; - iconv_t conv; - size_t numchars; - size_t outbytes; - size_t inbytes; - size_t n; - - if (!src_arg) - return NULL; - - /* convert the string to a wide character string. Note: outbytes - * is in fact the number of characters in the string and doesn't - * include the last NULL character. */ - memset(&state, 0, sizeof(state)); - numchars = mbsrtowcs(wsrc_, &src_arg, NAME_BUFFER_SIZE-1, &state); - if (numchars < 0) - return NULL; - - inbytes = numchars * sizeof(wchar_t); - - ret_ = malloc(numchars+1); - outbytes = numchars; - ret = ret_; - - /* initialize iconv */ - conv = iconv_open("ASCII", "WCHAR_T"); - if (conv == (iconv_t)-1) - return NULL; - - n = iconv(conv, &src, &inbytes, &ret, &outbytes); - while(n == -1) { - /* The destination buffer is too small. Stops here. */ - if(errno == E2BIG) - break; - - /* An incomplete multi bytes sequence was found. We - * can't do anything here. That's quite unlikely. */ - if(errno == EINVAL) - break; - - /* The last possible error is an invalid multi bytes - * sequence. Just replace the character with a "_". - * Probably the character doesn't exist in ascii like - * "é, è, à, ç, ..." in French. */ - *ret++ = '_'; - outbytes--; - - if(!outbytes) - break; - - /* There was an error with one character but some other remain - * to be converted. That's probably a multibyte character. - * See above comment. */ - src += sizeof(wchar_t); - inbytes -= sizeof(wchar_t); - - if(!inbytes) - break; - - n = iconv(conv, &src, &inbytes, &ret, &outbytes); - } - - iconv_close(conv); - - *ret='\0'; - return ret_; -} - -/* FIXME: C&P */ -uint16_t *str2ucs(const char *src_arg) -{ - wchar_t wsrc_[NAME_BUFFER_SIZE]; - char *src = (char*)wsrc_; - char *ret_; - char *ret; - mbstate_t state; - iconv_t conv; - size_t outbytes; - size_t numchars; - size_t inbytes; - size_t n; - - if (!src_arg) - return calloc(2, 1); /* empty UCS string */ - - /* convert the string to a wide character string. Note: outbytes - * is in fact the number of characters in the string and doesn't - * include the last NULL character. */ - memset(&state, 0, sizeof(state)); - numchars = mbsrtowcs(wsrc_, &src_arg, NAME_BUFFER_SIZE-1, &state); - if (numchars < 0) - return calloc(2, 1); /* empty UCS string */ - - inbytes = numchars * sizeof(wchar_t); - - outbytes = numchars * sizeof(uint16_t); - ret_ = malloc ((numchars+1) * sizeof(uint16_t)); - ret = ret_; - - /* initialize iconv */ - conv = iconv_open("UCS-2BE", "WCHAR_T"); - if (conv == (iconv_t)-1) - return calloc(2, 1); /* empty UCS string */ - - n = iconv(conv, &src, &inbytes, &ret, &outbytes); - while(n == -1) { - /* The destination buffer is too small. Stops here. */ - if(errno == E2BIG) - break; - - /* An incomplete multi bytes sequence was found. We - * can't do anything here. That's quite unlikely. */ - if(errno == EINVAL) - break; - - /* The last possible error is an invalid multi bytes - * sequence. Just replace the character with a "_". - * Probably the character doesn't exist in ascii like - * "é, è, à, ç, ..." in French. */ - *((uint16_t*) ret) = '_'; - ret += sizeof(uint16_t); - outbytes -= sizeof(uint16_t); - - if(!outbytes) - break; - - /* There was an error with one character but some other remain - * to be converted. That's probably a multibyte character. - * See above comment. */ - src += sizeof(wchar_t); - inbytes -= sizeof(wchar_t); - - if(!inbytes) - break; - - n = iconv(conv, &src, &inbytes, &ret, &outbytes); - } - - iconv_close(conv); - - /* close the ucs string */ - *((uint16_t*) ret) = 0; - - return (uint16_t*)ret_; -} - - -static int valid_d_char(char c) -{ - return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == '_'); -} - -static int valid_a_char(char c) -{ - return (c >= ' ' && c <= '"') || (c >= '%' && c <= '?') - || (c >= 'A' && c <= 'Z') - || (c == '_'); -} - -static int valid_j_char(uint16_t c) -{ - return !(c < (uint16_t)' ' || c == (uint16_t)'*' || c == (uint16_t)'/' - || c == (uint16_t)':' || c == (uint16_t)';' - || c == (uint16_t)'?' || c == (uint16_t)'\\'); -} - -/* FIXME: where are these documented? */ -static int valid_p_char(char c) -{ - return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') - || (c >= 'a' && c <= 'z') - || (c == '.') || (c == '_') || (c == '-'); -} - -static char *iso_dirid(const char *src, int size) -{ - char *ret = str2ascii(src); - size_t len, i; - - if (!ret) - return NULL; - - len = strlen(ret); - if (len > size) { - ret[size] = '\0'; - len = size; - } - for (i = 0; i < len; i++) { - char c = toupper(ret[i]); - ret[i] = valid_d_char(c) ? c : '_'; - } - - return ret; -} - -char *iso_1_dirid(const char *src) -{ - return iso_dirid(src, 8); -} - -char *iso_2_dirid(const char *src) -{ - return iso_dirid(src, 31); -} - -char *iso_1_fileid(const char *src_arg) -{ - char *src = str2ascii(src_arg); - char *dest; - char *dot; /* Position of the last dot in the - filename, will be used to calculate - lname and lext. */ - int lname, lext, pos, i; - - if (!src) - return NULL; - - dest = malloc(15); /* 15 = 8 (name) + 1 (.) + 3 (ext) + 2 - (;1) + 1 (\0) */ - dot = strrchr(src, '.'); - - lext = dot ? strlen(dot + 1) : 0; - lname = strlen(src) - lext - (dot ? 1 : 0); - - /* If we can't build a filename, return NULL. */ - if (lname == 0 && lext == 0) { - free(src); - free(dest); - return NULL; - } - - pos = 0; - /* Convert up to 8 characters of the filename. */ - for (i = 0; i < lname && i < 8; i++) { - char c = toupper(src[i]); - - dest[pos++] = valid_d_char(c) ? c : '_'; - } - /* This dot is mandatory, even if there is no extension. */ - dest[pos++] = '.'; - /* Convert up to 3 characters of the extension, if any. */ - for (i = 0; i < lext && i < 3; i++) { - char c = toupper(src[lname + 1 + i]); - - dest[pos++] = valid_d_char(c) ? c : '_'; - } - /* File versions are mandatory, even if they aren't used. */ - dest[pos++] = ';'; - dest[pos++] = '1'; - dest[pos] = '\0'; - dest = (char *)realloc(dest, pos + 1); - - free(src); - return dest; -} - -char *iso_2_fileid(const char *src_arg) -{ - char *src = str2ascii(src_arg); - char *dest; - char *dot; - int lname, lext, lnname, lnext, pos, i; - - if (!src) - return NULL; - - dest = malloc(34); /* 34 = 30 (name + ext) + 1 (.) + 2 - (;1) + 1 (\0) */ - dot = strrchr(src, '.'); - - /* 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 - the extension, but keep a minimum extension length of 3. */ - if (dot == NULL || dot == src || *(dot + 1) == '\0') { - lname = strlen(src); - lnname = (lname > 30) ? 30 : lname; - lext = lnext = 0; - } else { - lext = strlen(dot + 1); - lname = strlen(src) - lext - 1; - lnext = (strlen(src) > 31 && lext > 3) - ? (lname < 27 ? 30 - lname : 3) : lext; - lnname = (strlen(src) > 31) ? 30 - lnext : lname; - } - - if (lnname == 0 && lnext == 0) { - free(src); - free(dest); - return NULL; - } - - pos = 0; - /* Convert up to lnname characters of the filename. */ - for (i = 0; i < lnname; i++) { - char c = toupper(src[i]); - - dest[pos++] = valid_d_char(c) ? c : '_'; - } - dest[pos++] = '.'; - /* Convert up to lnext characters of the extension, if any. */ - for (i = 0; i < lnext; i++) { - char c = toupper(src[lname + 1 + i]); - - dest[pos++] = valid_d_char(c) ? c : '_'; - } - dest[pos++] = ';'; - dest[pos++] = '1'; - dest[pos] = '\0'; - dest = (char *)realloc(dest, pos + 1); - - free(src); - return dest; -} - -char * -iso_p_fileid(const char *src) -{ - char *ret = str2ascii(src); - size_t i, len; - - if (!ret) - return NULL; - len = strlen(ret); - for (i = 0; i < len; i++) { - if (!valid_p_char(ret[i])) { - ret[i] = (uint16_t)'_'; - } - } - return ret; -} - -uint16_t * -iso_j_id(const char *src_arg) -{ - uint16_t *j_str = str2ucs(src_arg); - size_t len = ucslen(j_str); - size_t n; - - if (len > 128) { - j_str[128] = '\0'; - len = 128; - } - - for (n = 0; n < len; n++) - if (!valid_j_char(j_str[n])) - j_str[n] = '_'; - return j_str; -} - -void iso_lsb(uint8_t *buf, uint32_t num, int bytes) -{ - int i; - - assert(bytes <= 4); - - for (i = 0; i < bytes; ++i) - buf[i] = (num >> (8 * i)) & 0xff; -} - -void iso_msb(uint8_t *buf, uint32_t num, int bytes) -{ - int i; - - assert(bytes <= 4); - - for (i = 0; i < bytes; ++i) - buf[bytes - 1 - i] = (num >> (8 * i)) & 0xff; -} - -void iso_bb(uint8_t *buf, uint32_t num, int bytes) -{ - iso_lsb(buf, num, bytes); - iso_msb(buf+bytes, num, bytes); -} - - -void iso_datetime_7(unsigned char *buf, time_t t) -{ - static int tzsetup = 0; - int tzoffset; - struct tm tm; - - if (!tzsetup) { - tzset(); - tzsetup = 1; - } - - localtime_r(&t, &tm); - - buf[0] = tm.tm_year; - buf[1] = tm.tm_mon + 1; - buf[2] = tm.tm_mday; - buf[3] = tm.tm_hour; - buf[4] = tm.tm_min; - buf[5] = tm.tm_sec; -#ifdef HAVE_TM_GMTOFF - tzoffset = -tm.tm_gmtoff / 60 / 15; -#else - tzoffset = -timezone / 60 / 15; -#endif - if (tzoffset < -48) - tzoffset += 101; - buf[6] = tzoffset; -} - -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_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; -} - -void iso_datetime_17(unsigned char *buf, time_t t) -{ - static int tzsetup = 0; - static int tzoffset; - struct tm tm; - - if (t == (time_t) - 1) { - /* unspecified time */ - memset(buf, '0', 16); - buf[16] = 0; - } else { - if (!tzsetup) { - tzset(); - tzsetup = 1; - } - - localtime_r(&t, &tm); - - sprintf((char*)&buf[0], "%04d", tm.tm_year + 1900); - sprintf((char*)&buf[4], "%02d", tm.tm_mon + 1); - sprintf((char*)&buf[6], "%02d", tm.tm_mday); - sprintf((char*)&buf[8], "%02d", tm.tm_hour); - sprintf((char*)&buf[10], "%02d", tm.tm_min); - sprintf((char*)&buf[12], "%02d", MIN(59, tm.tm_sec)); - memcpy(&buf[14], "00", 2); -#ifdef HAVE_TM_GMTOFF - tzoffset = -tm.tm_gmtoff / 60 / 15; -#else - tzoffset = -timezone / 60 / 15; -#endif - if (tzoffset < -48) - tzoffset += 101; - buf[16] = tzoffset; - } -} - -time_t iso_datetime_read_17(const uint8_t *buf) -{ - struct tm tm; - - sscanf((char*)&buf[0], "%4d", &tm.tm_year); - sscanf((char*)&buf[4], "%2d", &tm.tm_mon); - sscanf((char*)&buf[6], "%2d", &tm.tm_mday); - sscanf((char*)&buf[8], "%2d", &tm.tm_hour); - sscanf((char*)&buf[10], "%2d", &tm.tm_min); - sscanf((char*)&buf[12], "%2d", &tm.tm_sec); - tm.tm_year -= 1900; - tm.tm_mon -= 1; - - return mktime(&tm) - buf[16] * 60 * 60; -} - -size_t ucslen(const uint16_t *str) -{ - int i; - - for (i=0; str[i]; i++) - ; - return i; -} - -/** - * Although each character is 2 bytes, we actually compare byte-by-byte - * (thats what the spec says). - */ -int ucscmp(const uint16_t *s1, const uint16_t *s2) -{ - const char *s = (const char*)s1; - const char *t = (const char*)s2; - size_t len1 = ucslen(s1); - size_t len2 = ucslen(s2); - size_t i, len = MIN(len1, len2) * 2; - - for (i=0; i < len; i++) { - if (s[i] < t[i]) { - return -1; - } else if (s[i] > t[i]) { - return 1; - } - } - - if (len1 < len2) - return -1; - else if (len1 > len2) - return 1; - return 0; -} - -uint32_t iso_read_lsb(const uint8_t *buf, int bytes) -{ - int i; - uint32_t ret = 0; - - for (i=0; i -#include -#include - -#ifndef MAX -# define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif - -#ifndef MIN -# define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -extern inline int div_up(int n, int div) -{ - return (n + div - 1) / div; -} - -extern inline int round_up(int n, int mul) -{ - return div_up(n, mul) * mul; -} - -wchar_t *towcs(const char *); -char *str2ascii(const char*); -uint16_t *str2ucs(const char*); - -/** - * Create a level 1 directory identifier. - */ -char *iso_1_dirid(const char *src); - -/** - * Create a level 2 directory identifier. - */ -char *iso_2_dirid(const char *src); - -/** - * Create a level 1 file identifier that consists of a name, extension and - * version number. The resulting string will have a file name of maximum - * length 8, followed by a separator (.), an optional extension of maximum - * length 3, followed by a separator (;) and a version number (digit 1). - * @return NULL if the original name and extension both are of length 0. - */ -char *iso_1_fileid(const char *src); - -/** - * Create a level 2 file identifier that consists of a name, extension and - * version number. The combined file name and extension length will not exceed - * 30, the name and extension will be separated (.), and the extension will be - * followed by a separator (;) and a version number (digit 1). - * @return NULL if the original name and extension both are of length 0. - */ -char *iso_2_fileid(const char *src); - -/** - * Create a Joliet file or directory identifier that consists of a name, - * extension and version number. The combined name and extension length will - * not exceed 128 bytes, the name and extension will be separated (.), - * and the extension will be followed by a separator (;) and a version number - * (digit 1). All characters consist of 2 bytes and the resulting string is - * NULL-terminated by a 2-byte NULL. Requires the locale to be set correctly. - * - * @param size will be set to the size (in bytes) of the identifier. - * @return NULL if the original name and extension both are of length 0 or the conversion from the current codeset to UCS-2BE is not available. - */ -uint16_t *iso_j_id(const char *src); - -/** - * FIXME: what are the requirements for these next two? Is this for RR? - * - * Create a POSIX portable file name that consists of a name and extension. - * The resulting file name will not exceed 250 characters. - * @return NULL if the original name and extension both are of length 0. - */ -char *iso_p_fileid(const char *src); - -/** - * Create a POSIX portable directory name. - * The resulting directory name will not exceed 250 characters. - * @return NULL if the original name is of length 0. - */ -char *iso_p_dirid(const char *src); - -void iso_lsb(uint8_t *buf, uint32_t num, int bytes); -void iso_msb(uint8_t *buf, uint32_t num, int bytes); -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); - -/** Records the date/time into a 7 byte buffer (9.1.5) */ -void iso_datetime_7(uint8_t *buf, time_t t); - -/** Records the date/time into a 17 byte buffer (8.4.26.1) */ -void iso_datetime_17(uint8_t *buf, time_t t); - -time_t iso_datetime_read_7(const uint8_t *buf); -time_t iso_datetime_read_17(const uint8_t *buf); - -/** - * Like strlen, but for Joliet strings. - */ -size_t ucslen(const uint16_t *str); - -/** - * Like strcmp, but for Joliet strings. - */ -int ucscmp(const uint16_t *s1, const uint16_t *s2); - -#endif /* LIBISO_UTIL_H */ diff --git a/libisofs/volume.c b/libisofs/volume.c deleted file mode 100755 index 65cbbbf..0000000 --- a/libisofs/volume.c +++ /dev/null @@ -1,189 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ -/* vim: set ts=8 sts=8 sw=8 noet : */ - -#include -#include -#include - -#include "libisofs.h" -#include "tree.h" -#include "util.h" -#include "volume.h" - -struct iso_volset* -iso_volset_new(struct iso_volume *vol, const char *id) -{ - struct iso_volset *volset = calloc(1, sizeof(struct iso_volset)); - - volset->volset_size = 1; - volset->refcount = 1; - volset->volume = malloc(sizeof(void *)); - volset->volume[0] = vol; - volset->volset_id = strdup(id); - - vol->refcount++; - return volset; -} - -void -iso_volset_free(struct iso_volset *volset) -{ - if (--volset->refcount < 1) { - int i; - for (i = 0; i < volset->volset_size; i++) { - iso_volume_free(volset->volume[i]); - } - free(volset->volume); - free(volset->volset_id); - } -} - -struct iso_volume* -iso_volume_new(const char *volume_id, - const char *publisher_id, - const char *data_preparer_id) -{ - return iso_volume_new_with_root(volume_id, - publisher_id, - data_preparer_id, - NULL); -} - -struct iso_volume* -iso_volume_new_with_root(const char *volume_id, - const char *publisher_id, - const char *data_preparer_id, - struct iso_tree_node *root) -{ - struct iso_volume *volume; - - volume = calloc(1, sizeof(struct iso_volume)); - volume->refcount = 1; - - volume->root = root ? root : iso_tree_new_root(volume); - - if (volume_id != NULL) - volume->volume_id = strdup(volume_id); - if (publisher_id != NULL) - volume->publisher_id = strdup(publisher_id); - if (data_preparer_id != NULL) - volume->data_preparer_id = strdup(data_preparer_id); - return volume; -} - -void -iso_volume_free(struct iso_volume *volume) -{ - /* Only free if no references are in use. */ - if (--volume->refcount < 1) { - iso_tree_free(volume->root); - - free(volume->volume_id); - free(volume->publisher_id); - free(volume->data_preparer_id); - - free(volume); - } -} - -struct iso_tree_node * -iso_volume_get_root(const struct iso_volume *volume) -{ - return volume->root; -} - -struct iso_tree_node * -iso_tree_volume_path_to_node(struct iso_volume *volume, const char *path) -{ - struct iso_tree_node *node; - char *ptr, *brk_info, *component; - - /* get the first child at the root of the volume - * that is "/" */ - node=iso_volume_get_root(volume); - if (!strcmp (path, "/")) - return node; - - if (!node->nchildren) - return NULL; - - /* the name of the nodes is in wide characters so first convert path - * into wide characters. */ - ptr = strdup(path); - - /* get the first component of the path */ - component=strtok_r(ptr, "/", &brk_info); - while (component) { - size_t max; - size_t i; - - /* search among all the children of this directory if this path component exists */ - max=node->nchildren; - for (i=0; i < max; i++) { - if (!strcmp(component, node->children[i]->name)) { - node=node->children[i]; - break; - } - } - - /* see if a node could be found */ - if (i==max) { - node=NULL; - break; - } - - component=strtok_r(NULL, "/", &brk_info); - } - - free(ptr); - return node; -} - -struct iso_tree_node * -iso_tree_volume_add_path(struct iso_volume *volume, - const char *disc_path, - const char *path) -{ - char *tmp; - struct iso_tree_node *node; - struct iso_tree_node *parent_node; - - tmp=strdup(disc_path); - parent_node = iso_tree_volume_path_to_node(volume, dirname(tmp)); - free(tmp); - - if (!parent_node) - return NULL; - - node = iso_tree_radd_dir(parent_node, path); - if (!node) - return NULL; - - tmp=strdup(disc_path); - iso_tree_node_set_name(node, basename(tmp)); - free(tmp); - - return node; -} - -struct iso_tree_node * -iso_tree_volume_add_new_dir(struct iso_volume *volume, - const char *disc_path) -{ - char *tmp; - struct iso_tree_node *node; - struct iso_tree_node *parent_node; - - tmp=strdup(disc_path); - parent_node = iso_tree_volume_path_to_node(volume, dirname(tmp)); - free(tmp); - - if (!parent_node) - return NULL; - - tmp=strdup(disc_path); - node = iso_tree_add_new_dir(parent_node, basename(tmp)); - free(tmp); - - return node; -} diff --git a/libisofs/volume.h b/libisofs/volume.h deleted file mode 100755 index 8903186..0000000 --- a/libisofs/volume.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ -/* vim: set noet sts=8 ts=8 sw=8 : */ - -/** - * Extra declarations for use with the iso_volume structure. - */ - -#ifndef LIBISO_VOLUME_H -#define LIBISO_VOLUME_H - -#include "libisofs.h" - -/** - * Data volume. - */ -struct iso_volume -{ - int refcount; /**< Number of used references to this - volume. */ - - struct iso_tree_node *root; /**< Root of the directory tree for the - volume. */ - - char *volume_id; /**< Volume identifier. */ - char *publisher_id; /**< Volume publisher. */ - char *data_preparer_id; /**< Volume data preparer. */ -}; - -/** - * A set of data volumes. - */ -struct iso_volset -{ - int refcount; - - struct iso_volume **volume; /**< The volumes belonging to this - volume set. */ - int volset_size; /**< The number of volumes in this - volume set. */ - - char *volset_id; /**< The id of this volume set, encoded - in the current locale. */ -}; - -#endif /* __ISO_VOLUME */ diff --git a/test/iso.c b/test/iso.c deleted file mode 100644 index d20c631..0000000 --- a/test/iso.c +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ -/* vim: set ts=8 sts=8 sw=8 noet : */ - -#define _GNU_SOURCE - -#include "libisofs.h" -#include "libburn/libburn.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SECSIZE 2048 - -const char * const optstring = "JRL:h"; -extern char *optarg; -extern int optind; - -void usage() -{ - printf("test [OPTIONS] DIRECTORY OUTPUT\n"); -} - -void help() -{ - printf( -"Options:\n" -" -J Add Joliet support\n" -" -R Add Rock Ridge support\n" -" -L Set the ISO level (1 or 2)\n" -" -h Print this message\n" -); -} - -int main(int argc, char **argv) -{ - struct iso_volset *volset; - struct iso_volume *volume; - struct iso_tree_node *root; - struct burn_source *src; - unsigned char buf[2048]; - FILE *fd; - int c; - int level=1, flags=0; - - while ((c = getopt(argc, argv, optstring)) != -1) { - switch(c) { - case 'h': - usage(); - help(); - exit(0); - break; - case 'J': - flags |= ECMA119_JOLIET; - break; - case 'R': - flags |= ECMA119_ROCKRIDGE; - break; - case 'L': - level = atoi(optarg); - break; - case '?': - usage(); - exit(1); - break; - } - } - - if (argc < 2) { - printf ("must pass directory to build iso from\n"); - usage(); - return 1; - } - if (argc < 3) { - printf ("must supply output file\n"); - usage(); - return 1; - } - fd = fopen(argv[optind+1], "w"); - if (!fd) { - err(1, "error opening output file"); - } - - root = iso_tree_radd_dir(NULL, argv[optind]); - if (!root) { - err(1, "error opening input directory"); - } - volume = iso_volume_new_with_root( "VOLID", "PUBID", "PREPID", root ); - volset = iso_volset_new( volume, "VOLSETID" ); - - src = iso_source_new_ecma119(volset, 0, level, flags); - - while (src->read(src, buf, 2048) == 2048) { - fwrite(buf, 1, 2048, fd); - } - fclose(fd); - - return 0; -} diff --git a/test/iso.py b/test/iso.py deleted file mode 100644 index 61da5fd..0000000 --- a/test/iso.py +++ /dev/null @@ -1,297 +0,0 @@ - -import struct -import tree -import sys - -voldesc_fmt = "B" "5s" "B" "2041x" - -# all these fields are common between the pri and sec voldescs -privoldesc_fmt = "B" "5s" "B" "x" "32s" "32s" "8x" "8s" "32x" "4s" "4s" "4s" "8s" "4s4s" "4s4s" "34s" "128s" \ - "128s" "128s" "128s" "37s" "37s" "37s" "17s" "17s" "17s" "17s" "B" "x" "512s" "653x" - -# the fields unique to the sec_vol_desc -secvoldesc_fmt = "x" "5x" "x" "B" "32x" "32x" "8x" "8x" "32s" "4x" "4x" "4x" "8x" "4x4x" "4x4x" "34x" "128x" \ - "128x" "128x" "128x" "37x" "37x" "37x" "17x" "17x" "17x" "17x" "x" "x" "512x" "653x" - -dirrecord_fmt = "B" "B" "8s" "8s" "7s" "B" "B" "B" "4s" "B" # + file identifier, padding field and SU area - -pathrecord_fmt = "B" "B" "4s" "2s" # + directory identifier and padding field - -def read_bb(str, le, be): - val1, = struct.unpack(le, str) - val2, = struct.unpack(be, str) - if val1 != val2: - print "val1=%d, val2=%d" % (val1, val2) - raise AssertionError, "values are not equal in dual byte-order field" - return val1 - -def read_bb4(str): - return read_bb(str, "4xI") - -def read_bb2(str): - return read_bb(str, "2xH") - -def read_lsb4(str): - return struct.unpack("I", str)[0] - -def read_msb2(str): - return struct.unpack(">H", str)[0] - -class VolDesc(object): - def __init__(self, data): - print "fmt len=%d, data len=%d" % ( struct.calcsize(voldesc_fmt), len(data) ) - self.vol_desc_type, self.standard_id, self.vol_desc_version = struct.unpack(voldesc_fmt, data) - -class PriVolDesc(VolDesc): - def __init__(self, data): - self.vol_desc_type, \ - self.standard_id, \ - self.vol_desc_version, \ - self.system_id, \ - self.volume_id, \ - self.vol_space_size, \ - self.vol_set_size, \ - self.vol_seq_num, \ - self.block_size, \ - self.path_table_size, \ - self.l_table_pos, \ - self.l_table2_pos, \ - self.m_table_pos, \ - self.m_table2_pos, \ - self.root_record, \ - self.volset_id, \ - self.publisher_id, \ - self.preparer_id, \ - self.application_id, \ - self.copyright_file, \ - self.abstract_file, \ - self.bibliographic_file, \ - self.creation_timestamp, \ - self.modification_timestamp, \ - self.expiration_timestamp, \ - self.effective_timestamp, \ - self.file_struct_version, \ - self.application_use = struct.unpack(privoldesc_fmt, data) - - # take care of reading the integer types - self.vol_space_size = read_bb4(self.vol_space_size) - self.vol_set_size = read_bb2(self.vol_set_size) - self.vol_seq_num = read_bb2(self.vol_seq_num) - self.block_size = read_bb2(self.block_size) - self.path_table_size = read_bb4(self.path_table_size) - self.l_table_pos = read_lsb4(self.l_table_pos) - self.l_table2_pos = read_lsb4(self.l_table2_pos) - self.m_table_pos = read_msb4(self.m_table_pos) - self.m_table2_pos = read_msb4(self.m_table2_pos) - - # parse the root directory record - self.root_record = DirRecord(self.root_record) - - def readPathTables(self, file): - file.seek( self.block_size * self.l_table_pos ) - self.l_table = PathTable( file.read(self.path_table_size), 0 ) - file.seek( self.block_size * self.m_table_pos ) - self.m_table = PathTable( file.read(self.path_table_size), 1 ) - - if self.l_table2_pos: - file.seek( self.block_size * self.l_table2_pos ) - self.l_table2 = PathTable( file.read(self.path_table_size), 0 ) - else: - self.l_table2 = None - - if self.m_table2_pos: - file.seek( self.block_size * self.m_table2_pos ) - self.m_table2 = PathTable( file.read(self.path_table_size), 1 ) - else: - self.m_table2 = None - - def toTree(self, isofile): - ret = tree.Tree(isofile=isofile.name) - ret.root = self.root_record.toTreeNode(parent=None, isofile=isofile) - return ret - -class SecVolDesc(PriVolDesc): - def __init__(self, data): - super(SecVolDesc,self).__init__(data) - self.flags, self.escape_sequences = struct.unpack(secvoldesc_fmt, data) - -# return a single volume descriptor of the appropriate type -def readVolDesc(data): - desc = VolDesc(data) - if desc.standard_id != "CD001": - print "Unexpected standard_id " +desc.standard_id - return None - if desc.vol_desc_type == 1: - return PriVolDesc(data) - elif desc.vol_desc_type == 2: - return SecVolDesc(data) - elif desc.vol_desc_type == 3: - print "I don't know about partitions yet!" - return None - elif desc.vol_desc_type == 255: - return desc - else: - print "Unknown volume descriptor type %d" % (desc.vol_desc_type,) - return None - -def readVolDescSet(file): - ret = [ readVolDesc(file.read(2048)) ] - while ret[-1].vol_desc_type != 255: - ret.append( readVolDesc(file.read(2048)) ) - - for vol in ret: - if vol.vol_desc_type == 1 or vol.vol_desc_type == 2: - vol.readPathTables(file) - - return ret - -class DirRecord: - def __init__(self, data): - self.len_dr, \ - self.len_xa, \ - self.block, \ - self.len_data, \ - self.timestamp, \ - self.flags, \ - self.unit_size, \ - self.gap_size, \ - self.vol_seq_number, \ - self.len_fi = struct.unpack(dirrecord_fmt, data[:33]) - self.children = [] - - if self.len_dr > len(data): - raise AssertionError, "Error: not enough data to read in DirRecord()" - elif self.len_dr < 34: - raise AssertionError, "Error: directory record too short" - - fmt = str(self.len_fi) + "s" - if self.len_fi % 2 == 0: - fmt += "1x" - len_su = self.len_dr - (33 + self.len_fi + 1 - (self.len_fi % 2)) - fmt += str(len_su) + "s" - - if len(data) >= self.len_dr: - self.file_id, self.su = struct.unpack(fmt, data[33 : self.len_dr]) - else: - print "Error: couldn't read file_id: not enough data" - self.file_id = "BLANK" - self.su = "" - - # convert to integers - self.block = read_bb4(self.block) - self.len_data = read_bb4(self.len_data) - self.vol_seq_number = read_bb2(self.vol_seq_number) - - def toTreeNode(self, parent, isofile, path=""): - ret = tree.TreeNode(parent=parent, isofile=isofile.name) - if len(path) > 0: - path += "/" - path += self.file_id - ret.path = path - - if self.flags & 2: # we are a directory, recurse - isofile.seek( 2048 * self.block ) - data = isofile.read( self.len_data ) - pos = 0 - while pos < self.len_data: - try: - child = DirRecord( data[pos:] ) - pos += child.len_dr - if child.len_fi == 1 and (child.file_id == "\x00" or child.file_id == "\x01"): - continue - print "read child named " +child.file_id - self.children.append( child ) - ret.children.append( child.toTreeNode(ret, isofile, path) ) - except AssertionError: - print "Couldn't read child of directory %s, position is %d, len is %d" % \ - (path, pos, self.len_data) - raise - - return ret - -class PathTableRecord: - def __init__(self, data, readint2, readint4): - self.len_di, self.len_xa, self.block, self.parent_number = struct.unpack(pathrecord_fmt, data[:8]) - - if len(data) < self.len_di + 8: - raise AssertionError, "Error: not enough data to read path table record" - - fmt = str(self.len_di) + "s" - self.dir_id, = struct.unpack(fmt, data[8:8+self.len_di]) - - self.block = readint4(self.block) - self.parent_number = readint2(self.parent_number) - -class PathTable: - def __init__(self, data, m_type): - if m_type: - readint2 = read_msb2 - readint4 = read_msb4 - else: - readint2 = read_lsb2 - readint4 = read_lsb4 - pos = 0 - self.records = [] - while pos < len(data): - try: - self.records.append( PathTableRecord(data[pos:], readint2, readint4) ) - print "Read path record %d: dir_id %s, block %d, parent_number %d" %\ - (len(self.records), self.records[-1].dir_id, self.records[-1].block, self.records[-1].parent_number) - pos += self.records[-1].len_di + 8 - pos += pos % 2 - except AssertionError: - print "Last successfully read path table record had dir_id %s, block %d, parent_number %d" % \ - (self.records[-1].dir_id, self.records[-1].block, self.records[-1].parent_number) - print "Error was near offset %x" % (pos,) - raise - - def findRecord(self, dir_id, block, parent_number): - number=1 - for record in self.records: - if record.dir_id == dir_id and record.block == block and record.parent_number == parent_number: - return number, record - number += 1 - - return None, None - - # check this path table for consistency against the actual directory heirarchy - def crossCheckDirRecords(self, root, parent_number=1): - number, rec = self.findRecord(root.file_id, root.block, parent_number) - - if not rec: - print "Error: directory record parent_number %d, dir_id %s, block %d doesn't match a path table record" % \ - (parent_number, root.file_id, root.block) - parent = self.records[parent_number] - print "Parent has parent_number %d, dir_id %s, block %d" % (parent.parent_number, parent.dir_id, parent.block) - return 0 - - for child in root.children: - if child.flags & 2: - self.crossCheckDirRecords(child, number) - - -if len(sys.argv) != 2: - print "Please enter the name of the .iso file to open" - sys.exit(1) - -f = file(sys.argv[1]) -f.seek(2048 * 16) # system area -volumes = readVolDescSet(f) -vol = volumes[0] -t = vol.toTree(f) -vol.l_table.crossCheckDirRecords(vol.root_record) -vol.m_table.crossCheckDirRecords(vol.root_record) - -vol = volumes[1] -try: - t = vol.toTree(f) - vol.l_table.crossCheckDirRecords(vol.root_record) - vol.m_table.crossCheckDirRecords(vol.root_record) -except AttributeError: - pass