Support for writting ISO Level 3 images.
This allows files greater than 4GB, that are written using multiple extents.
This commit is contained in:
parent
68bd636bd8
commit
6ff7699c47
@ -235,11 +235,13 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
*/
|
||||
static
|
||||
void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
||||
uint8_t *buf, size_t len_fi, struct susp_info *info)
|
||||
uint8_t *buf, size_t len_fi, struct susp_info *info,
|
||||
int extent)
|
||||
{
|
||||
uint32_t len;
|
||||
uint32_t block;
|
||||
uint8_t len_dr; /*< size of dir entry without SUSP fields */
|
||||
int multi_extend = 0;
|
||||
uint8_t *name = (file_id >= 0) ? (uint8_t*)&file_id
|
||||
: (uint8_t*)node->iso_name;
|
||||
|
||||
@ -260,8 +262,17 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
||||
len = node->info.dir->len;
|
||||
block = node->info.dir->block;
|
||||
} else if (node->type == ECMA119_FILE) {
|
||||
len = iso_file_src_get_size(node->info.file);
|
||||
off_t size = iso_file_src_get_size(node->info.file)
|
||||
- ((off_t)0xFFFFF800) * (off_t)extent; /* bytes in another extent */
|
||||
if (size > (off_t) 0xffffffff) {
|
||||
/* 2097151 is the number of blocks needed to store 4 GB - 2048 */
|
||||
block = node->info.file->block + extent * 2097151;
|
||||
len = 0xFFFFF800;
|
||||
multi_extend = 1;
|
||||
} else {
|
||||
len = (uint32_t) size;
|
||||
block = node->info.file->block;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* for nodes other than files and dirs, we set both
|
||||
@ -281,7 +292,7 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
||||
iso_bb(rec->block, block, 4);
|
||||
iso_bb(rec->length, len, 4);
|
||||
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
||||
rec->flags[0] = (node->type == ECMA119_DIR) ? 2 : 0;
|
||||
rec->flags[0] = ((node->type == ECMA119_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
|
||||
iso_bb(rec->vol_seq_number, 1, 2);
|
||||
rec->len_fi[0] = len_fi;
|
||||
|
||||
@ -365,7 +376,7 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
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, 0, vol.root_dir_record, 1, NULL);
|
||||
write_one_dir_record(t, t->root, 0, vol.root_dir_record, 1, NULL, 0);
|
||||
|
||||
strncpy_pad((char*)vol.vol_set_id, volset_id, 128);
|
||||
strncpy_pad((char*)vol.publisher_id, pub_id, 128);
|
||||
@ -429,7 +440,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
||||
}
|
||||
}
|
||||
len = 34 + info.suf_len;
|
||||
write_one_dir_record(t, dir, 0, buf, 1, &info);
|
||||
write_one_dir_record(t, dir, 0, buf, 1, &info, 0);
|
||||
buf += len;
|
||||
|
||||
if (t->rockridge) {
|
||||
@ -439,12 +450,15 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
||||
}
|
||||
}
|
||||
len = 34 + info.suf_len;
|
||||
write_one_dir_record(t, dir, 1, buf, 1, &info);
|
||||
write_one_dir_record(t, dir, 1, buf, 1, &info, 0);
|
||||
buf += len;
|
||||
|
||||
for (i = 0; i < dir->info.dir->nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir->children[i];
|
||||
|
||||
int extent = 0;
|
||||
do {
|
||||
|
||||
/* compute len of directory entry */
|
||||
fi_len = strlen(child->iso_name);
|
||||
len = fi_len + 33 + (fi_len % 2 ? 0 : 1);
|
||||
@ -471,8 +485,22 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
||||
buf = buffer;
|
||||
}
|
||||
/* write the directory entry in any case */
|
||||
write_one_dir_record(t, child, -1, buf, fi_len, &info);
|
||||
write_one_dir_record(t, child, -1, buf, fi_len, &info, extent);
|
||||
buf += len;
|
||||
|
||||
if (child->type == ECMA119_FILE) {
|
||||
/* check if file is too big and need more extents */
|
||||
off_t size = iso_file_src_get_size(child->info.file)
|
||||
- ((off_t)0xFFFFF800) * (off_t)extent;
|
||||
if (size > (off_t) 0xffffffff) {
|
||||
extent++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break; /* we only have a single extent */
|
||||
}
|
||||
} while(1); /* loop for each extend */
|
||||
}
|
||||
|
||||
/* write the last block */
|
||||
@ -1315,7 +1343,7 @@ int iso_write_opts_set_iso_level(IsoWriteOpts *opts, int level)
|
||||
if (opts == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
if (level != 1 && level != 2) {
|
||||
if (level != 1 && level != 2 && level != 3) {
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
opts->level = level;
|
||||
|
@ -161,7 +161,7 @@ int create_file(Ecma119Image *img, IsoFile *iso, Ecma119Node **node)
|
||||
off_t size;
|
||||
|
||||
size = iso_stream_get_size(iso->stream);
|
||||
if (size > (off_t)0xffffffff) {
|
||||
if (size > (off_t)0xffffffff && img->iso_level != 3) {
|
||||
return iso_msg_submit(img->image->id, ISO_FILE_TOO_BIG, 0,
|
||||
"File \"%s\" can't be added to image because "
|
||||
"is greater than 4GB", iso->node.name);
|
||||
|
@ -259,11 +259,6 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||
i = 0;
|
||||
while ((file = filelist[i++]) != NULL) {
|
||||
|
||||
/*
|
||||
* TODO WARNING
|
||||
* when we allow files greater than 4GB, current DIV_UP implementation
|
||||
* can overflow!!
|
||||
*/
|
||||
uint32_t nblocks = DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE);
|
||||
|
||||
res = filesrc_open(file);
|
||||
|
@ -937,6 +937,7 @@ void iso_write_opts_free(IsoWriteOpts *opts);
|
||||
* -> 1 for higher compatibility with old systems. With this level
|
||||
* filenames are restricted to 8.3 characters.
|
||||
* -> 2 to allow up to 31 filename characters.
|
||||
* -> 3 to allow files greater than 4GB
|
||||
* @return
|
||||
* 1 success, < 0 error
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user