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 #include "ext2_fs.h" 28 #include "ext2fs.h" 29 30 struct get_pathname_struct { 31 ext2_ino_t search_ino; 32 ext2_ino_t parent; 33 char *name; 34 errcode_t errcode; 35 }; 36 37 #ifdef __TURBOC__ 38 #pragma argsused 39 #endif 40 static int get_pathname_proc(struct ext2_dir_entry *dirent, 41 int offset EXT2FS_ATTR((unused)), 42 int blocksize EXT2FS_ATTR((unused)), 43 char *buf EXT2FS_ATTR((unused)), 44 void *priv_data) 45 { 46 struct get_pathname_struct *gp; 47 errcode_t retval; 48 49 gp = (struct get_pathname_struct *) priv_data; 50 51 if (((dirent->name_len & 0xFF) == 2) && 52 !strncmp(dirent->name, "..", 2)) 53 gp->parent = dirent->inode; 54 if (dirent->inode == gp->search_ino) { 55 retval = ext2fs_get_mem((dirent->name_len & 0xFF) + 1, 56 &gp->name); 57 if (retval) { 58 gp->errcode = retval; 59 return DIRENT_ABORT; 60 } 61 strncpy(gp->name, dirent->name, (dirent->name_len & 0xFF)); 62 gp->name[dirent->name_len & 0xFF] = '\0'; 63 return DIRENT_ABORT; 64 } 65 return 0; 66 } 67 68 static errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ext2_ino_t dir, 69 ext2_ino_t ino, int maxdepth, 70 char *buf, char **name) 71 { 72 struct get_pathname_struct gp; 73 char *parent_name, *ret; 74 errcode_t retval; 75 76 if (dir == ino) { 77 retval = ext2fs_get_mem(2, name); 78 if (retval) 79 return retval; 80 strcpy(*name, (dir == EXT2_ROOT_INO) ? "/" : "."); 81 return 0; 82 } 83 84 if (!dir || (maxdepth < 0)) { 85 retval = ext2fs_get_mem(4, name); 86 if (retval) 87 return retval; 88 strcpy(*name, "..."); 89 return 0; 90 } 91 92 gp.search_ino = ino; 93 gp.parent = 0; 94 gp.name = 0; 95 gp.errcode = 0; 96 97 retval = ext2fs_dir_iterate(fs, dir, 0, buf, get_pathname_proc, &gp); 98 if (retval) 99 goto cleanup; 100 if (gp.errcode) { 101 retval = gp.errcode; 102 goto cleanup; 103 } 104 105 retval = ext2fs_get_pathname_int(fs, gp.parent, dir, maxdepth-1, 106 buf, &parent_name); 107 if (retval) 108 goto cleanup; 109 if (!ino) { 110 *name = parent_name; 111 return 0; 112 } 113 114 if (gp.name) 115 retval = ext2fs_get_mem(strlen(parent_name)+strlen(gp.name)+2, 116 &ret); 117 else 118 retval = ext2fs_get_mem(strlen(parent_name)+5, &ret); 119 if (retval) 120 goto cleanup; 121 122 ret[0] = 0; 123 if (parent_name[1]) 124 strcat(ret, parent_name); 125 strcat(ret, "/"); 126 if (gp.name) 127 strcat(ret, gp.name); 128 else 129 strcat(ret, "???"); 130 *name = ret; 131 ext2fs_free_mem(&parent_name); 132 retval = 0; 133 134 cleanup: 135 if (gp.name) 136 ext2fs_free_mem(&gp.name); 137 return retval; 138 } 139 140 errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino, 141 char **name) 142 { 143 char *buf; 144 errcode_t retval; 145 146 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 147 148 retval = ext2fs_get_mem(fs->blocksize, &buf); 149 if (retval) 150 return retval; 151 if (dir == ino) 152 ino = 0; 153 retval = ext2fs_get_pathname_int(fs, dir, ino, 32, buf, name); 154 ext2fs_free_mem(&buf); 155 return retval; 156 157 } 158