diff options
Diffstat (limited to 'e2fsprogs/ext2fs/get_pathname.c')
-rw-r--r-- | e2fsprogs/ext2fs/get_pathname.c | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/e2fsprogs/ext2fs/get_pathname.c b/e2fsprogs/ext2fs/get_pathname.c new file mode 100644 index 000000000..23f593f67 --- /dev/null +++ b/e2fsprogs/ext2fs/get_pathname.c | |||
@@ -0,0 +1,157 @@ | |||
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 | } | ||