minix/minix/fs/isofs/susp.c
David van Moolenbroek 0314acfb2d libminixfs: miscellaneous API cleanup
Mostly removal of unused parameters from calls.

Change-Id: I0eb7b568265d1669492d958e78b9e69d7cf6fc05
2015-08-14 18:39:00 +00:00

131 lines
3.2 KiB
C

/*
* This file contains support for System Use Sharing Protocol (SUSP) extension
* to ISO 9660.
*/
#include "inc.h"
#include <sys/stat.h>
int parse_susp(struct rrii_dir_record *dir, char *buffer)
{
/* Parse fundamental SUSP entries */
char susp_signature[2];
u8_t susp_length;
u8_t susp_version;
u32_t ca_block_nr;
u32_t ca_offset;
u32_t ca_length;
struct buf *ca_bp;
susp_signature[0] = buffer[0];
susp_signature[1] = buffer[1];
susp_length = *((u8_t*)buffer + 2);
susp_version = *((u8_t*)buffer + 3);
if ((susp_signature[0] == 'C') && (susp_signature[1] == 'E') &&
(susp_length >= 28) && (susp_version >= 1)) {
/*
* Continuation area, perform a recursion.
*
* FIXME: Currently we're parsing only first logical block of a
* continuation area, and infinite recursion is not checked.
*/
ca_block_nr = *((u32_t*)(buffer + 4));
ca_offset = *((u32_t*)(buffer + 12));
ca_length = *((u32_t*)(buffer + 20));
/* Truncate continuation area to fit one logical block. */
if (ca_offset >= v_pri.logical_block_size_l) {
return EINVAL;
}
if (ca_offset + ca_length > v_pri.logical_block_size_l) {
ca_length = v_pri.logical_block_size_l - ca_offset;
}
ca_bp = lmfs_get_block(fs_dev, ca_block_nr, NORMAL);
if (ca_bp == NULL) {
return EINVAL;
}
parse_susp_buffer(dir, b_data(ca_bp) + ca_offset, ca_length);
lmfs_put_block(ca_bp);
return OK;
}
else if ((susp_signature[0] == 'P') && (susp_signature[1] == 'D')) {
/* Padding, skip. */
return OK;
}
else if ((susp_signature[0] == 'S') && (susp_signature[1] == 'P')) {
/* Ignored, skip. */
return OK;
}
else if ((susp_signature[0] == 'S') && (susp_signature[1] == 'T')) {
/* Terminator entry, stop processing. */
return(ECANCELED);
}
else if ((susp_signature[0] == 'E') && (susp_signature[1] == 'R')) {
/* Ignored, skip. */
return OK;
}
else if ((susp_signature[0] == 'E') && (susp_signature[1] == 'S')) {
/* Ignored, skip. */
return OK;
}
/* Not a SUSP fundamental entry. */
return EINVAL;
}
void parse_susp_buffer(struct rrii_dir_record *dir, char *buffer, u32_t size)
{
/*
* Parse a SUSP system use entry for the ISO 9660.
* This is the main entry point for parsing SUSP data : SUSP entries are
* routed from here to the relevant handling functions.
*/
char susp_signature[2];
u8_t susp_length;
int parser_return;
while (TRUE) {
/* A SUSP entry can't be smaller than 4 bytes. */
if (size < 4)
return;
susp_signature[0] = buffer[0];
susp_signature[1] = buffer[1];
susp_length = *((u8_t*)buffer + 2);
/* Check if SUSP entry is present. */
if (((susp_signature[0] == 0) && (susp_signature[1] == 0)) ||
(susp_length > size) || (susp_length < 4))
return;
/* Check for SUSP fundamental entry. */
parser_return = parse_susp(dir, buffer);
if (parser_return == ECANCELED)
return;
else if (parser_return == OK)
goto next_entry;
/* Check for Rock Ridge entry. */
if (opt.norock == FALSE) {
parser_return = parse_susp_rock_ridge(dir, buffer);
if (parser_return == ECANCELED)
return;
else if (parser_return == OK)
goto next_entry;
}
/* Parse next SUSP entry. */
next_entry:
buffer += susp_length;
size -= susp_length;
}
}