1 /*
2 * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7 #include "SymLink.h"
8
9 #include <string.h>
10
11 #include "Block.h"
12 #include "DebugSupport.h"
13
14
15 static const size_t kSymLinkDataOffset = sizeof(checksumfs_node);
16 static const size_t kMaxSymLinkSize = B_PAGE_SIZE - kSymLinkDataOffset;
17
18
SymLink(Volume * volume,uint64 blockIndex,const checksumfs_node & nodeData)19 SymLink::SymLink(Volume* volume, uint64 blockIndex,
20 const checksumfs_node& nodeData)
21 :
22 Node(volume, blockIndex, nodeData)
23 {
24 }
25
26
SymLink(Volume * volume,mode_t mode)27 SymLink::SymLink(Volume* volume, mode_t mode)
28 :
29 Node(volume, mode)
30 {
31 }
32
33
~SymLink()34 SymLink::~SymLink()
35 {
36 }
37
38
39 status_t
ReadSymLink(char * buffer,size_t toRead,size_t & _bytesRead)40 SymLink::ReadSymLink(char* buffer, size_t toRead, size_t& _bytesRead)
41 {
42 uint64 size = Size();
43 if (size > kMaxSymLinkSize)
44 RETURN_ERROR(B_BAD_DATA);
45
46 if (toRead > size)
47 toRead = size;
48
49 if (toRead == 0) {
50 _bytesRead = 0;
51 return B_OK;
52 }
53
54 // get the block
55 Block block;
56 if (!block.GetReadable(GetVolume(), BlockIndex()))
57 RETURN_ERROR(B_ERROR);
58
59 const char* data = (char*)block.Data() + kSymLinkDataOffset;
60 memcpy(buffer, data, toRead);
61
62 _bytesRead = toRead;
63 return B_OK;
64 }
65
66
67 status_t
WriteSymLink(const char * buffer,size_t toWrite,Transaction & transaction)68 SymLink::WriteSymLink(const char* buffer, size_t toWrite,
69 Transaction& transaction)
70 {
71 uint64 size = Size();
72 if (size > kMaxSymLinkSize)
73 RETURN_ERROR(B_BAD_DATA);
74
75 if (toWrite > kMaxSymLinkSize)
76 RETURN_ERROR(B_NAME_TOO_LONG);
77
78 if (toWrite == 0) {
79 SetSize(0);
80 return B_OK;
81 }
82
83 Block block;
84 if (!block.GetWritable(GetVolume(), BlockIndex(), transaction))
85 return B_ERROR;
86
87 char* data = (char*)block.Data() + kSymLinkDataOffset;
88 memcpy(data, buffer, toWrite);
89 SetSize(toWrite);
90
91 return B_OK;
92 }
93