xref: /haiku/src/add-ons/kernel/file_systems/netfs/client/ShareNode.cpp (revision 71452e98334eaac603bf542d159e24788a46bebb)
1 // ShareNode.cpp
2 
3 #include "ShareNode.h"
4 
5 #include "ShareAttrDir.h"
6 
7 // constructor
8 ShareDirEntry::ShareDirEntry(ShareDir* directory, const char* name,
9 	ShareNode* node)
10 	:
11 	BReferenceable(),
12 	fDirectory(directory),
13 	fName(name),
14 	fNode(node),
15 	fRevision(-1)
16 {
17 }
18 
19 // destructor
20 ShareDirEntry::~ShareDirEntry()
21 {
22 }
23 
24 // InitCheck
25 status_t
26 ShareDirEntry::InitCheck() const
27 {
28 	if (fName.GetLength() == 0)
29 		return B_NO_MEMORY;
30 
31 	return B_OK;
32 }
33 
34 // GetDirectory
35 ShareDir*
36 ShareDirEntry::GetDirectory() const
37 {
38 	return fDirectory;
39 }
40 
41 // GetName
42 const char*
43 ShareDirEntry::GetName() const
44 {
45 	return fName.GetString();
46 }
47 
48 // GetNode
49 ShareNode*
50 ShareDirEntry::GetNode() const
51 {
52 	return fNode;
53 }
54 
55 // SetRevision
56 void
57 ShareDirEntry::SetRevision(int64 revision)
58 {
59 	fRevision = revision;
60 }
61 
62 // GetRevision
63 int64
64 ShareDirEntry::GetRevision() const
65 {
66 	return fRevision;
67 }
68 
69 // IsActualEntry
70 bool
71 ShareDirEntry::IsActualEntry() const
72 {
73 	return (fName.GetLength() > 0 && fName != "." && fName != "..");
74 }
75 
76 
77 // #pragma mark -
78 
79 // constructor
80 ShareNode::ShareNode(Volume* volume, vnode_id id, const NodeInfo* nodeInfo)
81 	:
82 	Node(volume, id),
83 	fInfo(),
84 	fReferringEntries(),
85 	fAttrDir(NULL)
86 {
87 	if (nodeInfo) {
88 		fInfo = *nodeInfo;
89 	} else {
90 		// init the stat data at least a bit, if no node info is given
91 		fInfo.st.st_dev = -1;
92 		fInfo.st.st_ino = -1;
93 		fInfo.st.st_mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP
94 			| S_IROTH | S_IXOTH;
95 		fInfo.st.st_nlink = 1;
96 		fInfo.st.st_size = 1;
97 		fInfo.st.st_blksize = 1024;
98 		fInfo.st.st_crtime = 0;
99 		fInfo.st.st_ctime = fInfo.st.st_mtime = fInfo.st.st_atime
100 			= fInfo.st.st_crtime;
101 
102 		// negative revision, to make sure it is updated
103 		fInfo.revision = -1;
104 	}
105 }
106 
107 // destructor
108 ShareNode::~ShareNode()
109 {
110 	delete fAttrDir;
111 }
112 
113 // GetNodeInfo
114 const NodeInfo&
115 ShareNode::GetNodeInfo() const
116 {
117 	return fInfo;
118 }
119 
120 // GetRemoteID
121 NodeID
122 ShareNode::GetRemoteID() const
123 {
124 	return fInfo.GetID();
125 }
126 
127 // Update
128 void
129 ShareNode::Update(const NodeInfo& nodeInfo)
130 {
131 	if (fInfo.revision < nodeInfo.revision)
132 		fInfo = nodeInfo;
133 }
134 
135 // AddReferringEntry
136 void
137 ShareNode::AddReferringEntry(ShareDirEntry* entry)
138 {
139 	if (entry)
140 		fReferringEntries.Insert(entry);
141 }
142 
143 // RemoveReferringEntry
144 void
145 ShareNode::RemoveReferringEntry(ShareDirEntry* entry)
146 {
147 	if (entry)
148 		fReferringEntries.Remove(entry);
149 }
150 
151 // GetFirstReferringEntry
152 ShareDirEntry*
153 ShareNode::GetFirstReferringEntry() const
154 {
155 	return fReferringEntries.GetFirst();
156 }
157 
158 // GetNextReferringEntry
159 ShareDirEntry*
160 ShareNode::GetNextReferringEntry(ShareDirEntry* entry) const
161 {
162 	return (entry ? fReferringEntries.GetNext(entry) : NULL);
163 }
164 
165 // GetActualReferringEntry
166 ShareDirEntry*
167 ShareNode::GetActualReferringEntry() const
168 {
169 	for (ShareDirEntry* entry = GetFirstReferringEntry();
170 		 entry;
171 		 entry = GetNextReferringEntry(entry)) {
172 		if (entry->IsActualEntry())
173 			return entry;
174 	}
175 
176 	return NULL;
177 }
178 
179 // SetAttrDir
180 void
181 ShareNode::SetAttrDir(ShareAttrDir* attrDir)
182 {
183 	delete fAttrDir;
184 	fAttrDir = attrDir;
185 }
186 
187 // GetAttrDir
188 ShareAttrDir*
189 ShareNode::GetAttrDir() const
190 {
191 	return fAttrDir;
192 }
193 
194 
195 // #pragma mark -
196 
197 // constructor
198 ShareDirIterator::ShareDirIterator()
199 {
200 }
201 
202 // destructor
203 ShareDirIterator::~ShareDirIterator()
204 {
205 }
206 
207 
208 // #pragma mark -
209 
210 // constructor
211 LocalShareDirIterator::LocalShareDirIterator()
212 	: fDirectory(NULL),
213 	  fCurrentEntry(NULL)
214 {
215 }
216 
217 // destructor
218 LocalShareDirIterator::~LocalShareDirIterator()
219 {
220 	SetDirectory(NULL);
221 }
222 
223 // SetDirectory
224 void
225 LocalShareDirIterator::SetDirectory(ShareDir* directory)
226 {
227 	// unset the old directory
228 	if (fDirectory)
229 		fDirectory->RemoveDirIterator(this);
230 
231 	// set the new directory
232 	fDirectory = directory;
233 	if (fDirectory) {
234 		fDirectory->AddDirIterator(this);
235 		fCurrentEntry = fDirectory->GetFirstEntry();
236 	}
237 }
238 
239 // GetCurrentEntry
240 ShareDirEntry*
241 LocalShareDirIterator::GetCurrentEntry() const
242 {
243 	return fCurrentEntry;
244 }
245 
246 // NextEntry
247 void
248 LocalShareDirIterator::NextEntry()
249 {
250 	if (!fDirectory || !fCurrentEntry)
251 		return;
252 
253 	fCurrentEntry = fDirectory->GetNextEntry(fCurrentEntry);
254 }
255 
256 // Rewind
257 void
258 LocalShareDirIterator::Rewind()
259 {
260 	fCurrentEntry = (fDirectory ? fDirectory->GetFirstEntry() : NULL);
261 }
262 
263 // IsDone
264 bool
265 LocalShareDirIterator::IsDone() const
266 {
267 	return !fCurrentEntry;
268 }
269 
270 
271 // #pragma mark -
272 
273 // constructor
274 RemoteShareDirIterator::RemoteShareDirIterator()
275 	: fCookie(-1),
276 	  fCapacity(kRemoteShareDirIteratorCapacity),
277 	  fCount(0),
278 	  fIndex(0),
279 	  fRevision(-1),
280 	  fDone(false),
281 	  fRewind(false)
282 {
283 }
284 
285 // destructor
286 RemoteShareDirIterator::~RemoteShareDirIterator()
287 {
288 	Clear();
289 }
290 
291 // GetCurrentEntry
292 ShareDirEntry*
293 RemoteShareDirIterator::GetCurrentEntry() const
294 {
295 	return (!fRewind && fIndex < fCount ? fEntries[fIndex] : NULL);
296 }
297 
298 // NextEntry
299 void
300 RemoteShareDirIterator::NextEntry()
301 {
302 	if (fIndex < fCount)
303 		fIndex++;
304 }
305 
306 // Rewind
307 void
308 RemoteShareDirIterator::Rewind()
309 {
310 	fRewind = true;
311 	fDone = false;
312 }
313 
314 // IsDone
315 bool
316 RemoteShareDirIterator::IsDone() const
317 {
318 	return fDone;
319 }
320 
321 // GetCapacity
322 int32
323 RemoteShareDirIterator::GetCapacity() const
324 {
325 	return fCapacity;
326 }
327 
328 // SetCookie
329 void
330 RemoteShareDirIterator::SetCookie(int32 cookie)
331 {
332 	fCookie = cookie;
333 }
334 
335 // GetCookie
336 int32
337 RemoteShareDirIterator::GetCookie() const
338 {
339 	return fCookie;
340 }
341 
342 // Clear
343 void
344 RemoteShareDirIterator::Clear()
345 {
346 	for (int32 i = 0; i < fCount; i++)
347 		fEntries[i]->ReleaseReference();
348 	fCount = 0;
349 	fIndex = 0;
350 	fDone = false;
351 	fRewind = false;
352 }
353 
354 // AddEntry
355 bool
356 RemoteShareDirIterator::AddEntry(ShareDirEntry* entry)
357 {
358 	if (!entry || fCount >= fCapacity)
359 		return false;
360 
361 	fEntries[fCount++] = entry;
362 	entry->AcquireReference();
363 	return true;
364 }
365 
366 // SetRevision
367 void
368 RemoteShareDirIterator::SetRevision(int64 revision)
369 {
370 	fRevision = revision;
371 }
372 
373 // GetRevision
374 int64
375 RemoteShareDirIterator::GetRevision() const
376 {
377 	return fRevision;
378 }
379 
380 // SetDone
381 void
382 RemoteShareDirIterator::SetDone(bool done)
383 {
384 	fDone = done;
385 }
386 
387 // GetRewind
388 bool
389 RemoteShareDirIterator::GetRewind() const
390 {
391 	return fRewind;
392 }
393 
394 
395 // #pragma mark -
396 
397 // constructor
398 ShareDir::ShareDir(Volume* volume, vnode_id id, const NodeInfo* nodeInfo)
399 	: ShareNode(volume, id, nodeInfo),
400 	  fEntries(),
401 	  fIterators(),
402 	  fEntryCreatedEventRevision(-1),
403 	  fEntryRemovedEventRevision(-1),
404 	  fIsComplete(false)
405 {
406 }
407 
408 // destructor
409 ShareDir::~ShareDir()
410 {
411 }
412 
413 // UpdateEntryCreatedEventRevision
414 void
415 ShareDir::UpdateEntryCreatedEventRevision(int64 revision)
416 {
417 	if (revision > fEntryCreatedEventRevision)
418 		fEntryCreatedEventRevision = revision;
419 }
420 
421 // GetEntryCreatedEventRevision
422 int64
423 ShareDir::GetEntryCreatedEventRevision() const
424 {
425 	return fEntryCreatedEventRevision;
426 }
427 
428 // UpdateEntryRemovedEventRevision
429 void
430 ShareDir::UpdateEntryRemovedEventRevision(int64 revision)
431 {
432 	if (revision > fEntryRemovedEventRevision)
433 		fEntryRemovedEventRevision = revision;
434 }
435 
436 // GetEntryRemovedEventRevision
437 int64
438 ShareDir::GetEntryRemovedEventRevision() const
439 {
440 	return fEntryRemovedEventRevision;
441 }
442 
443 // SetComplete
444 void
445 ShareDir::SetComplete(bool complete)
446 {
447 	fIsComplete = complete;
448 }
449 
450 // IsComplete
451 bool
452 ShareDir::IsComplete() const
453 {
454 	return fIsComplete;
455 }
456 
457 // AddEntry
458 void
459 ShareDir::AddEntry(ShareDirEntry* entry)
460 {
461 	if (entry)
462 		fEntries.Insert(entry);
463 }
464 
465 // RemoveEntry
466 void
467 ShareDir::RemoveEntry(ShareDirEntry* entry)
468 {
469 	if (entry) {
470 		// update the directory iterators pointing to the removed entry
471 		for (LocalShareDirIterator* iterator = fIterators.First();
472 			 iterator;
473 			 iterator = fIterators.GetNext(iterator)) {
474 			if (iterator->GetCurrentEntry() == entry)
475 				iterator->NextEntry();
476 		}
477 
478 		fEntries.Remove(entry);
479 	}
480 }
481 
482 // GetFirstEntry
483 ShareDirEntry*
484 ShareDir::GetFirstEntry() const
485 {
486 	return fEntries.First();
487 }
488 
489 // GetNextEntry
490 ShareDirEntry*
491 ShareDir::GetNextEntry(ShareDirEntry* entry) const
492 {
493 	if (!entry)
494 		return NULL;
495 
496 	return fEntries.GetNext(entry);
497 }
498 
499 // AddDirIterator
500 void
501 ShareDir::AddDirIterator(LocalShareDirIterator* iterator)
502 {
503 	if (!iterator)
504 		return;
505 
506 	fIterators.Insert(iterator);
507 }
508 
509 // RemoveDirIterator
510 void
511 ShareDir::RemoveDirIterator(LocalShareDirIterator* iterator)
512 {
513 	if (!iterator)
514 		return;
515 
516 	fIterators.Remove(iterator);
517 }
518 
519