Function to read file contents from image.
This commit is contained in:
parent
33635c4e41
commit
282ffa9a98
109
src/fs_image.c
109
src/fs_image.c
@ -151,7 +151,7 @@ struct image_fs_data
|
|||||||
/**
|
/**
|
||||||
* - For regular files, number of bytes already read.
|
* - For regular files, number of bytes already read.
|
||||||
*/
|
*/
|
||||||
uint32_t offset;
|
off_t offset;
|
||||||
} data;
|
} data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -216,8 +216,20 @@ int ifs_lstat(IsoFileSource *src, struct stat *info)
|
|||||||
static
|
static
|
||||||
int ifs_stat(IsoFileSource *src, struct stat *info)
|
int ifs_stat(IsoFileSource *src, struct stat *info)
|
||||||
{
|
{
|
||||||
//TODO to implement
|
ImageFileSourceData *data;
|
||||||
return -1;
|
|
||||||
|
if (src == NULL || info == NULL || src->data == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = (ImageFileSourceData*)src->data;
|
||||||
|
|
||||||
|
if (S_ISLNK(data->info.st_mode)) {
|
||||||
|
/* TODO follow symlinks not supported yet */
|
||||||
|
return ISO_FILE_BAD_PATH;
|
||||||
|
}
|
||||||
|
*info = data->info;
|
||||||
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -382,8 +394,17 @@ int ifs_open(IsoFileSource *src)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
} else if (S_ISREG(data->info.st_mode)) {
|
} else if (S_ISREG(data->info.st_mode)) {
|
||||||
// TODO handle files
|
/* ensure fs is openned */
|
||||||
return ISO_FILE_ERROR;
|
ret = data->fs->open(data->fs);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
data->data.content = malloc(BLOCK_SIZE);
|
||||||
|
if (data->data.content == NULL) {
|
||||||
|
return ISO_MEM_ERROR;
|
||||||
|
}
|
||||||
|
data->data.offset = 0;
|
||||||
|
data->opened = 1;
|
||||||
} else {
|
} else {
|
||||||
/* symlinks and special files inside image can't be openned */
|
/* symlinks and special files inside image can't be openned */
|
||||||
return ISO_FILE_ERROR;
|
return ISO_FILE_ERROR;
|
||||||
@ -414,19 +435,91 @@ int ifs_close(IsoFileSource *src)
|
|||||||
child_list_free((struct child_list*) data->data.content);
|
child_list_free((struct child_list*) data->data.content);
|
||||||
data->data.content = NULL;
|
data->data.content = NULL;
|
||||||
data->opened = 0;
|
data->opened = 0;
|
||||||
|
} else if (data->opened == 1) {
|
||||||
|
/* close regular file */
|
||||||
|
free(data->data.content);
|
||||||
|
data->fs->close(data->fs);
|
||||||
|
data->data.content = NULL;
|
||||||
|
data->opened = 0;
|
||||||
} else {
|
} else {
|
||||||
// TODO handle files
|
/* TODO only dirs and files supported for now */
|
||||||
return ISO_ERROR;
|
return ISO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to read up to count bytes from the given source into
|
||||||
|
* the buffer starting at buf.
|
||||||
|
*
|
||||||
|
* The file src must be open() before calling this, and close() when no
|
||||||
|
* more needed. Not valid for dirs. On symlinks it reads the destination
|
||||||
|
* file.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* number of bytes read, 0 if EOF, < 0 on error
|
||||||
|
* Error codes:
|
||||||
|
* ISO_FILE_ERROR
|
||||||
|
* ISO_NULL_POINTER
|
||||||
|
* ISO_FILE_NOT_OPENNED
|
||||||
|
* ISO_FILE_IS_DIR
|
||||||
|
* ISO_MEM_ERROR
|
||||||
|
* ISO_INTERRUPTED
|
||||||
|
*/
|
||||||
static
|
static
|
||||||
int ifs_read(IsoFileSource *src, void *buf, size_t count)
|
int ifs_read(IsoFileSource *src, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
//TODO implement
|
int ret;
|
||||||
return -1;
|
ImageFileSourceData *data;
|
||||||
|
uint32_t read = 0;
|
||||||
|
|
||||||
|
if (src == NULL || src->data == NULL || buf == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
if (count == 0) {
|
||||||
|
return ISO_WRONG_ARG_VALUE;
|
||||||
|
}
|
||||||
|
data = (ImageFileSourceData*)src->data;
|
||||||
|
|
||||||
|
if (!data->opened) {
|
||||||
|
return ISO_FILE_NOT_OPENNED;
|
||||||
|
} else if (data->opened != 1) {
|
||||||
|
return ISO_FILE_IS_DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (read < count) {
|
||||||
|
size_t bytes;
|
||||||
|
uint8_t *orig;
|
||||||
|
|
||||||
|
if (data->data.offset % BLOCK_SIZE == 0) {
|
||||||
|
/* we need to buffer next block */
|
||||||
|
uint32_t block;
|
||||||
|
_ImageFsData *fsdata;
|
||||||
|
|
||||||
|
if (data->data.offset >= data->info.st_size) {
|
||||||
|
/* EOF */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fsdata = data->fs->fs.data;
|
||||||
|
block = data->block + (data->data.offset / BLOCK_SIZE);
|
||||||
|
ret = fsdata->src->read_block(fsdata->src, block,
|
||||||
|
data->data.content);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* how much can I read */
|
||||||
|
bytes = MIN(BLOCK_SIZE - (data->data.offset % BLOCK_SIZE),
|
||||||
|
count - read);
|
||||||
|
orig = data->data.content;
|
||||||
|
orig += data->data.offset % BLOCK_SIZE;
|
||||||
|
memcpy((uint8_t*)buf + read, orig, bytes);
|
||||||
|
read += bytes;
|
||||||
|
orig += bytes;
|
||||||
|
}
|
||||||
|
return read;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -246,6 +246,9 @@ int lfs_read(IsoFileSource *src, void *buf, size_t count)
|
|||||||
if (src == NULL || buf == NULL) {
|
if (src == NULL || buf == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
if (count == 0) {
|
||||||
|
return ISO_WRONG_ARG_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
data = src->data;
|
data = src->data;
|
||||||
switch (data->openned) {
|
switch (data->openned) {
|
||||||
|
@ -177,6 +177,7 @@ typedef struct IsoFileSource_Iface
|
|||||||
* ISO_FILE_ERROR
|
* ISO_FILE_ERROR
|
||||||
* ISO_NULL_POINTER
|
* ISO_NULL_POINTER
|
||||||
* ISO_FILE_NOT_OPENNED
|
* ISO_FILE_NOT_OPENNED
|
||||||
|
* ISO_WRONG_ARG_VALUE -> if count == 0
|
||||||
* ISO_FILE_IS_DIR
|
* ISO_FILE_IS_DIR
|
||||||
* ISO_MEM_ERROR
|
* ISO_MEM_ERROR
|
||||||
* ISO_INTERRUPTED
|
* ISO_INTERRUPTED
|
||||||
|
Loading…
Reference in New Issue
Block a user