get_pathname.c revision 31dbecd482405e0d3a67eb58e1a1c8cb9f2ad83e
1/* 2 * get_pathname.c --- do directry/inode -> name translation 3 * 4 * Copyright (C) 1993, 1994, 1995 Theodore Ts'o. 5 * 6 * %Begin-Header% 7 * This file may be redistributed under the terms of the GNU Public 8 * License. 9 * %End-Header% 10 * 11 * ext2fs_get_pathname(fs, dir, ino, name) 12 * 13 * This function translates takes two inode numbers into a 14 * string, placing the result in <name>. <dir> is the containing 15 * directory inode, and <ino> is the inode number itself. If 16 * <ino> is zero, then ext2fs_get_pathname will return pathname 17 * of the the directory <dir>. 18 * 19 */ 20 21#include <stdio.h> 22#include <string.h> 23#if HAVE_UNISTD_H 24#include <unistd.h> 25#endif 26 27#if EXT2_FLAT_INCLUDES 28#include "ext2_fs.h" 29#else 30#include <linux/ext2_fs.h> 31#endif 32 33#include "ext2fs.h" 34 35struct get_pathname_struct { 36 ext2_ino_t search_ino; 37 ext2_ino_t parent; 38 char *name; 39 errcode_t errcode; 40}; 41 42#ifdef __TURBOC__ 43 #pragma argsused 44#endif 45static int get_pathname_proc(struct ext2_dir_entry *dirent, 46 int offset, 47 int blocksize, 48 char *buf, 49 void *priv_data) 50{ 51 struct get_pathname_struct *gp; 52 errcode_t retval; 53 54 gp = (struct get_pathname_struct *) priv_data; 55 56 if (((dirent->name_len & 0xFF) == 2) && 57 !strncmp(dirent->name, "..", 2)) 58 gp->parent = dirent->inode; 59 if (dirent->inode == gp->search_ino) { 60 retval = ext2fs_get_mem((dirent->name_len & 0xFF) + 1, 61 (void **) &gp->name); 62 if (retval) { 63 gp->errcode = retval; 64 return DIRENT_ABORT; 65 } 66 strncpy(gp->name, dirent->name, (dirent->name_len & 0xFF)); 67 gp->name[dirent->name_len & 0xFF] = '\0'; 68 return DIRENT_ABORT; 69 } 70 return 0; 71} 72 73static errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ext2_ino_t dir, 74 ext2_ino_t ino, int maxdepth, 75 char *buf, char **name) 76{ 77 struct get_pathname_struct gp; 78 char *parent_name, *ret; 79 errcode_t retval; 80 81 if (dir == ino) { 82 retval = ext2fs_get_mem(2, (void **)name); 83 if (retval) 84 return retval; 85 strcpy(*name, (dir == EXT2_ROOT_INO) ? "/" : "."); 86 return 0; 87 } 88 89 if (!dir || (maxdepth < 0)) { 90 retval = ext2fs_get_mem(4, (void **)name); 91 if (retval) 92 return retval; 93 strcpy(*name, "..."); 94 return 0; 95 } 96 97 gp.search_ino = ino; 98 gp.parent = 0; 99 gp.name = 0; 100 gp.errcode = 0; 101 102 retval = ext2fs_dir_iterate(fs, dir, 0, buf, get_pathname_proc, &gp); 103 if (retval) 104 goto cleanup; 105 if (gp.errcode) { 106 retval = gp.errcode; 107 goto cleanup; 108 } 109 110 retval = ext2fs_get_pathname_int(fs, gp.parent, dir, maxdepth-1, 111 buf, &parent_name); 112 if (retval) 113 goto cleanup; 114 if (!ino) { 115 *name = parent_name; 116 return 0; 117 } 118 119 if (gp.name) 120 retval = ext2fs_get_mem(strlen(parent_name)+strlen(gp.name)+2, 121 (void **) &ret); 122 else 123 retval = ext2fs_get_mem(strlen(parent_name)+5, 124 (void **) &ret); 125 if (retval) 126 goto cleanup; 127 128 ret[0] = 0; 129 if (parent_name[1]) 130 strcat(ret, parent_name); 131 strcat(ret, "/"); 132 if (gp.name) 133 strcat(ret, gp.name); 134 else 135 strcat(ret, "???"); 136 *name = ret; 137 ext2fs_free_mem((void **) &parent_name); 138 retval = 0; 139 140cleanup: 141 if (gp.name) 142 ext2fs_free_mem((void **) &gp.name); 143 return retval; 144} 145 146errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino, 147 char **name) 148{ 149 char *buf; 150 errcode_t retval; 151 152 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 153 154 retval = ext2fs_get_mem(fs->blocksize, (void **) &buf); 155 if (retval) 156 return retval; 157 if (dir == ino) 158 ino = 0; 159 retval = ext2fs_get_pathname_int(fs, dir, ino, 32, buf, name); 160 ext2fs_free_mem((void **) &buf); 161 return retval; 162 163} 164