Support for getting arbitrary file on image by path.
This commit is contained in:
parent
282ffa9a98
commit
2fada8eaa4
118
src/fs_image.c
118
src/fs_image.c
@ -18,6 +18,7 @@
|
|||||||
#include "rockridge.h"
|
#include "rockridge.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
@ -137,7 +138,7 @@ struct image_fs_data
|
|||||||
unsigned int opened : 2; /**< 0 not opened, 1 opened file, 2 opened dir */
|
unsigned int opened : 2; /**< 0 not opened, 1 opened file, 2 opened dir */
|
||||||
|
|
||||||
/* info for content reading */
|
/* info for content reading */
|
||||||
union
|
struct
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* - For regular files, once opened it points to a temporary data
|
* - For regular files, once opened it points to a temporary data
|
||||||
@ -488,7 +489,7 @@ int ifs_read(IsoFileSource *src, void *buf, size_t count)
|
|||||||
return ISO_FILE_IS_DIR;
|
return ISO_FILE_IS_DIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (read < count) {
|
while (read < count && data->data.offset < data->info.st_size) {
|
||||||
size_t bytes;
|
size_t bytes;
|
||||||
uint8_t *orig;
|
uint8_t *orig;
|
||||||
|
|
||||||
@ -513,11 +514,14 @@ int ifs_read(IsoFileSource *src, void *buf, size_t count)
|
|||||||
/* how much can I read */
|
/* how much can I read */
|
||||||
bytes = MIN(BLOCK_SIZE - (data->data.offset % BLOCK_SIZE),
|
bytes = MIN(BLOCK_SIZE - (data->data.offset % BLOCK_SIZE),
|
||||||
count - read);
|
count - read);
|
||||||
|
if (data->data.offset + (off_t)bytes > data->info.st_size) {
|
||||||
|
bytes = data->info.st_size - data->data.offset;
|
||||||
|
}
|
||||||
orig = data->data.content;
|
orig = data->data.content;
|
||||||
orig += data->data.offset % BLOCK_SIZE;
|
orig += data->data.offset % BLOCK_SIZE;
|
||||||
memcpy((uint8_t*)buf + read, orig, bytes);
|
memcpy((uint8_t*)buf + read, orig, bytes);
|
||||||
read += bytes;
|
read += bytes;
|
||||||
orig += bytes;
|
data->data.offset += (off_t)bytes;
|
||||||
}
|
}
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
@ -1051,11 +1055,115 @@ int ifs_get_root(IsoFilesystem *fs, IsoFileSource **root)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a file inside a node.
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* it is not modified if requested file is not found
|
||||||
|
* @return
|
||||||
|
* 1 success, 0 not found, < 0 error
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int ifs_get_file(IsoFileSource *dir, const char *name, IsoFileSource **file)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
IsoFileSource *src;
|
||||||
|
|
||||||
|
ret = iso_file_source_open(dir);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
while ((ret = iso_file_source_readdir(dir, &src)) == 1) {
|
||||||
|
char *fname = iso_file_source_get_name(src);
|
||||||
|
if (!strcmp(name, fname)) {
|
||||||
|
free(fname);
|
||||||
|
*file = src;
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(fname);
|
||||||
|
iso_file_source_unref(src);
|
||||||
|
}
|
||||||
|
iso_file_source_close(dir);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int ifs_get_by_path(IsoFilesystem *fs, const char *path, IsoFileSource **file)
|
int ifs_get_by_path(IsoFilesystem *fs, const char *path, IsoFileSource **file)
|
||||||
{
|
{
|
||||||
//TODO not implemented
|
int ret;
|
||||||
return -1;
|
_ImageFsData *data;
|
||||||
|
IsoFileSource *src;
|
||||||
|
char *ptr, *brk_info, *component;
|
||||||
|
|
||||||
|
if (fs == NULL || fs->data == NULL || path == NULL || file == NULL) {
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path[0] != '/') {
|
||||||
|
/* only absolute paths supported */
|
||||||
|
return ISO_FILE_BAD_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = (_ImageFsData*)fs->data;
|
||||||
|
|
||||||
|
/* open the filesystem */
|
||||||
|
ret = ifs_fs_open((IsoImageFilesystem*)fs);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ifs_get_root(fs, &src);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (!strcmp(path, "/")) {
|
||||||
|
/* we are looking for root */
|
||||||
|
*file = src;
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
goto get_path_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = strdup(path);
|
||||||
|
if (ptr == NULL) {
|
||||||
|
iso_file_source_unref(src);
|
||||||
|
ret = ISO_MEM_ERROR;
|
||||||
|
goto get_path_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
component = strtok_r(ptr, "/", &brk_info);
|
||||||
|
while (component) {
|
||||||
|
IsoFileSource *child = NULL;
|
||||||
|
|
||||||
|
ImageFileSourceData *fdata;
|
||||||
|
fdata = src->data;
|
||||||
|
if (!S_ISDIR(fdata->info.st_mode)) {
|
||||||
|
ret = ISO_FILE_BAD_PATH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ifs_get_file(src, component, &child);
|
||||||
|
iso_file_source_unref(src);
|
||||||
|
if (ret <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
src = child;
|
||||||
|
component = strtok_r(NULL, "/", &brk_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ptr);
|
||||||
|
if (ret < 0) {
|
||||||
|
iso_file_source_unref(src);
|
||||||
|
} else if (ret == 0) {
|
||||||
|
ret = ISO_FILE_DOESNT_EXIST;
|
||||||
|
} else {
|
||||||
|
*file = src;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_path_exit:;
|
||||||
|
ifs_fs_close((IsoImageFilesystem*)fs);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ifs_get_id(IsoFilesystem *fs)
|
unsigned int ifs_get_id(IsoFilesystem *fs)
|
||||||
|
@ -41,6 +41,13 @@ struct Iso_Filesystem
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* 1 success, < 0 error
|
* 1 success, < 0 error
|
||||||
|
* Error codes:
|
||||||
|
* ISO_FILE_ACCESS_DENIED
|
||||||
|
* ISO_FILE_BAD_PATH
|
||||||
|
* ISO_FILE_DOESNT_EXIST
|
||||||
|
* ISO_MEM_ERROR
|
||||||
|
* ISO_FILE_ERROR
|
||||||
|
* ISO_NULL_POINTER
|
||||||
*/
|
*/
|
||||||
int (*get_by_path)(IsoFilesystem *fs, const char *path,
|
int (*get_by_path)(IsoFilesystem *fs, const char *path,
|
||||||
IsoFileSource **file);
|
IsoFileSource **file);
|
||||||
|
Loading…
Reference in New Issue
Block a user