1/*
2 * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * All rights reserved. Distributed under the terms of the MIT license.
4 */
5
6#include <limits.h>
7
8#include "AllocationInfo.h"
9#include "DebugSupport.h"
10#include "SizeIndex.h"
11#include "SymLink.h"
12#include "Volume.h"
13
14// constructor
15SymLink::SymLink(Volume *volume)
16	: Node(volume, NODE_TYPE_SYMLINK),
17	  fLinkedPath()
18{
19}
20
21// destructor
22SymLink::~SymLink()
23{
24}
25
26// SetSize
27status_t
28SymLink::SetSize(off_t newSize)
29{
30	status_t error = (newSize >= 0 && newSize < PATH_MAX ? B_OK : B_BAD_VALUE);
31	int32 oldSize = GetLinkedPathLength();
32	if (error == B_OK && newSize < oldSize) {
33		fLinkedPath.Truncate(newSize);
34		MarkModified(B_STAT_SIZE);
35		// update the size index
36		if (SizeIndex *index = GetVolume()->GetSizeIndex())
37			index->Changed(this, oldSize);
38	}
39	return error;
40}
41
42// GetSize
43off_t
44SymLink::GetSize() const
45{
46	return GetLinkedPathLength();
47}
48
49// SetLinkedPath
50status_t
51SymLink::SetLinkedPath(const char *path)
52{
53	int32 oldLen = GetLinkedPathLength();
54	int32 len = strnlen(path, PATH_MAX - 1);
55	if (fLinkedPath.SetTo(path, len)) {
56		MarkModified(B_STAT_MODIFICATION_TIME);
57		// update the size index, if necessary
58		if (len != oldLen) {
59			MarkModified(B_STAT_SIZE);
60
61			if (SizeIndex *index = GetVolume()->GetSizeIndex())
62				index->Changed(this, oldLen);
63		}
64		return B_OK;
65	}
66	RETURN_ERROR(B_NO_MEMORY);
67}
68
69// GetAllocationInfo
70void
71SymLink::GetAllocationInfo(AllocationInfo &info)
72{
73	info.AddSymLinkAllocation(GetSize());
74}
75
76