From d1e063beb43e595680c65e3804d1f8ddff53373b Mon Sep 17 00:00:00 2001 From: Guido Guenther Date: Sat, 18 Nov 2006 23:48:07 +0100 Subject: Imported Debian version 0.3.8.8 --- e2fslib/get_pathname.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 e2fslib/get_pathname.c (limited to 'e2fslib/get_pathname.c') diff --git a/e2fslib/get_pathname.c b/e2fslib/get_pathname.c new file mode 100644 index 0000000..e218f2e --- /dev/null +++ b/e2fslib/get_pathname.c @@ -0,0 +1,158 @@ +/* + * get_pathname.c --- do directry/inode -> name translation + * + * Copyright (C) 1993, 1994, 1995 Theodore Ts'o. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + * + * ext2fs_get_pathname(fs, dir, ino, name) + * + * This function translates takes two inode numbers into a + * string, placing the result in . is the containing + * directory inode, and is the inode number itself. If + * is zero, then ext2fs_get_pathname will return pathname + * of the the directory . + * + */ + +#include +#include +#if HAVE_UNISTD_H +#include +#endif + +#include "ext2_fs.h" +#include "ext2fs.h" + +struct get_pathname_struct { + ext2_ino_t search_ino; + ext2_ino_t parent; + char *name; + errcode_t errcode; +}; + +#ifdef __TURBOC__ + #pragma argsused +#endif +static int get_pathname_proc(struct ext2_dir_entry *dirent, + int offset, + int blocksize, + char *buf, + void *priv_data) +{ + struct get_pathname_struct *gp; + errcode_t retval; + + gp = (struct get_pathname_struct *) priv_data; + + if (((dirent->name_len & 0xFF) == 2) && + !strncmp(dirent->name, "..", 2)) + gp->parent = dirent->inode; + if (dirent->inode == gp->search_ino) { + retval = ext2fs_get_mem((dirent->name_len & 0xFF) + 1, + (void **) &gp->name); + if (retval) { + gp->errcode = retval; + return DIRENT_ABORT; + } + strncpy(gp->name, dirent->name, (dirent->name_len & 0xFF)); + gp->name[dirent->name_len & 0xFF] = '\0'; + return DIRENT_ABORT; + } + return 0; +} + +static errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ext2_ino_t dir, + ext2_ino_t ino, int maxdepth, + char *buf, char **name) +{ + struct get_pathname_struct gp; + char *parent_name, *ret; + errcode_t retval; + + if (dir == ino) { + retval = ext2fs_get_mem(2, (void **)name); + if (retval) + return retval; + strcpy(*name, (dir == EXT2_ROOT_INO) ? "/" : "."); + return 0; + } + + if (!dir || (maxdepth < 0)) { + retval = ext2fs_get_mem(4, (void **)name); + if (retval) + return retval; + strcpy(*name, "..."); + return 0; + } + + gp.search_ino = ino; + gp.parent = 0; + gp.name = 0; + gp.errcode = 0; + + retval = ext2fs_dir_iterate(fs, dir, 0, buf, get_pathname_proc, &gp); + if (retval) + goto cleanup; + if (gp.errcode) { + retval = gp.errcode; + goto cleanup; + } + + retval = ext2fs_get_pathname_int(fs, gp.parent, dir, maxdepth-1, + buf, &parent_name); + if (retval) + goto cleanup; + if (!ino) { + *name = parent_name; + return 0; + } + + if (gp.name) + retval = ext2fs_get_mem(strlen(parent_name)+strlen(gp.name)+2, + (void **) &ret); + else + retval = ext2fs_get_mem(strlen(parent_name)+5, + (void **) &ret); + if (retval) + goto cleanup; + + ret[0] = 0; + if (parent_name[1]) + strcat(ret, parent_name); + strcat(ret, "/"); + if (gp.name) + strcat(ret, gp.name); + else + strcat(ret, "???"); + *name = ret; + ext2fs_free_mem((void **) &parent_name); + retval = 0; + +cleanup: + if (gp.name) + ext2fs_free_mem((void **) &gp.name); + return retval; +} + +errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino, + char **name) +{ + char *buf; + errcode_t retval; + + EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); + + retval = ext2fs_get_mem(fs->blocksize, (void **) &buf); + if (retval) + return retval; + if (dir == ino) + ino = 0; + retval = ext2fs_get_pathname_int(fs, dir, ino, 32, buf, name); + ext2fs_free_mem((void **) &buf); + return retval; + +} -- cgit v1.2.3