New API call iso_tree_resolve_symlink().
This commit is contained in:
parent
2c88e74798
commit
7a8995f322
@ -5059,6 +5059,37 @@ int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node);
|
|||||||
*/
|
*/
|
||||||
char *iso_tree_get_node_path(IsoNode *node);
|
char *iso_tree_get_node_path(IsoNode *node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the destination node of a symbolic link within the IsoImage.
|
||||||
|
*
|
||||||
|
* @param img
|
||||||
|
* The image wherein to try resolving the link.
|
||||||
|
* @param sym
|
||||||
|
* The symbolic link node which to resolve.
|
||||||
|
* @param res
|
||||||
|
* Will return the found destination node, in case of success.
|
||||||
|
* Call iso_node_ref() / iso_node_unref() if you intend to use the node
|
||||||
|
* over API calls which might in any event delete it.
|
||||||
|
* @param depth
|
||||||
|
* Prevents endless loops. Submit as 0.
|
||||||
|
* @param flag
|
||||||
|
* Bitfield for control purposes. Submit 0 for now.
|
||||||
|
* @return
|
||||||
|
* 1 on success,
|
||||||
|
* < 0 on failure, especially ISO_DEEP_SYMLINK and ISO_DEAD_SYMLINK
|
||||||
|
*
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
int iso_tree_resolve_symlink(IsoImage *img, IsoSymlink *sym, IsoNode **res,
|
||||||
|
int *depth, int flag);
|
||||||
|
|
||||||
|
/* Maximum number link resolution steps before ISO_DEEP_SYMLINK gets
|
||||||
|
* returned by iso_tree_resolve_symlink().
|
||||||
|
*
|
||||||
|
* @since 1.2.4
|
||||||
|
*/
|
||||||
|
#define LIBISO_MAX_LINK_DEPTH 100
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increments the reference counting of the given IsoDataSource.
|
* Increments the reference counting of the given IsoDataSource.
|
||||||
*
|
*
|
||||||
@ -7373,6 +7404,12 @@ int iso_image_hfsplus_get_blessed(IsoImage *img, IsoNode ***blessed_nodes,
|
|||||||
/** Name collision in HFS+, mangling not possible (FAILURE, HIGH, -393) */
|
/** Name collision in HFS+, mangling not possible (FAILURE, HIGH, -393) */
|
||||||
#define ISO_HFSP_NO_MANGLE 0xE830FE77
|
#define ISO_HFSP_NO_MANGLE 0xE830FE77
|
||||||
|
|
||||||
|
/** Symbolic link cannot be resolved (FAILURE, HIGH, -394) */
|
||||||
|
#define ISO_DEAD_SYMLINK 0xE830FE76
|
||||||
|
|
||||||
|
/** Too many chained symbolic links (FAILURE, HIGH, -395) */
|
||||||
|
#define ISO_DEEP_SYMLINK 0xE830FE75
|
||||||
|
|
||||||
|
|
||||||
/* Internal developer note:
|
/* Internal developer note:
|
||||||
Place new error codes directly above this comment.
|
Place new error codes directly above this comment.
|
||||||
|
@ -257,6 +257,7 @@ iso_tree_get_node_path;
|
|||||||
iso_tree_get_replace_mode;
|
iso_tree_get_replace_mode;
|
||||||
iso_tree_path_to_node;
|
iso_tree_path_to_node;
|
||||||
iso_tree_remove_exclude;
|
iso_tree_remove_exclude;
|
||||||
|
iso_tree_resolve_symlink;
|
||||||
iso_tree_set_follow_symlinks;
|
iso_tree_set_follow_symlinks;
|
||||||
iso_tree_set_ignore_hidden;
|
iso_tree_set_ignore_hidden;
|
||||||
iso_tree_set_ignore_special;
|
iso_tree_set_ignore_special;
|
||||||
|
@ -496,6 +496,10 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
return "APM block size prevents coexistence with GPT";
|
return "APM block size prevents coexistence with GPT";
|
||||||
case ISO_HFSP_NO_MANGLE:
|
case ISO_HFSP_NO_MANGLE:
|
||||||
return "Name collision in HFS+, mangling not possible";
|
return "Name collision in HFS+, mangling not possible";
|
||||||
|
case ISO_DEAD_SYMLINK:
|
||||||
|
return "Symbolic link cannot be resolved";
|
||||||
|
case ISO_DEEP_SYMLINK:
|
||||||
|
return "Too many chained symbolic links";
|
||||||
default:
|
default:
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
}
|
}
|
||||||
|
@ -1196,3 +1196,84 @@ int iso_tree_clone(IsoNode *node,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int iso_tree_resolve_symlink(IsoImage *img, IsoSymlink *sym, IsoNode **res,
|
||||||
|
int *depth, int flag)
|
||||||
|
{
|
||||||
|
IsoDir *cur_dir = NULL;
|
||||||
|
IsoNode *n, *resolved_node;
|
||||||
|
char *dest, *dest_start, *dest_end;
|
||||||
|
int ret = 0;
|
||||||
|
unsigned int comp_len, dest_len;
|
||||||
|
|
||||||
|
dest = sym->dest;
|
||||||
|
dest_len = strlen(dest);
|
||||||
|
|
||||||
|
if (dest[0] == '/') {
|
||||||
|
|
||||||
|
/* >>> ??? How to resolve absolute links without knowing the
|
||||||
|
path of the future mount point ?
|
||||||
|
??? Would it be better to throw error ?
|
||||||
|
I can only assume that it gets mounted at / during some stage
|
||||||
|
of booting.
|
||||||
|
*/;
|
||||||
|
|
||||||
|
cur_dir = img->root;
|
||||||
|
dest_end = dest;
|
||||||
|
} else {
|
||||||
|
cur_dir = sym->node.parent;
|
||||||
|
if (cur_dir == NULL)
|
||||||
|
cur_dir = img->root;
|
||||||
|
dest_end = dest - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (dest_end < dest + dest_len) {
|
||||||
|
dest_start = dest_end + 1;
|
||||||
|
dest_end = strchr(dest_start, '/');
|
||||||
|
if (dest_end == NULL)
|
||||||
|
dest_end = dest_start + strlen(dest_start);
|
||||||
|
comp_len = dest_end - dest_start;
|
||||||
|
if (comp_len == 0 || (comp_len == 1 && dest_start[0] == '.'))
|
||||||
|
continue;
|
||||||
|
if (comp_len == 2 && dest_start[0] == '.' && dest_start[1] == '.') {
|
||||||
|
cur_dir = cur_dir->node.parent;
|
||||||
|
if (cur_dir == NULL) /* link shoots over root */
|
||||||
|
return ISO_DEAD_SYMLINK;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search node in cur_dir */
|
||||||
|
for (n = cur_dir->children; n != NULL; n = n->next)
|
||||||
|
if (strncmp(dest_start, n->name, comp_len) == 0 &&
|
||||||
|
strlen(n->name) == comp_len)
|
||||||
|
break;
|
||||||
|
if (n == NULL)
|
||||||
|
return ISO_DEAD_SYMLINK;
|
||||||
|
|
||||||
|
if (n->type == LIBISO_DIR) {
|
||||||
|
cur_dir = (IsoDir *) n;
|
||||||
|
} else if (n->type == LIBISO_SYMLINK) {
|
||||||
|
if (*depth >= LIBISO_MAX_LINK_DEPTH)
|
||||||
|
return ISO_DEEP_SYMLINK;
|
||||||
|
(*depth)++;
|
||||||
|
ret = iso_tree_resolve_symlink(img, (IsoSymlink *) n,
|
||||||
|
&resolved_node, depth, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
if (resolved_node->type != LIBISO_DIR) {
|
||||||
|
n = resolved_node;
|
||||||
|
goto leaf_type;
|
||||||
|
}
|
||||||
|
cur_dir = (IsoDir *) resolved_node;
|
||||||
|
} else {
|
||||||
|
leaf_type:;
|
||||||
|
if (dest_end < dest + dest_len) /* attempt to dive into file */
|
||||||
|
return ISO_DEAD_SYMLINK;
|
||||||
|
*res = n;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*res = cur_dir;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user