Whamcloud - gitweb
libext2fs: add gnu.translator support
[tools/e2fsprogs.git] / lib / ext2fs / get_pathname.c
index f4f6db7..8cfaf6e 100644 (file)
@@ -1,12 +1,15 @@
 /*
- * get_pathname.c --- do directry/inode -> name translation
- * 
+ * get_pathname.c --- do directory/inode -> name translation
+ *
  * Copyright (C) 1993, 1994, 1995 Theodore Ts'o.
  *
  * %Begin-Header%
- * This file may be redistributed under the terms of the GNU Public
- * License.
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
  * %End-Header%
+ */
+
+/*
  *
  *     ext2fs_get_pathname(fs, dir, ino, name)
  *
  *     directory inode, and <ino> is the inode number itself.  If
  *     <ino> is zero, then ext2fs_get_pathname will return pathname
  *     of the the directory <dir>.
- * 
+ *
  */
 
+#include "config.h"
 #include <stdio.h>
 #include <string.h>
 #if HAVE_UNISTD_H
 #include <unistd.h>
 #endif
-#include <stdlib.h>
-
-#include <linux/ext2_fs.h>
 
+#include "ext2_fs.h"
 #include "ext2fs.h"
 
 struct get_pathname_struct {
-       ino_t           search_ino;
-       ino_t           parent;
+       ext2_ino_t      search_ino;
+       ext2_ino_t      parent;
        char            *name;
        errcode_t       errcode;
 };
 
 #ifdef __TURBOC__
-#pragma argsused
+ #pragma argsused
 #endif
 static int get_pathname_proc(struct ext2_dir_entry *dirent,
-                            int        offset,
-                            int        blocksize,
-                            char       *buf,
-                            void       *private)
+                            int        offset EXT2FS_ATTR((unused)),
+                            int        blocksize EXT2FS_ATTR((unused)),
+                            char       *buf EXT2FS_ATTR((unused)),
+                            void       *priv_data)
 {
        struct get_pathname_struct      *gp;
+       errcode_t                       retval;
+       int name_len = ext2fs_dirent_name_len(dirent);
 
-       gp = (struct get_pathname_struct *) private;
+       gp = (struct get_pathname_struct *) priv_data;
 
-       if ((dirent->name_len == 2) &&
-           !strncmp(dirent->name, "..", 2))
+       if ((name_len == 2) && !strncmp(dirent->name, "..", 2))
                gp->parent = dirent->inode;
        if (dirent->inode == gp->search_ino) {
-               gp->name = malloc(dirent->name_len + 1);
-               if (!gp->name) {
-                       gp->errcode = EXT2_NO_MEMORY;
+               retval = ext2fs_get_mem(name_len + 1, &gp->name);
+               if (retval) {
+                       gp->errcode = retval;
                        return DIRENT_ABORT;
                }
-               strncpy(gp->name, dirent->name, dirent->name_len);
-               gp->name[dirent->name_len] = '\0';
+               strncpy(gp->name, dirent->name, name_len);
+               gp->name[name_len] = '\0';
                return DIRENT_ABORT;
        }
        return 0;
 }
 
-static errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ino_t dir, ino_t ino,
-                                        int maxdepth, char *buf, char **name)
+static errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ext2_ino_t dir,
+                                        ext2_ino_t ino, int maxdepth,
+                                        char *buf, char **name)
 {
        struct get_pathname_struct gp;
-       char    *parent_name, *ret;
+       char    *parent_name = 0, *ret;
        errcode_t       retval;
 
        if (dir == ino) {
-               *name = malloc(2);
-               if (!*name)
-                       return EXT2_NO_MEMORY;
+               retval = ext2fs_get_mem(2, name);
+               if (retval)
+                       return retval;
                strcpy(*name, (dir == EXT2_ROOT_INO) ? "/" : ".");
                return 0;
        }
 
        if (!dir || (maxdepth < 0)) {
-               *name = malloc(4);
-               if (!*name)
-                       return EXT2_NO_MEMORY;
+               retval = ext2fs_get_mem(4, name);
+               if (retval)
+                       return retval;
                strcpy(*name, "...");
                return 0;
        }
@@ -92,9 +96,21 @@ static errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ino_t dir, ino_t ino,
        gp.parent = 0;
        gp.name = 0;
        gp.errcode = 0;
-       
+
        retval = ext2fs_dir_iterate(fs, dir, 0, buf, get_pathname_proc, &gp);
-       if (retval)
+       if (retval == EXT2_ET_NO_DIRECTORY) {
+               char tmp[32];
+
+               if (ino)
+                       snprintf(tmp, sizeof(tmp), "<%u>/<%u>", dir, ino);
+               else
+                       snprintf(tmp, sizeof(tmp), "<%u>", dir);
+               retval = ext2fs_get_mem(strlen(tmp)+1, name);
+               if (retval)
+                       goto cleanup;
+               strcpy(*name, tmp);
+               return 0;
+       } else if (retval)
                goto cleanup;
        if (gp.errcode) {
                retval = gp.errcode;
@@ -109,16 +125,15 @@ static errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ino_t dir, ino_t ino,
                *name = parent_name;
                return 0;
        }
-       
-       if (gp.name) 
-               ret = malloc(strlen(parent_name)+strlen(gp.name)+2);
+
+       if (gp.name)
+               retval = ext2fs_get_mem(strlen(parent_name)+strlen(gp.name)+2,
+                                       &ret);
        else
-               ret = malloc(strlen(parent_name)+5); /* strlen("???") + 2 */
-               
-       if (!ret) {
-               retval = EXT2_NO_MEMORY;
+               retval = ext2fs_get_mem(strlen(parent_name)+5, &ret);
+       if (retval)
                goto cleanup;
-       }
+
        ret[0] = 0;
        if (parent_name[1])
                strcat(ret, parent_name);
@@ -128,16 +143,15 @@ static errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ino_t dir, ino_t ino,
        else
                strcat(ret, "???");
        *name = ret;
-       free(parent_name);
        retval = 0;
-       
+
 cleanup:
-       if (gp.name)
-               free(gp.name);
+       ext2fs_free_mem(&parent_name);
+       ext2fs_free_mem(&gp.name);
        return retval;
 }
 
-errcode_t ext2fs_get_pathname(ext2_filsys fs, ino_t dir, ino_t ino,
+errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino,
                              char **name)
 {
        char    *buf;
@@ -145,13 +159,13 @@ errcode_t ext2fs_get_pathname(ext2_filsys fs, ino_t dir, ino_t ino,
 
        EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
-       buf = malloc(fs->blocksize);
-       if (!buf)
-               return EXT2_NO_MEMORY;
+       retval = ext2fs_get_mem(fs->blocksize, &buf);
+       if (retval)
+               return retval;
        if (dir == ino)
                ino = 0;
        retval = ext2fs_get_pathname_int(fs, dir, ino, 32, buf, name);
-       free(buf);
+       ext2fs_free_mem(&buf);
        return retval;
-       
+
 }