xref: /minix/minix/lib/libvtreefs/path.c (revision 9f988b79)
1 /* VTreeFS - path.c - name resolution */
2 
3 #include "inc.h"
4 
5 /*
6  * Resolve a path string to an inode.
7  */
8 int
9 fs_lookup(ino_t dir_nr, char * name, struct fsdriver_node * node_details,
10 	int * is_mountpt)
11 {
12 	struct inode *node, *child;
13 	int r;
14 
15 	if ((node = find_inode(dir_nr)) == NULL)
16 		return EINVAL;
17 
18 	if (!S_ISDIR(node->i_stat.mode))
19 		return ENOTDIR;
20 
21 	if (strlen(name) > NAME_MAX)
22 		return ENAMETOOLONG;
23 
24 	if (!strcmp(name, ".")) {
25 		/* Stay in the given directory. */
26 		child = node;
27 	} else if (!strcmp(name, "..")) {
28 		/* Progress into the parent directory. */
29 		if ((child = get_parent_inode(node)) == NULL)
30 			return ENOENT;	/* deleted? should not be possible */
31 	} else {
32 		/* Progress into a directory entry.  Call the lookup hook, if
33 		 * present, before doing the actual lookup.
34 		 */
35 		if (!is_inode_deleted(node) &&
36 		    vtreefs_hooks->lookup_hook != NULL) {
37 			r = vtreefs_hooks->lookup_hook(node, name,
38 			    get_inode_cbdata(node));
39 			if (r != OK) return r;
40 		}
41 
42 		if ((child = get_inode_by_name(node, name)) == NULL)
43 			return ENOENT;
44 	}
45 
46 	/* On success, open the resulting file and return its details. */
47 	ref_inode(child);
48 
49 	node_details->fn_ino_nr = get_inode_number(child);
50 	node_details->fn_mode = child->i_stat.mode;
51 	node_details->fn_size = child->i_stat.size;
52 	node_details->fn_uid = child->i_stat.uid;
53 	node_details->fn_gid = child->i_stat.gid;
54 	node_details->fn_dev = child->i_stat.dev;
55 
56 	*is_mountpt = FALSE;
57 
58 	return OK;
59 }
60