get_pathname.c revision 544349270e4c74a6feb971123884a8cf5052a7ee
1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch/* 2c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * get_pathname.c --- do directry/inode -> name translation 3c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * 4c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * Copyright (C) 1993, 1994, 1995 Theodore Ts'o. 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * 6c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * %Begin-Header% 7c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * This file may be redistributed under the terms of the GNU Public 8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * License. 9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * %End-Header% 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * 11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * ext2fs_get_pathname(fs, dir, ino, name) 12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * 13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * This function translates takes two inode numbers into a 14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * string, placing the result in <name>. <dir> is the containing 15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * directory inode, and <ino> is the inode number itself. If 16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * <ino> is zero, then ext2fs_get_pathname will return pathname 17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * of the the directory <dir>. 18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * 19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch */ 20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <stdio.h> 22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <string.h> 23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if HAVE_UNISTD_H 24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <unistd.h> 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif 26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ext2_fs.h" 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "ext2fs.h" 29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstruct get_pathname_struct { 31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ext2_ino_t search_ino; 32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ext2_ino_t parent; 33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch char *name; 34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch errcode_t errcode; 35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}; 36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#ifdef __TURBOC__ 38 #pragma argsused 39#endif 40static 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 68static 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 134cleanup: 135 if (gp.name) 136 ext2fs_free_mem(&gp.name); 137 return retval; 138} 139 140errcode_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