diff options
Diffstat (limited to 'src/myriadfs.cpp')
-rw-r--r-- | src/myriadfs.cpp | 144 |
1 files changed, 128 insertions, 16 deletions
diff --git a/src/myriadfs.cpp b/src/myriadfs.cpp index 4e2a0f6..8312bce 100644 --- a/src/myriadfs.cpp +++ b/src/myriadfs.cpp | |||
@@ -45,7 +45,17 @@ Bu::MyriadFs::MyriadFs( Bu::Stream &rStore, int iBlockSize ) : | |||
45 | 45 | ||
46 | int8_t iVer; | 46 | int8_t iVer; |
47 | ms.read( &iVer, 1 ); | 47 | ms.read( &iVer, 1 ); |
48 | throw MyriadFsException("You totally have a MyriadFs stream, version %d, but they can't be loaded yet.", iVer ); | 48 | |
49 | int32_t iNumNodes; | ||
50 | ms.read( &iNumNodes, 4 ); | ||
51 | for( int32_t j = 0; j < iNumNodes; j++ ) | ||
52 | { | ||
53 | int32_t iNode; | ||
54 | int32_t iPos; | ||
55 | ms.read( &iNode, 4 ); | ||
56 | ms.read( &iPos, 4 ); | ||
57 | hNodeIndex.insert( iNode, iPos ); | ||
58 | } | ||
49 | } | 59 | } |
50 | else | 60 | else |
51 | { | 61 | { |
@@ -125,26 +135,103 @@ Bu::MyriadStream Bu::MyriadFs::open( const Bu::String &sPath, int iMode ) | |||
125 | if( iParent < 0 ) | 135 | if( iParent < 0 ) |
126 | throw; | 136 | throw; |
127 | 137 | ||
138 | // This means that an intermediate path component couldn't be found | ||
139 | if( e.getErrorCode() == 1 ) | ||
140 | throw; | ||
141 | |||
128 | // The file wasn't found, but the path leading up to it was. | 142 | // The file wasn't found, but the path leading up to it was. |
129 | // first, figure out the final path element... | 143 | // first, figure out the final path element... |
130 | Bu::String::const_iterator iStart = sPath.begin(); | 144 | Bu::String::const_iterator iStart = sPath.begin(); |
131 | if( *iStart == '/' ) | 145 | if( *iStart == '/' ) |
132 | iStart++; | 146 | iStart++; |
133 | sio << "Scanning for filename:" << sio.nl; | 147 | sio << "Scanning for filename:" << sio.nl; |
134 | for( Bu::String::const_iterator iEnd = iStart.find('/')+1; iEnd; iStart = iEnd ) { } | 148 | for( Bu::String::const_iterator iEnd = iStart.find('/'); iEnd; |
149 | iStart = iEnd+1, iEnd = iStart.find('/') ) { } | ||
135 | Bu::String sName( iStart, sPath.end() ); | 150 | Bu::String sName( iStart, sPath.end() ); |
136 | sio << "End filename: " << sName << sio.nl; | 151 | sio << "End filename: " << sName << sio.nl; |
137 | sio << "Parent inode: " << iParent << sio.nl; | 152 | sio << "Parent inode: " << iParent << sio.nl; |
138 | iNode = create( iParent, sName, 0664|typeRegFile ); | 153 | iNode = create( iParent, sName, 0664|typeRegFile, 0 ); |
139 | sio << "New iNode: " << iNode << sio.nl; | 154 | sio << "New iNode: " << iNode << sio.nl; |
140 | return openByInode( iNode ); | 155 | return openByInode( iNode ); |
141 | } | 156 | } |
157 | } | ||
158 | |||
159 | void Bu::MyriadFs::create( const Bu::String &sPath, uint16_t iPerms ) | ||
160 | { | ||
161 | create( sPath, iPerms, 0 ); | ||
162 | } | ||
142 | 163 | ||
143 | return mStore.openStream( 2 ); | 164 | void Bu::MyriadFs::create( const Bu::String &sPath, uint16_t iPerms, |
165 | uint16_t iDevHi, uint16_t iDevLo ) | ||
166 | { | ||
167 | create( sPath, iPerms, ((uint32_t)iDevHi<<16)|(uint32_t)iDevLo ); | ||
168 | } | ||
169 | |||
170 | void Bu::MyriadFs::create( const Bu::String &sPath, uint16_t iPerms, | ||
171 | uint32_t uSpecial ) | ||
172 | { | ||
173 | int32_t iParent = -1; | ||
174 | int32_t iNode; | ||
175 | try | ||
176 | { | ||
177 | iNode = lookupInode( sPath, iParent ); | ||
178 | sio << "File found." << sio.nl; | ||
179 | // The file was found | ||
180 | throw Bu::MyriadFsException("Path already exists."); | ||
181 | } | ||
182 | catch( Bu::MyriadFsException &e ) | ||
183 | { | ||
184 | if( iParent < 0 ) | ||
185 | throw; | ||
186 | |||
187 | // This means that an intermediate path component couldn't be found | ||
188 | if( e.getErrorCode() == 1 ) | ||
189 | throw; | ||
190 | |||
191 | // The file wasn't found, but the path leading up to it was. | ||
192 | // first, figure out the final path element... | ||
193 | Bu::String::const_iterator iStart = sPath.begin(); | ||
194 | if( *iStart == '/' ) | ||
195 | iStart++; | ||
196 | sio << "Scanning for filename:" << sio.nl; | ||
197 | for( Bu::String::const_iterator iEnd = iStart.find('/'); iEnd; | ||
198 | iStart = iEnd+1, iEnd = iStart.find('/') ) { } | ||
199 | Bu::String sName( iStart, sPath.end() ); | ||
200 | sio << "End filename: " << sName << sio.nl; | ||
201 | sio << "Parent inode: " << iParent << sio.nl; | ||
202 | iNode = create( iParent, sName, iPerms, uSpecial ); | ||
203 | sio << "New iNode: " << iNode << sio.nl; | ||
204 | } | ||
205 | } | ||
206 | |||
207 | void Bu::MyriadFs::mkDir( const Bu::String &sPath, uint16_t iPerms ) | ||
208 | { | ||
209 | create( sPath, (iPerms&permMask)|typeDir, 0 ); | ||
210 | } | ||
211 | |||
212 | Bu::MyriadFs::Dir Bu::MyriadFs::readDir( const Bu::String &sPath ) | ||
213 | { | ||
214 | int32_t iParent = -1; | ||
215 | int32_t iNode = lookupInode( sPath, iParent ); | ||
216 | return readDir( iNode ); | ||
217 | } | ||
218 | |||
219 | dev_t Bu::MyriadFs::devToSys( uint32_t uDev ) | ||
220 | { | ||
221 | return (((uDev&0xFFFF0000)>>8)&0xFF00) | ((uDev&0xFF)); | ||
222 | } | ||
223 | |||
224 | uint32_t Bu::MyriadFs::sysToDev( dev_t uDev ) | ||
225 | { | ||
226 | return (((uint32_t)uDev&0xFF00)<<8) | ((uint32_t)uDev&0xFF); | ||
144 | } | 227 | } |
145 | 228 | ||
146 | int32_t Bu::MyriadFs::lookupInode( const Bu::String &sPath, int32_t &iParent ) | 229 | int32_t Bu::MyriadFs::lookupInode( const Bu::String &sPath, int32_t &iParent ) |
147 | { | 230 | { |
231 | if( sPath == "/" ) | ||
232 | { | ||
233 | return 0; | ||
234 | } | ||
148 | if( sPath[0] == '/' ) | 235 | if( sPath[0] == '/' ) |
149 | { | 236 | { |
150 | // Absolute lookup | 237 | // Absolute lookup |
@@ -185,7 +272,7 @@ int32_t Bu::MyriadFs::lookupInode( Bu::String::const_iterator iStart, | |||
185 | // Not the last one in our path, double check it's a dir | 272 | // Not the last one in our path, double check it's a dir |
186 | if( ((*i).uPerms&typeMask) == typeDir ) | 273 | if( ((*i).uPerms&typeMask) == typeDir ) |
187 | { | 274 | { |
188 | return lookupInode( iEnd+1, (*i).iNode ); | 275 | return lookupInode( iEnd+1, (*i).iNode, iParent ); |
189 | } | 276 | } |
190 | else | 277 | else |
191 | { | 278 | { |
@@ -198,13 +285,16 @@ int32_t Bu::MyriadFs::lookupInode( Bu::String::const_iterator iStart, | |||
198 | } | 285 | } |
199 | } | 286 | } |
200 | 287 | ||
201 | throw Bu::MyriadFsException( 1, "Path not found"); | 288 | if( iEnd ) |
289 | throw Bu::MyriadFsException( 1, "Path not found"); | ||
290 | else | ||
291 | throw Bu::MyriadFsException( 2, "Path not found"); | ||
202 | } | 292 | } |
203 | 293 | ||
204 | Bu::MyriadFs::Dir Bu::MyriadFs::readDir( int32_t iNode ) | 294 | Bu::MyriadFs::Dir Bu::MyriadFs::readDir( int32_t iNode ) |
205 | { | 295 | { |
206 | Bu::MyriadStream ms = openByInode( iNode ); | 296 | Bu::MyriadStream ms = openByInode( iNode ); |
207 | int32_t iNumChildren; | 297 | int32_t iNumChildren = 0; |
208 | ms.read( &iNumChildren, 4 ); | 298 | ms.read( &iNumChildren, 4 ); |
209 | 299 | ||
210 | Bu::MyriadStream is = mStore.openStream( 2 ); | 300 | Bu::MyriadStream is = mStore.openStream( 2 ); |
@@ -236,7 +326,7 @@ Bu::MyriadStream Bu::MyriadFs::openByInode( int32_t iNode ) | |||
236 | case typeDir: | 326 | case typeDir: |
237 | case typeSymLink: | 327 | case typeSymLink: |
238 | case typeRegFile: | 328 | case typeRegFile: |
239 | return mStore.openStream( rs.iStreamIndex ); | 329 | return mStore.openStream( rs.uStreamIndex ); |
240 | 330 | ||
241 | default: | 331 | default: |
242 | throw Bu::MyriadFsException( | 332 | throw Bu::MyriadFsException( |
@@ -245,22 +335,22 @@ Bu::MyriadStream Bu::MyriadFs::openByInode( int32_t iNode ) | |||
245 | } | 335 | } |
246 | 336 | ||
247 | int32_t Bu::MyriadFs::create( int32_t iParent, const Bu::String &sName, | 337 | int32_t Bu::MyriadFs::create( int32_t iParent, const Bu::String &sName, |
248 | uint16_t uPerms ) | 338 | uint16_t uPerms, uint32_t uSpecial ) |
249 | { | 339 | { |
250 | Bu::MyriadStream ms = openByInode( iParent ); | 340 | Bu::MyriadStream ms = openByInode( iParent ); |
251 | int32_t iNumChildren; | 341 | int32_t iNumChildren = 0; |
252 | ms.read( &iNumChildren, 4 ); | 342 | ms.read( &iNumChildren, 4 ); |
253 | iNumChildren++; | 343 | iNumChildren++; |
254 | ms.setPos( 0 ); | 344 | ms.setPos( 0 ); |
255 | ms.write( &iNumChildren, 4 ); | 345 | ms.write( &iNumChildren, 4 ); |
256 | ms.setPos( iNumChildren*4 ); // Actually 4+(iNumChildren-1)*4 :-P | 346 | ms.setPos( iNumChildren*4 ); // Actually 4+(iNumChildren-1)*4 :-P |
257 | int32_t iNode = allocInode( sName, iParent, uPerms ); | 347 | int32_t iNode = allocInode( sName, iParent, uPerms, uSpecial ); |
258 | ms.write( &iNode, 4 ); | 348 | ms.write( &iNode, 4 ); |
259 | return iNode; | 349 | return iNode; |
260 | } | 350 | } |
261 | 351 | ||
262 | int32_t Bu::MyriadFs::allocInode( const Bu::String &sName, int32_t iParent, | 352 | int32_t Bu::MyriadFs::allocInode( const Bu::String &sName, int32_t iParent, |
263 | uint16_t uPerms ) | 353 | uint16_t uPerms, uint32_t uSpecial ) |
264 | { | 354 | { |
265 | int32_t iNode = 0; | 355 | int32_t iNode = 0; |
266 | for(; iNode < 0xfffffff; iNode++ ) | 356 | for(; iNode < 0xfffffff; iNode++ ) |
@@ -279,14 +369,29 @@ int32_t Bu::MyriadFs::allocInode( const Bu::String &sName, int32_t iParent, | |||
279 | rs.iLinks = 1; | 369 | rs.iLinks = 1; |
280 | switch( (uPerms&typeMask) ) | 370 | switch( (uPerms&typeMask) ) |
281 | { | 371 | { |
282 | case typeDir: | ||
283 | case typeRegFile: | 372 | case typeRegFile: |
284 | case typeSymLink: | 373 | case typeSymLink: |
285 | rs.iStreamIndex = mStore.createStream(); | 374 | rs.uStreamIndex = mStore.createStream(); |
375 | break; | ||
376 | |||
377 | case typeDir: | ||
378 | rs.uStreamIndex = mStore.createStream(); | ||
379 | { | ||
380 | Bu::MyriadStream msDir = mStore.openStream( | ||
381 | rs.uStreamIndex | ||
382 | ); | ||
383 | uint32_t uSize = 0; | ||
384 | msDir.write( &uSize, 4 ); | ||
385 | } | ||
386 | break; | ||
387 | |||
388 | case typeChrDev: | ||
389 | case typeBlkDev: | ||
390 | rs.uStreamIndex = uSpecial; | ||
286 | break; | 391 | break; |
287 | 392 | ||
288 | default: | 393 | default: |
289 | rs.iStreamIndex = 0; | 394 | rs.uStreamIndex = 0; |
290 | break; | 395 | break; |
291 | } | 396 | } |
292 | rs.iParentNode = iParent; | 397 | rs.iParentNode = iParent; |
@@ -320,11 +425,18 @@ void Bu::MyriadFs::stat( int32_t iNode, Stat &rBuf, MyriadStream &rIs ) | |||
320 | rBuf.iATime = rs.iATime; | 425 | rBuf.iATime = rs.iATime; |
321 | rBuf.iMTime = rs.iMTime; | 426 | rBuf.iMTime = rs.iMTime; |
322 | rBuf.iCTime = rs.iCTime; | 427 | rBuf.iCTime = rs.iCTime; |
428 | rBuf.uDev = 0; | ||
429 | rBuf.iSize = 0; | ||
323 | switch( (rBuf.uPerms&typeMask) ) | 430 | switch( (rBuf.uPerms&typeMask) ) |
324 | { | 431 | { |
325 | case typeRegFile: | 432 | case typeRegFile: |
326 | case typeSymLink: | 433 | case typeSymLink: |
327 | rBuf.iSize = mStore.getStreamSize( rs.iStreamIndex ); | 434 | rBuf.iSize = mStore.getStreamSize( rs.uStreamIndex ); |
435 | break; | ||
436 | |||
437 | case typeChrDev: | ||
438 | case typeBlkDev: | ||
439 | rBuf.uDev = rs.uStreamIndex; | ||
328 | break; | 440 | break; |
329 | 441 | ||
330 | default: | 442 | default: |