1 /* 2 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. 3 * This file may be used under the terms of the MIT License. 4 */ 5 6 7 #include "DirectoryIterator.h" 8 9 #include <string.h> 10 11 #include "HTree.h" 12 #include "Inode.h" 13 14 15 //#define TRACE_EXT2 16 #ifdef TRACE_EXT2 17 # define TRACE(x...) dprintf("\33[34mext2:\33[0m " x) 18 #else 19 # define TRACE(x...) ; 20 #endif 21 22 23 DirectoryIterator::DirectoryIterator(Inode* inode) 24 : 25 fInode(inode), 26 fOffset(0) 27 { 28 } 29 30 31 DirectoryIterator::~DirectoryIterator() 32 { 33 } 34 35 36 status_t 37 DirectoryIterator::GetNext(char* name, size_t* _nameLength, ino_t* _id) 38 { 39 if (fOffset + sizeof(ext2_dir_entry) >= fInode->Size()) { 40 TRACE("DirectoryIterator::GetNext() out of entries\n"); 41 return B_ENTRY_NOT_FOUND; 42 } 43 44 ext2_dir_entry entry; 45 46 while (true) { 47 size_t length = ext2_dir_entry::MinimumSize(); 48 status_t status = fInode->ReadAt(fOffset, (uint8*)&entry, &length); 49 if (status != B_OK) 50 return status; 51 if (length < ext2_dir_entry::MinimumSize() || entry.Length() == 0) 52 return B_ENTRY_NOT_FOUND; 53 if (!entry.IsValid()) 54 return B_BAD_DATA; 55 56 if (entry.NameLength() != 0) 57 break; 58 59 fOffset += entry.Length(); 60 TRACE("DirectoryIterator::GetNext() skipping entry\n"); 61 } 62 63 TRACE("offset %Ld: entry ino %lu, length %u, name length %u, type %u\n", 64 fOffset, entry.InodeID(), entry.Length(), entry.NameLength(), 65 entry.FileType()); 66 67 // read name 68 69 size_t length = entry.NameLength(); 70 status_t status = fInode->ReadAt(fOffset + ext2_dir_entry::MinimumSize(), 71 (uint8*)entry.name, &length); 72 if (status == B_OK) { 73 if (*_nameLength < length) 74 length = *_nameLength - 1; 75 memcpy(name, entry.name, length); 76 name[length] = '\0'; 77 78 *_id = entry.InodeID(); 79 *_nameLength = length; 80 81 fOffset += entry.Length(); 82 } 83 84 return status; 85 } 86 87 88 status_t 89 DirectoryIterator::Rewind() 90 { 91 fOffset = 0; 92 return B_OK; 93 } 94