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
24DirectoryIterator::DirectoryIterator(Inode* inode)
25	:
26	fInode(inode)
27{
28	fOffset = 0;
29}
30
31
32DirectoryIterator::~DirectoryIterator()
33{
34}
35
36
37status_t
38DirectoryIterator::InitCheck()
39{
40	return B_OK;
41}
42
43
44status_t
45DirectoryIterator::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
67status_t
68DirectoryIterator::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
94status_t
95DirectoryIterator::Rewind()
96{
97	fOffset = 0;
98	return B_OK;
99}
100