13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/* 23839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * get_pathname.c --- do directry/inode -> name translation 3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 419c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * Copyright (C) 1993, 1994, 1995 Theodore Ts'o. 519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * 619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %Begin-Header% 7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library 8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2. 919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %End-Header% 10543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o */ 11543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o 12543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o/* 1319c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * 1419c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * ext2fs_get_pathname(fs, dir, ino, name) 1519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * 1619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * This function translates takes two inode numbers into a 1719c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * string, placing the result in <name>. <dir> is the containing 1819c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * directory inode, and <ino> is the inode number itself. If 1919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * <ino> is zero, then ext2fs_get_pathname will return pathname 2019c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * of the the directory <dir>. 21efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h> 253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <string.h> 264cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#if HAVE_UNISTD_H 273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h> 284cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#endif 29f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 30b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h" 313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "ext2fs.h" 323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostruct get_pathname_struct { 3431dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o ext2_ino_t search_ino; 3531dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o ext2_ino_t parent; 363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o char *name; 373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o errcode_t errcode; 383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}; 393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 404cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#ifdef __TURBOC__ 4131dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o #pragma argsused 424cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#endif 433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic int get_pathname_proc(struct ext2_dir_entry *dirent, 44544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o int offset EXT2FS_ATTR((unused)), 45544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o int blocksize EXT2FS_ATTR((unused)), 46544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o char *buf EXT2FS_ATTR((unused)), 47b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o void *priv_data) 483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o struct get_pathname_struct *gp; 507b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o errcode_t retval; 513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 52b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o gp = (struct get_pathname_struct *) priv_data; 533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 54674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o if (((dirent->name_len & 0xFF) == 2) && 553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o !strncmp(dirent->name, "..", 2)) 563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o gp->parent = dirent->inode; 573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (dirent->inode == gp->search_ino) { 58674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o retval = ext2fs_get_mem((dirent->name_len & 0xFF) + 1, 59c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o &gp->name); 602eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o if (retval) { 612eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o gp->errcode = retval; 623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return DIRENT_ABORT; 633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 64674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o strncpy(gp->name, dirent->name, (dirent->name_len & 0xFF)); 65674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o gp->name[dirent->name_len & 0xFF] = '\0'; 663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return DIRENT_ABORT; 673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return 0; 693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 71efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ostatic errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ext2_ino_t dir, 72efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o ext2_ino_t ino, int maxdepth, 7331dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o char *buf, char **name) 743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o struct get_pathname_struct gp; 76e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall char *parent_name = 0, *ret; 773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o errcode_t retval; 783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (dir == ino) { 80c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o retval = ext2fs_get_mem(2, name); 817b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o if (retval) 827b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o return retval; 833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o strcpy(*name, (dir == EXT2_ROOT_INO) ? "/" : "."); 843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return 0; 853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (!dir || (maxdepth < 0)) { 88c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o retval = ext2fs_get_mem(4, name); 897b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o if (retval) 907b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o return retval; 913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o strcpy(*name, "..."); 923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return 0; 933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o gp.search_ino = ino; 963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o gp.parent = 0; 973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o gp.name = 0; 983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o gp.errcode = 0; 99efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 1003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = ext2fs_dir_iterate(fs, dir, 0, buf, get_pathname_proc, &gp); 101e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (retval == EXT2_ET_NO_DIRECTORY) { 102e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall char tmp[32]; 103e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 104e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (ino) 105e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall snprintf(tmp, sizeof(tmp), "<%u>/<%u>", dir, ino); 106e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall else 107e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall snprintf(tmp, sizeof(tmp), "<%u>", dir); 108e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = ext2fs_get_mem(strlen(tmp)+1, name); 109e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (retval) 110e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall goto cleanup; 111e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall strcpy(*name, tmp); 112e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return 0; 113e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } else if (retval) 1143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o goto cleanup; 1153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (gp.errcode) { 1163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = gp.errcode; 1173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o goto cleanup; 1183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 1203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = ext2fs_get_pathname_int(fs, gp.parent, dir, maxdepth-1, 1213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o buf, &parent_name); 1223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) 1233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o goto cleanup; 1243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (!ino) { 1253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *name = parent_name; 1263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return 0; 1273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 128efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 129efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o if (gp.name) 1307b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o retval = ext2fs_get_mem(strlen(parent_name)+strlen(gp.name)+2, 131c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o &ret); 132f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o else 133c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o retval = ext2fs_get_mem(strlen(parent_name)+5, &ret); 1347b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o if (retval) 1353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o goto cleanup; 136efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 1373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o ret[0] = 0; 1383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (parent_name[1]) 1393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o strcat(ret, parent_name); 1403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o strcat(ret, "/"); 1413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (gp.name) 1423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o strcat(ret, gp.name); 1433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o else 1443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o strcat(ret, "???"); 1453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *name = ret; 1463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = 0; 147efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 1483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ocleanup: 149e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_free_mem(&parent_name); 150e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_free_mem(&gp.name); 1513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return retval; 1523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 1533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 15431dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'oerrcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino, 1553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o char **name) 1563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 1573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o char *buf; 1583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o errcode_t retval; 1593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 160f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 161f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 162c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o retval = ext2fs_get_mem(fs->blocksize, &buf); 1637b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o if (retval) 1647b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o return retval; 1653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (dir == ino) 1663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o ino = 0; 1673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = ext2fs_get_pathname_int(fs, dir, ino, 32, buf, name); 168c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o ext2fs_free_mem(&buf); 1693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return retval; 170efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 1713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 172