diff --git a/ChangeLog b/ChangeLog index cf161dd9..a5134fd9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -159,6 +159,9 @@ xx/xx/2005 - 2.0.0-WIP At least after attribute resize we leave absolutely consist volume. (Yura) - Update attribute definition handling. (Anton, Yura) + - Move utils_pathname_to_inode from to library (dir.c), adapt it + for the library, rename it to ntfs_pathname_to_inode, update all + users. (Yura) 04/09/2004 - 1.9.4 - Urgent bug fixes. diff --git a/include/ntfs/dir.h b/include/ntfs/dir.h index 035de300..59835b5a 100644 --- a/include/ntfs/dir.h +++ b/include/ntfs/dir.h @@ -24,12 +24,21 @@ #include "types.h" +#define PATH_SEP '/' + +#ifndef MAX_PATH +#define MAX_PATH 1024 +#endif + /* The little endian Unicode string $I30 as a global constant. */ extern ntfschar I30[5]; extern u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni, const ntfschar *uname, const int uname_len); +extern ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent, + const char *pathname); + /* * File types (adapted from include ) */ diff --git a/libntfs/dir.c b/libntfs/dir.c index d2354d44..1b85dc45 100644 --- a/libntfs/dir.c +++ b/libntfs/dir.c @@ -459,6 +459,111 @@ close_err_out: goto eo_put_err_out; } +/** + * ntfs_pathname_to_inode - Find the inode which represents the given pathname + * @vol: An ntfs volume obtained from ntfs_mount + * @parent: A directory inode to begin the search (may be NULL) + * @pathname: Pathname to be located + * + * Take an ASCII pathname and find the inode that represents it. The function + * splits the path and then descends the directory tree. If @parent is NULL, + * then the root directory '.' will be used as the base for the search. + * + * Return: inode Success, the pathname was valid + * NULL Error, the pathname was invalid, or some other error occurred + */ +ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent, + const char *pathname) +{ + u64 inum; + int len, err = 0; + char *p, *q; + ntfs_inode *ni; + ntfs_inode *result = NULL; + ntfschar *unicode = NULL; + char *ascii = NULL; + + if (!vol || !pathname) { + errno = EINVAL; + return NULL; + } + + if (parent) { + ni = parent; + } else { + ni = ntfs_inode_open(vol, FILE_root); + if (!ni) { + Dprintf("Couldn't open the inode of the root " + "directory.\n"); + err = EIO; + goto close; + } + } + + unicode = calloc(1, MAX_PATH); + ascii = strdup(pathname); + if (!unicode || !ascii) { + Dprintf("Out of memory.\n"); + err = ENOMEM; + goto close; + } + + p = ascii; + /* Remove leading /'s. */ + while (p && *p && *p == PATH_SEP) + p++; + while (p && *p) { + /* Find the end of the first token. */ + q = strchr(p, PATH_SEP); + if (q != NULL) { + *q = '\0'; + q++; + } + + len = ntfs_mbstoucs(p, &unicode, MAX_PATH); + if (len < 0) { + Dprintf("Couldn't convert name to Unicode: %s.\n", p); + err = EILSEQ; + goto close; + } + + inum = ntfs_inode_lookup_by_name(ni, unicode, len); + if (inum == (u64) -1) { + Dprintf("Couldn't find name '%s' in " + "pathname '%s'.\n", p, pathname); + err = ENOENT; + goto close; + } + + if (ni != parent) + ntfs_inode_close(ni); + + inum = MREF(inum); + ni = ntfs_inode_open(vol, inum); + if (!ni) { + Dprintf("Cannot open inode %llu: %s.\n", + (unsigned long long)inum, p); + err = EIO; + goto close; + } + + p = q; + while (p && *p && *p == PATH_SEP) + p++; + } + + result = ni; + ni = NULL; +close: + if (ni && (ni != parent)) + ntfs_inode_close(ni); + free(ascii); + free(unicode); + if (err) + errno = err; + return result; +} + /* * The little endian Unicode string ".." for ntfs_readdir(). */ diff --git a/ntfsprogs/ntfscat.c b/ntfsprogs/ntfscat.c index 73326724..0749addc 100644 --- a/ntfsprogs/ntfscat.c +++ b/ntfsprogs/ntfscat.c @@ -286,7 +286,7 @@ int main (int argc, char *argv[]) if (opts.inode != -1) inode = ntfs_inode_open (vol, opts.inode); else - inode = utils_pathname_to_inode (vol, NULL, opts.file); + inode = ntfs_pathname_to_inode (vol, NULL, opts.file); if (!inode) { perror("ERROR: Couldn't open inode"); diff --git a/ntfsprogs/ntfscluster.c b/ntfsprogs/ntfscluster.c index 194d79d4..57ba5a2d 100644 --- a/ntfsprogs/ntfscluster.c +++ b/ntfsprogs/ntfscluster.c @@ -487,7 +487,7 @@ int main (int argc, char *argv[]) result = cluster_find (vol, opts.range_begin, opts.range_end, (cluster_cb*)&print_match, NULL); break; case act_file: - ino = utils_pathname_to_inode (vol, NULL, opts.filename); + ino = ntfs_pathname_to_inode(vol, NULL, opts.filename); if (ino) result = dump_file (vol, ino); break; diff --git a/ntfsprogs/ntfscp.c b/ntfsprogs/ntfscp.c index 6f851f54..9d2a948f 100644 --- a/ntfsprogs/ntfscp.c +++ b/ntfsprogs/ntfscp.c @@ -35,6 +35,7 @@ #include "attrib.h" #include "utils.h" #include "volume.h" +#include "dir.h" #include "debug.h" struct options { @@ -319,7 +320,7 @@ int main (int argc, char *argv[]) } out = ntfs_inode_open(vol, inode_num); } else - out = utils_pathname_to_inode(vol, NULL, opts.dest_file); + out = ntfs_pathname_to_inode(vol, NULL, opts.dest_file); if (!out) { perror("ERROR: Couldn't open destination file"); goto close_src; @@ -353,7 +354,7 @@ int main (int argc, char *argv[]) strcat(new_dest_file, "/"); strcat(new_dest_file, filename); ntfs_inode_close(out); - out = utils_pathname_to_inode(vol, NULL, new_dest_file); + out = ntfs_pathname_to_inode(vol, NULL, new_dest_file); free(new_dest_file); if (!out) { perror("ERROR: Failed to open destination file"); diff --git a/ntfsprogs/ntfsinfo.c b/ntfsprogs/ntfsinfo.c index fc66549d..6c51b392 100644 --- a/ntfsprogs/ntfsinfo.c +++ b/ntfsprogs/ntfsinfo.c @@ -66,6 +66,7 @@ #include "utils.h" #include "security.h" #include "mst.h" +#include "dir.h" static const char *EXEC_NAME = "ntfsinfo"; @@ -1776,7 +1777,7 @@ int main(int argc, char **argv) ntfs_inode *inode; /* obtain the inode */ if (opts.filename) { - inode = utils_pathname_to_inode (vol, NULL, opts.filename); + inode = ntfs_pathname_to_inode(vol, NULL, opts.filename); } else { inode = ntfs_inode_open(vol, MK_LE_MREF(opts.inode, 0)); } diff --git a/ntfsprogs/ntfsls.c b/ntfsprogs/ntfsls.c index 8d77ea54..3f8419b9 100644 --- a/ntfsprogs/ntfsls.c +++ b/ntfsprogs/ntfsls.c @@ -404,7 +404,7 @@ static int readdir_recursive(ntfs_inode * ni, s64 * pos, ntfsls_dirent * dirent) dir_list_insert_pos = &dirs.list; if (!subdir->ni) { subdir->ni = - utils_pathname_to_inode(ni->vol, ni, + ntfs_pathname_to_inode(ni->vol, ni, subdir->name); if (!subdir->ni) { @@ -628,7 +628,7 @@ int main(int argc, char **argv) return 2; } - ni = utils_pathname_to_inode (vol, NULL, opts.path); + ni = ntfs_pathname_to_inode (vol, NULL, opts.path); if (!ni) { // FIXME: Print error... (AIA) ntfs_umount(vol, FALSE); diff --git a/ntfsprogs/ntfsmove.c b/ntfsprogs/ntfsmove.c index 309ba21f..f25416fc 100644 --- a/ntfsprogs/ntfsmove.c +++ b/ntfsprogs/ntfsmove.c @@ -858,7 +858,7 @@ int main (int argc, char *argv[]) return 1; } - inode = utils_pathname_to_inode (vol, NULL, opts.file); + inode = ntfs_pathname_to_inode(vol, NULL, opts.file); if (!inode) { printf ("!inode\n"); return 1; diff --git a/ntfsprogs/ntfswipe.c b/ntfsprogs/ntfswipe.c index 14955268..5184435d 100644 --- a/ntfsprogs/ntfswipe.c +++ b/ntfsprogs/ntfswipe.c @@ -1175,7 +1175,7 @@ static s64 wipe_pagefile (ntfs_volume *vol, int byte, enum action act) //Qprintf ("wipe_pagefile (not implemented) 0x%02x\n", byte); - ni = utils_pathname_to_inode (vol, NULL, "pagefile.sys"); + ni = ntfs_pathname_to_inode(vol, NULL, "pagefile.sys"); if (!ni) { Dprintf("Failed to open inode of pagefile.sys.\n"); return 0; diff --git a/ntfsprogs/utils.c b/ntfsprogs/utils.c index 2b3b03ca..db48be07 100644 --- a/ntfsprogs/utils.c +++ b/ntfsprogs/utils.c @@ -701,99 +701,6 @@ int utils_mftrec_in_use (ntfs_volume *vol, MFT_REF mref) return (buffer[byte] & bit); } -/** - * utils_pathname_to_inode - Find the inode which represents the given pathname - * @vol: An ntfs volume obtained from ntfs_mount - * @parent: A directory inode to begin the search (may be NULL) - * @pathname: Pathname to be located - * - * Take an ASCII pathname and find the inode that represents it. The function - * splits the path and then descends the directory tree. If @parent is NULL, - * then the root directory '.' will be used as the base for the search. - * - * Return: inode Success, the pathname was valid - * NULL Error, the pathname was invalid, or some other error occurred - */ -ntfs_inode * utils_pathname_to_inode (ntfs_volume *vol, ntfs_inode *parent, const char *pathname) -{ - u64 inum; - int len; - char *p, *q; - ntfs_inode *ni; - ntfs_inode *result = NULL; - ntfschar *unicode = NULL; - char *ascii = NULL; - - if (!vol || !pathname) { - errno = EINVAL; - return NULL; - } - - if (parent) { - ni = parent; - } else { - ni = ntfs_inode_open (vol, FILE_root); - if (!ni) { - Eprintf ("Couldn't open the inode of the root directory.\n"); - goto close; - } - } - - unicode = calloc (1, MAX_PATH); - ascii = strdup (pathname); // Work with a r/w copy - if (!unicode || !ascii) { - Eprintf ("Out of memory.\n"); - goto close; - } - - p = ascii; - while (p && *p && *p == PATH_SEP) // Remove leading /'s - p++; - while (p && *p) { - q = strchr (p, PATH_SEP); // Find the end of the first token - if (q != NULL) { - *q = '\0'; - q++; - } - - len = ntfs_mbstoucs (p, &unicode, MAX_PATH); - if (len < 0) { - Eprintf ("Couldn't convert name to Unicode: %s.\n", p); - goto close; - } - - inum = ntfs_inode_lookup_by_name (ni, unicode, len); - if (inum == (u64)-1) { - Eprintf ("Couldn't find name '%s' in pathname '%s'.\n", p, pathname); - goto close; - } - - if (ni != parent) - ntfs_inode_close (ni); - - inum = MREF (inum); - ni = ntfs_inode_open (vol, inum); - if (!ni) { - Eprintf ("Cannot open inode %llu: %s.\n", - (unsigned long long)inum, p); - goto close; - } - - p = q; - while (p && *p && *p == PATH_SEP) - p++; - } - - result = ni; - ni = NULL; -close: - if (ni && (ni != parent)) - ntfs_inode_close (ni); - free (ascii); - free (unicode); - return result; -} - /** * __metadata */ diff --git a/ntfsprogs/utils.h b/ntfsprogs/utils.h index b012ca0d..598d4763 100644 --- a/ntfsprogs/utils.h +++ b/ntfsprogs/utils.h @@ -39,11 +39,6 @@ extern const char *ntfs_bugs; extern const char *ntfs_home; extern const char *ntfs_gpl; -#define PATH_SEP '/' -#ifndef MAX_PATH -# define MAX_PATH 1024 -#endif - #if !defined(REG_NOERROR) || (REG_NOERROR != 0) # define REG_NOERROR 0 #endif @@ -97,7 +92,6 @@ int utils_attr_get_name (ntfs_volume *vol, ATTR_RECORD *attr, char *buffer, int int utils_cluster_in_use (ntfs_volume *vol, long long lcn); int utils_mftrec_in_use (ntfs_volume *vol, MFT_REF mref); int utils_is_metadata (ntfs_inode *inode); -ntfs_inode * utils_pathname_to_inode (ntfs_volume *vol, ntfs_inode *parent, const char *pathname); void utils_dump_mem (u8 *buf, int start, int length, int ascii); time_t ntfs2utc (s64 ntfs_time);