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