1 /* 2 * Copyright 2020 Suhel Mehta, mehtasuhel@gmail.com 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "DirectoryIterator.h" 8 9 #include <stdlib.h> 10 #include <string.h> 11 12 #include "Inode.h" 13 14 #define TRACE_UFS2 15 #ifdef TRACE_UFS2 16 # define TRACE(x...) dprintf("\33[34mufs2:\33[0m " x) 17 #else 18 # define TRACE(x...) ; 19 #endif 20 21 #define ERROR(x...) dprintf("\33[34mufs2:\33[0m " x) 22 23 24 DirectoryIterator::DirectoryIterator(Inode* inode) 25 : 26 fInode(inode) 27 { 28 fOffset = 0; 29 } 30 31 32 DirectoryIterator::~DirectoryIterator() 33 { 34 } 35 36 37 status_t 38 DirectoryIterator::InitCheck() 39 { 40 return B_OK; 41 } 42 43 44 status_t 45 DirectoryIterator::Lookup(const char* name, ino_t* _id) 46 { 47 if (strcmp(name, ".") == 0) { 48 *_id = fInode->ID(); 49 return B_OK; 50 } 51 52 char getname[B_FILE_NAME_LENGTH + 1]; 53 54 status_t status; 55 while(true) { 56 size_t len = sizeof (getname) - 1; 57 status = GetNext(getname, &len, _id); 58 if (status != B_OK) 59 return status; 60 if (strcmp(getname, name) == 0) 61 return B_OK; 62 } 63 64 } 65 66 67 status_t 68 DirectoryIterator::GetNext(char* name, size_t* _nameLength, ino_t* _id) 69 { 70 dir direct; 71 size_t size = sizeof(dir); 72 status_t status = fInode->ReadAt(fOffset, (uint8_t*)&direct, &size); 73 if (size < 8 || direct.reclen < 8) 74 return B_ENTRY_NOT_FOUND; 75 if (status == B_OK) { 76 fOffset += direct.reclen; 77 78 if (direct.next_ino > 0) { 79 if ((size_t) (direct.namlen + 1) > *_nameLength) 80 return B_BUFFER_OVERFLOW; 81 strlcpy(name, direct.name, direct.namlen + 1); 82 *_id = direct.next_ino; 83 *_nameLength = direct.namlen; 84 return B_OK; 85 } 86 87 return B_ENTRY_NOT_FOUND; 88 } 89 90 return B_ERROR; 91 } 92 93 94 status_t 95 DirectoryIterator::Rewind() 96 { 97 fOffset = 0; 98 return B_OK; 99 } 100