summaryrefslogtreecommitdiffstats
path: root/tools/lib/h5trav.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib/h5trav.c')
-rw-r--r--tools/lib/h5trav.c143
1 files changed, 138 insertions, 5 deletions
diff --git a/tools/lib/h5trav.c b/tools/lib/h5trav.c
index 287af29..5195261 100644
--- a/tools/lib/h5trav.c
+++ b/tools/lib/h5trav.c
@@ -292,7 +292,7 @@ traverse(hid_t file_id, const char *grp_name, hbool_t visit_start,
*
*-------------------------------------------------------------------------
*/
-static void
+void
trav_info_add(trav_info_t *info, const char *path, h5trav_type_t obj_type)
{
size_t idx; /* Index of address to use */
@@ -323,7 +323,7 @@ trav_info_add(trav_info_t *info, const char *path, h5trav_type_t obj_type)
*
*-------------------------------------------------------------------------
*/
-static int
+int
trav_info_visit_obj(const char *path, const H5O_info_t *oinfo,
const char UNUSED *already_visited, void *udata)
{
@@ -348,7 +348,7 @@ trav_info_visit_obj(const char *path, const H5O_info_t *oinfo,
*
*-------------------------------------------------------------------------
*/
-static int
+int
trav_info_visit_lnk(const char *path, const H5L_info_t *linfo, void *udata)
{
/* Add the link to the 'info' struct */
@@ -438,14 +438,21 @@ h5trav_getindex(const trav_info_t *info, const char *obj)
*/
void
-trav_info_init(trav_info_t **_info)
+trav_info_init(const char *filename, hid_t fileid, trav_info_t **_info)
{
trav_info_t *info = (trav_info_t *)HDmalloc(sizeof(trav_info_t));
/* Init info structure */
info->nused = info->nalloc = 0;
info->paths = NULL;
-
+ info->fname = filename;
+ info->fid = fileid;
+
+ /* Initialize list of visited symbolic links */
+ info->symlink_visited.nused = 0;
+ info->symlink_visited.nalloc = 0;
+ info->symlink_visited.objs = NULL;
+ info->symlink_visited.dangle_link = FALSE;
*_info = info;
} /* end trav_info_init() */
@@ -464,6 +471,16 @@ trav_info_free(trav_info_t *info)
size_t u; /* Local index variable */
if(info) {
+ /* Free visited symbolic links path and file (if alloc) */
+ for(u=0; u < info->symlink_visited.nused; u++)
+ {
+ if (info->symlink_visited.objs[u].file)
+ HDfree(info->symlink_visited.objs[u].file);
+
+ HDfree(info->symlink_visited.objs[u].path);
+ }
+ HDfree(info->symlink_visited.objs);
+
/* Free path names */
for(u = 0; u < info->nused; u++)
HDfree(info->paths[u].path);
@@ -973,3 +990,119 @@ h5trav_visit(hid_t fid, const char *grp_name, hbool_t visit_start,
return 0;
}
+/*-------------------------------------------------------------------------
+ * Function: symlink_visit_add
+ *
+ * Purpose: Add an symbolic link to visited data structure
+ *
+ * Return: 0 on success, -1 on failure
+ *
+ * Programmer: Neil Fortner, nfortne2@hdfgroup.org
+ * Adapted from trav_addr_add in h5trav.c by Quincey Koziol
+ *
+ * Date: September 5, 2008
+ *
+ * Modified:
+ * Jonathan Kim
+ * - Moved from h5ls.c to share among tools. (Sep 16, 2010)
+ * - Renamed from elink_trav_add to symlink_visit_add for both soft and
+ * external links. (May 25, 2010)
+ * - Add type parameter to distingush between soft and external link for
+ * sure, which prevent from mixing up visited link when the target names
+ * are same between the soft and external link, as code marks with the
+ * target name. (May 25,2010)
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+symlink_visit_add(symlink_trav_t *visited, H5L_type_t type, const char *file, const char *path)
+{
+ size_t idx; /* Index of address to use */
+ void *tmp_ptr;
+
+ /* Allocate space if necessary */
+ if(visited->nused == visited->nalloc)
+ {
+ visited->nalloc = MAX(1, visited->nalloc * 2);
+ if(NULL == (tmp_ptr = HDrealloc(visited->objs, visited->nalloc * sizeof(visited->objs[0]))))
+ return -1;
+ visited->objs = tmp_ptr;
+ } /* end if */
+
+ /* Append it */
+ idx = visited->nused++;
+
+ visited->objs[idx].type = type;
+ visited->objs[idx].file = NULL;
+ visited->objs[idx].path = NULL;
+
+ if (type == H5L_TYPE_EXTERNAL)
+ {
+ if(NULL == (visited->objs[idx].file = HDstrdup(file)))
+ {
+ visited->nused--;
+ return -1;
+ }
+ }
+
+ if(NULL == (visited->objs[idx].path = HDstrdup(path)))
+ {
+ visited->nused--;
+ if (visited->objs[idx].file)
+ HDfree (visited->objs[idx].file);
+ return -1;
+ }
+
+ return 0;
+} /* end symlink_visit_add() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: symlink_is_visited
+ *
+ * Purpose: Check if an symbolic link has already been visited
+ *
+ * Return: TRUE/FALSE
+ *
+ * Programmer: Neil Fortner, nfortne2@hdfgroup.org
+ * Adapted from trav_addr_visited in h5trav.c by Quincey Koziol
+ *
+ * Date: September 5, 2008
+ *
+ * Modified:
+ * Jonathan Kim
+ * - Moved from h5ls.c to share among tools. (Sep 16, 2010)
+ * - Renamed from elink_trav_visited to symlink_is_visited for both soft and
+ * external links. (May 25, 2010)
+ * - Add type parameter to distingush between soft and external link for
+ * sure, which prevent from mixing up visited link when the target names
+ * are same between the soft and external link, as code marks with the
+ * target name. (May 25,2010)
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+symlink_is_visited(symlink_trav_t *visited, H5L_type_t type, const char *file, const char *path)
+{
+ size_t u; /* Local index variable */
+
+ /* Look for symlink */
+ for(u = 0; u < visited->nused; u++)
+ {
+ /* Check for symlink values already in array */
+ /* check type and path pair to distingush between symbolic links */
+ if ((visited->objs[u].type == type) && !HDstrcmp(visited->objs[u].path, path))
+ {
+ /* if external link, file need to be matched as well */
+ if (visited->objs[u].type == H5L_TYPE_EXTERNAL)
+ {
+ if (!HDstrcmp(visited->objs[u].file, file))
+ return (TRUE);
+ }
+ return (TRUE);
+ }
+ }
+ /* Didn't find symlink */
+ return(FALSE);
+} /* end symlink_is_visited() */
+