summaryrefslogtreecommitdiff
path: root/src/myriadfs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/myriadfs.cpp')
-rw-r--r--src/myriadfs.cpp144
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
159void Bu::MyriadFs::create( const Bu::String &sPath, uint16_t iPerms )
160{
161 create( sPath, iPerms, 0 );
162}
142 163
143 return mStore.openStream( 2 ); 164void 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
170void 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
207void Bu::MyriadFs::mkDir( const Bu::String &sPath, uint16_t iPerms )
208{
209 create( sPath, (iPerms&permMask)|typeDir, 0 );
210}
211
212Bu::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
219dev_t Bu::MyriadFs::devToSys( uint32_t uDev )
220{
221 return (((uDev&0xFFFF0000)>>8)&0xFF00) | ((uDev&0xFF));
222}
223
224uint32_t Bu::MyriadFs::sysToDev( dev_t uDev )
225{
226 return (((uint32_t)uDev&0xFF00)<<8) | ((uint32_t)uDev&0xFF);
144} 227}
145 228
146int32_t Bu::MyriadFs::lookupInode( const Bu::String &sPath, int32_t &iParent ) 229int32_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
204Bu::MyriadFs::Dir Bu::MyriadFs::readDir( int32_t iNode ) 294Bu::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
247int32_t Bu::MyriadFs::create( int32_t iParent, const Bu::String &sName, 337int32_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
262int32_t Bu::MyriadFs::allocInode( const Bu::String &sName, int32_t iParent, 352int32_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: