12
12
13
13
/* pathDepth(): helper function to calculate the depth of a path
14
14
* params: path - full qualified path
15
- * returns: maximum depth of the path
15
+ * returns: maximum depth of the path, zero for root directory, ONE-BASED elsewhere
16
16
*/
17
17
18
18
int pathDepth (const char * path ) {
19
19
if (!path || !strlen (path ) || strlen (path ) == 1 ) return 0 ;
20
20
21
- int c = 0 ;
21
+ int c = 1 ;
22
22
for (int i = 0 ; i < strlen (path ); i ++ ) {
23
23
if (path [i ] == '/' ) c ++ ;
24
24
}
@@ -37,6 +37,11 @@ char *pathComponent(char *dest, const char *path, int n) {
37
37
int depth = pathDepth (path );
38
38
if (n > depth ) return NULL ;
39
39
40
+ if (depth <= 1 ) {
41
+ // special case for files on the root directory
42
+ return strcpy (dest , path );
43
+ }
44
+
40
45
int c = 0 ;
41
46
int len = 0 ;
42
47
for (int i = 0 ; i < strlen (path ); i ++ ) {
@@ -65,5 +70,82 @@ char *pathComponent(char *dest, const char *path, int n) {
65
70
*/
66
71
67
72
LXFSDirectoryEntry * lxfsFind (LXFSDirectoryEntry * dest , Mountpoint * mp , const char * path ) {
68
- return NULL ; // stub
73
+ // special case for the root directory because it does not have a true
74
+ // directory entry within the file system itself
75
+ if ((strlen (path ) == 1 ) && (path [0 ] == '/' )) {
76
+ if (lxfsReadBlock (mp , mp -> root , mp -> dataBuffer )) return NULL ;
77
+
78
+ LXFSDirectoryHeader * root = (LXFSDirectoryHeader * ) mp -> dataBuffer ;
79
+ dest -> size = root -> sizeEntries ;
80
+ dest -> accessTime = root -> accessTime ;
81
+ dest -> createTime = root -> createTime ;
82
+ dest -> modTime = root -> modTime ;
83
+ dest -> name [0 ] = 0 ;
84
+ dest -> flags = LXFS_DIR_VALID | (LXFS_DIR_TYPE_DIR << LXFS_DIR_TYPE_SHIFT );
85
+ dest -> block = mp -> root ;
86
+
87
+ // root directory is owned by root:root and its mode is rwxr-xr-x
88
+ dest -> owner = 0 ;
89
+ dest -> group = 0 ;
90
+ dest -> permissions = LXFS_PERMS_OWNER_R | LXFS_PERMS_OWNER_W | LXFS_PERMS_OWNER_X | LXFS_PERMS_GROUP_R | LXFS_PERMS_GROUP_X | LXFS_PERMS_OTHER_R | LXFS_PERMS_OTHER_X ;
91
+
92
+ return dest ;
93
+ }
94
+
95
+ // for everything else we will need to traverse the file system starting
96
+ // at the root directory
97
+ LXFSDirectoryEntry * dir ;
98
+ uint64_t next = mp -> root ;
99
+ int depth = pathDepth (path );
100
+ char component [MAX_FILE_PATH ];
101
+
102
+ int i = 0 ;
103
+
104
+ traverse :
105
+ while (i < depth ) {
106
+ // iterate over each component in the path and search for it in the directory
107
+ if (!pathComponent (component , path , i )) return NULL ;
108
+
109
+ next = lxfsReadNextBlock (mp , next , mp -> dataBuffer );
110
+ if (!next ) return NULL ;
111
+
112
+ // read two blocks at a time for entries that cross boundaries
113
+ if (next != LXFS_BLOCK_EOF )
114
+ lxfsReadNextBlock (mp , next , mp -> dataBuffer + mp -> blockSizeBytes );
115
+
116
+ dir = (LXFSDirectoryEntry * )((uintptr_t )mp -> dataBuffer + sizeof (LXFSDirectoryHeader ));
117
+ off_t offset = sizeof (LXFSDirectoryHeader );
118
+
119
+ while (offset < mp -> blockSizeBytes ) {
120
+ if ((dir -> flags & LXFS_DIR_VALID ) && !strcmp ((const char * ) dir -> name , component )) {
121
+ if (i == depth - 1 ) {
122
+ // found the file we're looking for
123
+ return (LXFSDirectoryEntry * ) memcpy (dest , dir , dir -> entrySize );
124
+ } else {
125
+ // found a parent directory
126
+ i ++ ;
127
+ luxLogf (KPRINT_LEVEL_WARNING , "TODO: implement directory trees\n" );
128
+ }
129
+ }
130
+
131
+ // advance to the next entry
132
+ dir = (LXFSDirectoryEntry * )((uintptr_t )dir + dir -> entrySize );
133
+ offset += dir -> entrySize ;
134
+
135
+ if ((offset >= mp -> blockSizeBytes ) && (next != LXFS_BLOCK_EOF )) {
136
+ // copy the second block to the first block
137
+ offset -= mp -> blockSizeBytes ;
138
+ dir = (LXFSDirectoryEntry * )((uintptr_t )dir - mp -> blockSizeBytes );
139
+ memmove (mp -> dataBuffer , mp -> dataBuffer + mp -> blockSizeBytes , mp -> blockSizeBytes );
140
+
141
+ if (!dir -> entrySize ) return NULL ;
142
+
143
+ // and read the next block
144
+ next = lxfsReadNextBlock (mp , next , mp -> dataBuffer );
145
+ if (!next ) return NULL ;
146
+ }
147
+ }
148
+ }
149
+
150
+ return NULL ;
69
151
}
0 commit comments