|
|
|
@ -16,6 +16,7 @@
|
|
|
|
|
#include "volume.h"
|
|
|
|
|
#include "tree.h"
|
|
|
|
|
#include "util.h"
|
|
|
|
|
#include "file.h"
|
|
|
|
|
#include "libisofs.h"
|
|
|
|
|
#include "libburn/libburn.h"
|
|
|
|
|
|
|
|
|
@ -101,30 +102,35 @@ add_susp_fields_rec(struct ecma119_write_target *t,
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
switch (node->type) {
|
|
|
|
|
case ECMA119_FILE:
|
|
|
|
|
break;
|
|
|
|
|
case ECMA119_SYMLINK:
|
|
|
|
|
rrip_add_SL(t, node);
|
|
|
|
|
break;
|
|
|
|
|
case ECMA119_DIR:
|
|
|
|
|
if (node->info.dir.real_parent != node->parent) {
|
|
|
|
|
rrip_add_RE(t, node);
|
|
|
|
|
rrip_add_PL(t, node);
|
|
|
|
|
}
|
|
|
|
|
for (i = 0; i < node->info.dir.nchildren; i++) {
|
|
|
|
|
add_susp_fields_rec(t, node->info.dir.children[i]);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ECMA119_PLACEHOLDER:
|
|
|
|
|
rrip_add_CL(t, node);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
// FIXME support for device blocks by uncommenting this
|
|
|
|
|
//if (node->iso_self->attrib.st_rdev)
|
|
|
|
|
// rrip_add_PN(t, node);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
@ -151,35 +157,35 @@ calc_dir_size(struct ecma119_write_target *t,
|
|
|
|
|
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];
|
|
|
|
|
|
|
|
|
|
newlen = dir->dir.len + ch->dirent_len + ch->susp.non_CE_len;
|
|
|
|
|
if ((newlen % 2048) < (dir->dir.len % 2048)) {
|
|
|
|
|
dir->dir.len = newlen + (2048 - (dir->dir.len % 2048));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
dir->dir.len += ch->dirent_len + ch->susp.non_CE_len;
|
|
|
|
|
dir->info.dir.len = 34 + dir->info.dir.self_susp.non_CE_len
|
|
|
|
|
+ 34 + dir->info.dir.parent_susp.non_CE_len;
|
|
|
|
|
dir->info.dir.CE_len = dir->info.dir.self_susp.CE_len
|
|
|
|
|
+ dir->info.dir.parent_susp.CE_len;
|
|
|
|
|
for (i = 0; i < dir->info.dir.nchildren; ++i) {
|
|
|
|
|
struct ecma119_tree_node *ch = dir->info.dir.children[i];
|
|
|
|
|
|
|
|
|
|
newlen = dir->info.dir.len + ch->dirent_len + ch->susp.non_CE_len;
|
|
|
|
|
if ((newlen % 2048) < (dir->info.dir.len % 2048)) {
|
|
|
|
|
dir->info.dir.len = newlen + (2048 - (dir->info.dir.len % 2048));
|
|
|
|
|
} else {
|
|
|
|
|
dir->info.dir.len += ch->dirent_len + ch->susp.non_CE_len;
|
|
|
|
|
}
|
|
|
|
|
dir->dir.CE_len += ch->susp.CE_len;
|
|
|
|
|
dir->info.dir.CE_len += ch->susp.CE_len;
|
|
|
|
|
}
|
|
|
|
|
t->total_dir_size += round_up(dir->dir.len + dir->dir.CE_len,
|
|
|
|
|
t->total_dir_size += round_up(dir->info.dir.len + dir->info.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;
|
|
|
|
|
for (i = 0; i < dir->info.dir.nchildren; i++) {
|
|
|
|
|
struct ecma119_tree_node *ch = dir->info.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++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// else if (iso && iso->attrib.st_size
|
|
|
|
|
// && iso->loc.type == LIBISO_FILESYS
|
|
|
|
|
// && iso->loc.path) {
|
|
|
|
|
// t->filelist_len++;
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -195,26 +201,27 @@ calc_dir_pos(struct ecma119_write_target *t,
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
dir->info.dir.block = t->curblock;
|
|
|
|
|
t->curblock += div_up(dir->info.dir.len + dir->info.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];
|
|
|
|
|
for (i = 0; i < dir->info.dir.nchildren; i++) {
|
|
|
|
|
struct ecma119_tree_node *ch = dir->info.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;
|
|
|
|
|
}
|
|
|
|
|
static int
|
|
|
|
|
cmp_file(const void *f1, const void *f2)
|
|
|
|
|
{
|
|
|
|
|
struct iso_file *f = *((struct iso_file**)f1);
|
|
|
|
|
struct iso_file *g = *((struct iso_file**)f2);
|
|
|
|
|
/* higher weighted first */
|
|
|
|
|
return g->sort_weight - f->sort_weight;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Fill out the block field for each ecma119_tree_node that is a file and fill
|
|
|
|
|
* out t->filelist.
|
|
|
|
|
* Fill out the block field for each file and fill out t->filelist.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
calc_file_pos(struct ecma119_write_target *t,
|
|
|
|
@ -223,31 +230,40 @@ calc_file_pos(struct ecma119_write_target *t,
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
t->filelist = calloc(1, sizeof(struct iso_file *) * t->file_table->count);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < FILE_HASH_NODES; ++i) {
|
|
|
|
|
|
|
|
|
|
struct iso_file_hash_node *node;
|
|
|
|
|
|
|
|
|
|
node = t->file_table->table[i];
|
|
|
|
|
if (!node)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
struct iso_file *file = node->file;
|
|
|
|
|
if (file->size)
|
|
|
|
|
t->filelist[t->curfile++] = file;
|
|
|
|
|
node = node->next;
|
|
|
|
|
} while (node);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
t->filelist_len = t->curfile;
|
|
|
|
|
|
|
|
|
|
/* sort */
|
|
|
|
|
if ( t->sort_files )
|
|
|
|
|
qsort(t->filelist, t->filelist_len, sizeof(void*), cmp_file);
|
|
|
|
|
|
|
|
|
|
/* fill block value */
|
|
|
|
|
for ( i = 0; i < t->filelist_len; ++i) {
|
|
|
|
|
struct iso_file *file = t->filelist[i];
|
|
|
|
|
file->block = t->curblock;
|
|
|
|
|
t->curblock += div_up(file->size, t->block_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* reset curfile when we're finished */
|
|
|
|
|
if (!dir->parent) {
|
|
|
|
|
t->curfile = 0;
|
|
|
|
|
}
|
|
|
|
|
t->curfile = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct ecma119_write_target*
|
|
|
|
@ -259,33 +275,48 @@ ecma119_target_new(struct iso_volset *volset,
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
struct iso_tree_node *iso_root =
|
|
|
|
|
(struct iso_tree_node*) volset->volume[volnum]->root;
|
|
|
|
|
|
|
|
|
|
//TODO default values here, need an API for this
|
|
|
|
|
t->cache_inodes = 1;
|
|
|
|
|
t->replace_mode = 1;
|
|
|
|
|
t->dir_mode = 0555;
|
|
|
|
|
t->file_mode = 0444;
|
|
|
|
|
t->gid = 0;
|
|
|
|
|
t->uid = 0;
|
|
|
|
|
t->input_charset = "UTF-8";
|
|
|
|
|
t->ouput_charset = "UTF-8";
|
|
|
|
|
t->sort_files = 1;
|
|
|
|
|
|
|
|
|
|
t->file_table = iso_file_table_new(t->cache_inodes);
|
|
|
|
|
volset->refcount++;
|
|
|
|
|
t->root = ecma119_tree_create(t, iso_root);
|
|
|
|
|
t->iso_level = level;
|
|
|
|
|
t->block_size = 2048;
|
|
|
|
|
|
|
|
|
|
t->rockridge = (flags & ECMA119_ROCKRIDGE) ? 1 : 0;
|
|
|
|
|
t->joliet = (flags & ECMA119_JOLIET) ? 1 : 0;
|
|
|
|
|
|
|
|
|
|
t->root = ecma119_tree_create(t, iso_root);
|
|
|
|
|
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->pathlist_joliet = calloc(1, sizeof(void*) * t->dirlist_len_joliet);
|
|
|
|
|
t->dirlist_joliet = calloc(1, sizeof(void*) * t->dirlist_len_joliet);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
//t->filelist = calloc(1, sizeof(void*) * t->filelist_len);
|
|
|
|
|
|
|
|
|
|
/* fill out the pathlist */
|
|
|
|
|
t->pathlist[0] = t->root;
|
|
|
|
@ -293,10 +324,10 @@ ecma119_target_new(struct iso_volset *volset,
|
|
|
|
|
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];
|
|
|
|
|
for (j = 0; j < dir->info.dir.nchildren; j++) {
|
|
|
|
|
struct ecma119_tree_node *ch = dir->info.dir.children[j];
|
|
|
|
|
if (ch->type == ECMA119_DIR) {
|
|
|
|
|
size_t len = 8 + strlen(ch->name);
|
|
|
|
|
size_t len = 8 + strlen(ch->iso_name);
|
|
|
|
|
t->pathlist[cur++] = ch;
|
|
|
|
|
t->path_table_size += len + len % 2;
|
|
|
|
|
}
|
|
|
|
@ -323,11 +354,19 @@ ecma119_target_new(struct iso_volset *volset,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
calc_dir_pos(t, t->root);
|
|
|
|
|
if (t->joliet)
|
|
|
|
|
|
|
|
|
|
/* reset curfile when we're finished */
|
|
|
|
|
t->curfile = 0;
|
|
|
|
|
if (t->joliet) {
|
|
|
|
|
|
|
|
|
|
joliet_calc_dir_pos(t, t->joliet_root);
|
|
|
|
|
|
|
|
|
|
/* reset curfile when we're finished */
|
|
|
|
|
t->curfile = 0;
|
|
|
|
|
}
|
|
|
|
|
calc_file_pos(t, t->root);
|
|
|
|
|
if (t->joliet)
|
|
|
|
|
joliet_update_file_pos (t, t->joliet_root);
|
|
|
|
|
//if (t->joliet)
|
|
|
|
|
// joliet_update_file_pos (t, t->joliet_root);
|
|
|
|
|
|
|
|
|
|
if (t->rockridge) {
|
|
|
|
|
susp_finalize(t, t->root);
|
|
|
|
@ -406,11 +445,13 @@ 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;
|
|
|
|
|
struct iso_file *f = t->filelist[f_st->file];
|
|
|
|
|
const char *path = f->path;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!f_st->fd) {
|
|
|
|
|
f_st->data_len = f->iso_self->attrib.st_size;
|
|
|
|
|
printf("Writing file %s\n", path);
|
|
|
|
|
f_st->data_len = f->size;
|
|
|
|
|
f_st->fd = fopen(path, "r");
|
|
|
|
|
if (!f_st->fd)
|
|
|
|
|
err(1, "couldn't open %s for reading", path);
|
|
|
|
@ -438,16 +479,16 @@ 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 = str2d_char(volume->volume_id);
|
|
|
|
|
char *pub_id = str2a_char(volume->publisher_id);
|
|
|
|
|
char *data_id = str2a_char(volume->data_preparer_id);
|
|
|
|
|
char *volset_id = str2d_char(t->volset->volset_id);
|
|
|
|
|
char *vol_id = str2d_char(volume->volume_id, t->input_charset);
|
|
|
|
|
char *pub_id = str2a_char(volume->publisher_id, t->input_charset);
|
|
|
|
|
char *data_id = str2a_char(volume->data_preparer_id, t->input_charset);
|
|
|
|
|
char *volset_id = str2d_char(t->volset->volset_id, t->input_charset);
|
|
|
|
|
|
|
|
|
|
char *system_id = str2a_char(volume->system_id);
|
|
|
|
|
char *application_id = str2a_char(volume->application_id);
|
|
|
|
|
char *copyright_file_id = str2d_char(volume->copyright_file_id);
|
|
|
|
|
char *abstract_file_id = str2d_char(volume->abstract_file_id);
|
|
|
|
|
char *biblio_file_id = str2d_char(volume->biblio_file_id);
|
|
|
|
|
char *system_id = str2a_char(volume->system_id, t->input_charset);
|
|
|
|
|
char *application_id = str2a_char(volume->application_id, t->input_charset);
|
|
|
|
|
char *copyright_file_id = str2d_char(volume->copyright_file_id, t->input_charset);
|
|
|
|
|
char *abstract_file_id = str2d_char(volume->abstract_file_id, t->input_charset);
|
|
|
|
|
char *biblio_file_id = str2d_char(volume->biblio_file_id, t->input_charset);
|
|
|
|
|
|
|
|
|
|
vol->vol_desc_type[0] = 1;
|
|
|
|
|
memcpy(vol->std_identifier, "CD001", 5);
|
|
|
|
@ -522,17 +563,18 @@ write_path_table(struct ecma119_write_target *t, int l_type, uint8_t *buf)
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < t->dirlist_len; i++) {
|
|
|
|
|
dir = t->pathlist[i];
|
|
|
|
|
assert(dir->type == ECMA119_DIR);
|
|
|
|
|
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_di[0] = dir->parent ? (uint8_t) strlen(dir->iso_name) : 1;
|
|
|
|
|
rec->len_xa[0] = 0;
|
|
|
|
|
write_int(rec->block, dir->block, 4);
|
|
|
|
|
write_int(rec->block, dir->info.dir.block, 4);
|
|
|
|
|
write_int(rec->parent, parent + 1, 2);
|
|
|
|
|
if (dir->parent)
|
|
|
|
|
memcpy(rec->dir_id, dir->name, rec->len_di[0]);
|
|
|
|
|
memcpy(rec->dir_id, dir->iso_name, rec->len_di[0]);
|
|
|
|
|
buf += 8 + rec->len_di[0] + (rec->len_di[0] % 2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -558,22 +600,36 @@ write_one_dir_record(struct ecma119_write_target *t,
|
|
|
|
|
int file_id,
|
|
|
|
|
uint8_t *buf)
|
|
|
|
|
{
|
|
|
|
|
uint32_t len;
|
|
|
|
|
uint32_t block;
|
|
|
|
|
uint8_t len_dr = (file_id >= 0) ? 34 : node->dirent_len;
|
|
|
|
|
uint8_t len_fi = (file_id >= 0) ? 1 : strlen(node->name);
|
|
|
|
|
uint8_t len_fi = (file_id >= 0) ? 1 : strlen(node->iso_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;
|
|
|
|
|
uint8_t *name = (file_id >= 0) ? &f_id : (uint8_t*)node->iso_name;
|
|
|
|
|
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (node->type == ECMA119_DIR) {
|
|
|
|
|
len = node->info.dir.len;
|
|
|
|
|
block = node->info.dir.block;
|
|
|
|
|
} else if (node->type == ECMA119_FILE) {
|
|
|
|
|
len = node->info.file->size;
|
|
|
|
|
block = node->info.file->block;
|
|
|
|
|
} else {
|
|
|
|
|
/* for nodes other than files and dirs, we set both len and block to 0 */
|
|
|
|
|
len = 0;
|
|
|
|
|
block = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
assert(node->type == ECMA119_DIR);
|
|
|
|
|
susp_write(t, &node->info.dir.self_susp, &buf[len_dr]);
|
|
|
|
|
len_dr += node->info.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;
|
|
|
|
|
assert(node->type == ECMA119_DIR);
|
|
|
|
|
susp_write(t, &node->info.dir.parent_susp, &buf[len_dr]);
|
|
|
|
|
len_dr += node->info.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;
|
|
|
|
@ -583,7 +639,7 @@ write_one_dir_record(struct ecma119_write_target *t,
|
|
|
|
|
node = node->parent;
|
|
|
|
|
|
|
|
|
|
rec->len_dr[0] = len_dr;
|
|
|
|
|
iso_bb(rec->block, node->block, 4);
|
|
|
|
|
iso_bb(rec->block, 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;
|
|
|
|
@ -611,8 +667,8 @@ write_one_dir(struct ecma119_write_target *t,
|
|
|
|
|
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);
|
|
|
|
|
for (i = 0; i < dir->info.dir.nchildren; i++) {
|
|
|
|
|
write_one_dir_record(t, dir->info.dir.children[i], -1, buf);
|
|
|
|
|
len = ((struct ecma119_dir_record*) buf)->len_dr[0];
|
|
|
|
|
if ((buf + len - prior_buf) >= 2048) {
|
|
|
|
|
for (j = len - 1; j >= 0; j--) {
|
|
|
|
@ -629,16 +685,16 @@ write_one_dir(struct ecma119_write_target *t,
|
|
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
susp_write_CE(t, &dir->info.dir.self_susp, buf);
|
|
|
|
|
buf += dir->info.dir.self_susp.CE_len;
|
|
|
|
|
susp_write_CE(t, &dir->info.dir.parent_susp, buf);
|
|
|
|
|
buf += dir->info.dir.parent_susp.CE_len;
|
|
|
|
|
for (i = 0; i < dir->info.dir.nchildren; i++) {
|
|
|
|
|
susp_write_CE(t, &dir->info.dir.children[i]->susp, buf);
|
|
|
|
|
buf += dir->info.dir.children[i]->susp.CE_len;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
assert (buf - orig_buf == dir->dir.len + dir->dir.CE_len);
|
|
|
|
|
assert (buf - orig_buf == dir->info.dir.len + dir->info.dir.CE_len);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
@ -649,7 +705,7 @@ write_dirs(struct ecma119_write_target *t, uint8_t *buf)
|
|
|
|
|
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);
|
|
|
|
|
buf += round_up(dir->info.dir.len + dir->info.dir.CE_len, t->block_size);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -714,6 +770,9 @@ bs_free_data(struct burn_source *bs)
|
|
|
|
|
{
|
|
|
|
|
struct ecma119_write_target *t = (struct ecma119_write_target*)bs->data;
|
|
|
|
|
ecma119_tree_free(t->root);
|
|
|
|
|
iso_file_table_clear(t->file_table);
|
|
|
|
|
|
|
|
|
|
//FIXME free joliet tree
|
|
|
|
|
free(t->dirlist);
|
|
|
|
|
free(t->pathlist);
|
|
|
|
|
free(t->dirlist_joliet);
|
|
|
|
|