Define functions to generate and write the RR/SUSP fields.
This commit is contained in:
parent
778e39ba3c
commit
c3af3553df
@ -78,7 +78,7 @@ size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
|
|||||||
size_t ce_len = 0;
|
size_t ce_len = 0;
|
||||||
|
|
||||||
/* size of "." and ".." entries */
|
/* size of "." and ".." entries */
|
||||||
len += 34 + 34;
|
len = 34 + 34;
|
||||||
if (t->rockridge) {
|
if (t->rockridge) {
|
||||||
len += rrip_calc_len(t, dir, 1, 255 - 34, &ce_len);
|
len += rrip_calc_len(t, dir, 1, 255 - 34, &ce_len);
|
||||||
*ce += ce_len;
|
*ce += ce_len;
|
||||||
@ -189,22 +189,23 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
*
|
*
|
||||||
* @param file_id
|
* @param file_id
|
||||||
* if >= 0, we use it instead of the filename (for "." and ".." entries).
|
* if >= 0, we use it instead of the filename (for "." and ".." entries).
|
||||||
* As a magic number, file_id == 3 means that we are writing the root
|
|
||||||
* directory record in the PVD (ECMA-119, 8.4.18) (in order to distinguish
|
|
||||||
* it from the "." entry in the root directory)
|
|
||||||
* @param len_fi
|
* @param len_fi
|
||||||
* Computed length of the file identifier. Total size of the directory
|
* Computed length of the file identifier. Total size of the directory
|
||||||
* entry will be len + 33 + padding if needed (ECMA-119, 9.1.12)
|
* entry will be len + 33 + padding if needed (ECMA-119, 9.1.12)
|
||||||
|
* @param info
|
||||||
|
* SUSP entries for the given directory record. It will be NULL for the
|
||||||
|
* root directory record in the PVD (ECMA-119, 8.4.18) (in order to
|
||||||
|
* distinguish it from the "." entry in the root directory)
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
||||||
uint8_t *buf, size_t len_fi)
|
uint8_t *buf, size_t len_fi, struct susp_info *info)
|
||||||
{
|
{
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
uint32_t block;
|
uint32_t block;
|
||||||
uint8_t len_dr;
|
uint8_t len_dr; /*< size of dir entry without SUSP fields */
|
||||||
uint8_t f_id = (uint8_t) ((file_id == 3) ? 0 : file_id);
|
uint8_t *name = (file_id >= 0) ? (uint8_t*)&file_id :
|
||||||
uint8_t *name = (file_id >= 0) ? &f_id : (uint8_t*)node->iso_name;
|
(uint8_t*)node->iso_name;
|
||||||
|
|
||||||
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
|
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
|
||||||
|
|
||||||
@ -240,13 +241,18 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
|||||||
if (file_id == 1 && node->parent)
|
if (file_id == 1 && node->parent)
|
||||||
node = node->parent;
|
node = node->parent;
|
||||||
|
|
||||||
rec->len_dr[0] = len_dr;
|
rec->len_dr[0] = len_dr + (info != NULL ? info->suf_len : 0);
|
||||||
iso_bb(rec->block, block, 4);
|
iso_bb(rec->block, block, 4);
|
||||||
iso_bb(rec->length, len, 4);
|
iso_bb(rec->length, len, 4);
|
||||||
iso_datetime_7(rec->recording_time, t->now);
|
iso_datetime_7(rec->recording_time, t->now);
|
||||||
rec->flags[0] = (node->type == ECMA119_DIR) ? 2 : 0;
|
rec->flags[0] = (node->type == ECMA119_DIR) ? 2 : 0;
|
||||||
iso_bb(rec->vol_seq_number, 1, 2);
|
iso_bb(rec->vol_seq_number, 1, 2);
|
||||||
rec->len_fi[0] = len_fi;
|
rec->len_fi[0] = len_fi;
|
||||||
|
|
||||||
|
/* and finally write the SUSP fields */
|
||||||
|
if (info != NULL) {
|
||||||
|
rrip_write_susp_fields(t, info, buf + len_dr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -303,7 +309,7 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
|
|||||||
iso_lsb(vol.l_path_table_pos, t->l_path_table_pos, 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);
|
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, 1);
|
write_one_dir_record(t, t->root, 0, vol.root_dir_record, 1, NULL);
|
||||||
|
|
||||||
if (volset_id)
|
if (volset_id)
|
||||||
strncpy((char*)vol.vol_set_id, volset_id, 128);
|
strncpy((char*)vol.vol_set_id, volset_id, 128);
|
||||||
@ -347,6 +353,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
|||||||
uint8_t buffer[BLOCK_SIZE];
|
uint8_t buffer[BLOCK_SIZE];
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t fi_len, len;
|
size_t fi_len, len;
|
||||||
|
struct susp_info info;
|
||||||
|
|
||||||
/* buf will point to current write position on buffer */
|
/* buf will point to current write position on buffer */
|
||||||
uint8_t *buf = buffer;
|
uint8_t *buf = buffer;
|
||||||
@ -354,12 +361,35 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
|||||||
/* initialize buffer with 0s */
|
/* initialize buffer with 0s */
|
||||||
memset(buffer, 0, BLOCK_SIZE);
|
memset(buffer, 0, BLOCK_SIZE);
|
||||||
|
|
||||||
/* write the "." and ".." entries first */
|
/*
|
||||||
write_one_dir_record(t, dir, 0, buf, 1);
|
* set susp_info to 0's, this way code for both plain ECMA-119 and
|
||||||
buf += 34;
|
* RR is very similar
|
||||||
|
*/
|
||||||
|
memset(&info, 0, sizeof(struct susp_info));
|
||||||
|
if (t->rockridge) {
|
||||||
|
/* initialize the ce_block, it might be needed */
|
||||||
|
info.ce_block = div_up(dir->info.dir.block + dir->info.dir.len,
|
||||||
|
BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
write_one_dir_record(t, dir, 1, buf, 1);
|
/* write the "." and ".." entries first */
|
||||||
buf += 34;
|
if (t->rockridge) {
|
||||||
|
ret = rrip_get_susp_fields(t, dir, 1, 255 - 32, &info);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write_one_dir_record(t, dir, 0, buf, 1, &info);
|
||||||
|
buf += 34 + info.suf_len;
|
||||||
|
|
||||||
|
if (t->rockridge) {
|
||||||
|
ret = rrip_get_susp_fields(t, dir, 2, 255 - 32, &info);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write_one_dir_record(t, dir, 1, buf, 1, &info);
|
||||||
|
buf += 34 + info.suf_len;
|
||||||
|
|
||||||
for (i = 0; i < dir->info.dir.nchildren; i++) {
|
for (i = 0; i < dir->info.dir.nchildren; i++) {
|
||||||
Ecma119Node *child = dir->info.dir.children[i];
|
Ecma119Node *child = dir->info.dir.children[i];
|
||||||
@ -370,6 +400,16 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
|||||||
if (child->type == ECMA119_FILE && !t->omit_version_numbers) {
|
if (child->type == ECMA119_FILE && !t->omit_version_numbers) {
|
||||||
len += 2;
|
len += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* get the SUSP fields if rockridge is enabled */
|
||||||
|
if (t->rockridge) {
|
||||||
|
ret = rrip_get_susp_fields(t, child, 0, 255 - len, &info);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
len += info.suf_len;
|
||||||
|
}
|
||||||
|
|
||||||
if ( (buf + len - buffer) > BLOCK_SIZE ) {
|
if ( (buf + len - buffer) > BLOCK_SIZE ) {
|
||||||
/* dir doesn't fit in current block */
|
/* dir doesn't fit in current block */
|
||||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||||
@ -380,12 +420,21 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
|||||||
buf = buffer;
|
buf = buffer;
|
||||||
}
|
}
|
||||||
/* write the directory entry in any case */
|
/* write the directory entry in any case */
|
||||||
write_one_dir_record(t, child, -1, buf, fi_len);
|
write_one_dir_record(t, child, -1, buf, fi_len, &info);
|
||||||
buf += len;
|
buf += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write the last block */
|
/* write the last block */
|
||||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write the Continuation Area if needed */
|
||||||
|
if (info.ce_len > 0) {
|
||||||
|
ret = rrip_write_ce_fields(t, &info);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,6 +199,22 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
return su_size;
|
return su_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||||
|
size_t space, struct susp_info *info)
|
||||||
|
{
|
||||||
|
//TODO to implement
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info,
|
||||||
|
void *buf)
|
||||||
|
{
|
||||||
|
//TODO to implement
|
||||||
|
}
|
||||||
|
|
||||||
|
int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
||||||
|
{
|
||||||
|
//TODO to implement
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -8,10 +8,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions and structures used for Rock Ridge support.
|
* This header defines the functions and structures needed to add RockRidge
|
||||||
|
* extensions to an ISO image.
|
||||||
*
|
*
|
||||||
* See IEEE P1282, Rock Ridge Interchange Protocol, Draft Standard version
|
* References:
|
||||||
* 1.12 for further details.
|
*
|
||||||
|
* - SUSP (IEEE 1281).
|
||||||
|
* System Use Sharing Protocol, draft standard version 1.12.
|
||||||
|
*
|
||||||
|
* - RRIP (IEEE 1282)
|
||||||
|
* Rock Ridge Interchange Protocol, Draft Standard version 1.12.
|
||||||
|
*
|
||||||
|
* - ECMA-119 (ISO-9660)
|
||||||
|
* Volume and File Structure of CDROM for Information Interchange.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBISO_ROCKRIDGE_H
|
#ifndef LIBISO_ROCKRIDGE_H
|
||||||
@ -19,6 +28,30 @@
|
|||||||
|
|
||||||
#include "ecma119.h"
|
#include "ecma119.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This contains the information about the System Use Fields (SUSP, 4.1),
|
||||||
|
* that will be written in the System Use Areas, both in the ISO directory
|
||||||
|
* record System Use field (ECMA-119, 9.1.13) or in a Continuation Area as
|
||||||
|
* defined by SUSP.
|
||||||
|
*/
|
||||||
|
struct susp_info
|
||||||
|
{
|
||||||
|
/** Number of SUSP fields in the System Use field */
|
||||||
|
size_t n_susp_fields;
|
||||||
|
uint8_t **susp_fields;
|
||||||
|
|
||||||
|
/** Length of the part of the SUSP area that fits in the dirent. */
|
||||||
|
int suf_len;
|
||||||
|
|
||||||
|
/** Length of the part of the SUSP area that will go in a CE area. */
|
||||||
|
uint32_t ce_block;
|
||||||
|
uint32_t ce_len;
|
||||||
|
|
||||||
|
size_t n_ce_susp_fields;
|
||||||
|
uint8_t **ce_susp_fields;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the length needed for write all RR and SUSP entries for a given
|
* Compute the length needed for write all RR and SUSP entries for a given
|
||||||
* node.
|
* node.
|
||||||
@ -36,4 +69,39 @@
|
|||||||
size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type,
|
size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type,
|
||||||
size_t space, size_t *ce);
|
size_t space, size_t *ce);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill a struct susp_info with the RR/SUSP entries needed for a given
|
||||||
|
* node.
|
||||||
|
*
|
||||||
|
* @param type
|
||||||
|
* 0 normal entry, 1 "." entry for that node (it is a dir), 2 ".."
|
||||||
|
* for that node (i.e., it will refer to the parent)
|
||||||
|
* @param space
|
||||||
|
* Available space in the System Use Area for the directory record.
|
||||||
|
* @param info
|
||||||
|
* Pointer to the struct susp_info where the entries will be stored.
|
||||||
|
* If some entries need to go to a Continuation Area, they will be added
|
||||||
|
* to the existing ce_susp_fields, and ce_len will be incremented
|
||||||
|
* propertly. Please ensure ce_block is initialized propertly.
|
||||||
|
*/
|
||||||
|
int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||||
|
size_t space, struct susp_info *info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the given SUSP fields into buf. Note that Continuation Area
|
||||||
|
* fields are not written.
|
||||||
|
* If info does not contain any SUSP entry this function just return.
|
||||||
|
* After written, the info susp_fields array will be freed, and the counters
|
||||||
|
* updated propertly.
|
||||||
|
*/
|
||||||
|
void rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info,
|
||||||
|
void *buf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the Continuation Area entries for the given struct susp_info, using
|
||||||
|
* the iso_write() function.
|
||||||
|
* After written, the ce_susp_fields array will be freed.
|
||||||
|
*/
|
||||||
|
int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info);
|
||||||
|
|
||||||
#endif /* LIBISO_ROCKRIDGE_H */
|
#endif /* LIBISO_ROCKRIDGE_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user