xref: /haiku/src/kits/storage/SymLink.cpp (revision 1e60bdeab63fa7a57bc9a55b032052e95a18bd2c)
1 /*
2  * Copyright 2002-2009 Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Tyler Dauwalder
7  *		Ingo Weinhold, ingo_weinhold@gmx.de
8  */
9 
10 
11 #include <new>
12 #include <string.h>
13 
14 #include <SymLink.h>
15 #include <Directory.h>
16 #include <Entry.h>
17 #include <Path.h>
18 
19 #include <syscalls.h>
20 
21 #include "storage_support.h"
22 
23 
24 using namespace std;
25 
26 
27 // Creates an uninitialized BSymLink object.
28 BSymLink::BSymLink()
29 {
30 }
31 
32 
33 // Creates a copy of the supplied BSymLink object.
34 BSymLink::BSymLink(const BSymLink& other)
35 	:
36 	BNode(other)
37 {
38 }
39 
40 
41 // Creates a BSymLink object and initializes it to the symbolic link referred
42 // to by the supplied entry_ref.
43 BSymLink::BSymLink(const entry_ref* ref)
44 	:
45 	BNode(ref)
46 {
47 }
48 
49 
50 // Creates a BSymLink object and initializes it to the symbolic link referred
51 // to by the supplied BEntry.
52 BSymLink::BSymLink(const BEntry* entry)
53 		: BNode(entry)
54 {
55 }
56 
57 
58 // Creates a BSymLink object and initializes it to the symbolic link referred
59 // to by the supplied path name.
60 BSymLink::BSymLink(const char* path)
61 	:
62 	BNode(path)
63 {
64 }
65 
66 
67 // Creates a BSymLink object and initializes it to the symbolic link referred
68 // to by the supplied path name relative to the specified BDirectory.
69 BSymLink::BSymLink(const BDirectory* dir, const char* path)
70 	:
71 	BNode(dir, path)
72 {
73 }
74 
75 
76 // Destroys the object and frees all allocated resources.
77 BSymLink::~BSymLink()
78 {
79 }
80 
81 
82 // Reads the contents of the symbolic link into a buffer.
83 ssize_t
84 BSymLink::ReadLink(char* buffer, size_t size)
85 {
86 	if (buffer == NULL)
87 		return B_BAD_VALUE;
88 
89 	if (InitCheck() != B_OK)
90 		return B_FILE_ERROR;
91 
92 	size_t linkLen = size;
93 	status_t result = _kern_read_link(get_fd(), NULL, buffer, &linkLen);
94 	if (result < B_OK)
95 		return result;
96 
97 	// null-terminate
98 	if (linkLen >= size)
99 		return B_BUFFER_OVERFLOW;
100 
101 	buffer[linkLen] = '\0';
102 
103 	return linkLen;
104 }
105 
106 
107 // Combines a directory path and the contents of this symbolic link to form an
108 // absolute path.
109 ssize_t
110 BSymLink::MakeLinkedPath(const char* dirPath, BPath* path)
111 {
112 	// BeOS seems to convert the dirPath to a BDirectory, which causes links
113 	// to be resolved. This means that the dirPath must exist!
114 	if (dirPath == NULL || path == NULL)
115 		return B_BAD_VALUE;
116 
117 	BDirectory dir(dirPath);
118 	ssize_t result = dir.InitCheck();
119 	if (result == B_OK)
120 		result = MakeLinkedPath(&dir, path);
121 
122 	return result;
123 }
124 
125 
126 // Combines a directory path and the contents of this symbolic link to form an
127 // absolute path.
128 ssize_t
129 BSymLink::MakeLinkedPath(const BDirectory* dir, BPath* path)
130 {
131 	if (dir == NULL || path == NULL)
132 		return B_BAD_VALUE;
133 
134 	char contents[B_PATH_NAME_LENGTH];
135 	ssize_t result = ReadLink(contents, sizeof(contents));
136 	if (result >= 0) {
137 		if (BPrivate::Storage::is_absolute_path(contents))
138 			result = path->SetTo(contents);
139 		else
140 			result = path->SetTo(dir, contents);
141 
142 		if (result == B_OK)
143 			result = strlen(path->Path());
144 	}
145 
146 	return result;
147 }
148 
149 
150 // Returns whether or not the object refers to an absolute path.
151 bool
152 BSymLink::IsAbsolute()
153 {
154 	char contents[B_PATH_NAME_LENGTH];
155 	bool result = (ReadLink(contents, sizeof(contents)) >= 0);
156 	if (result)
157 		result = BPrivate::Storage::is_absolute_path(contents);
158 
159 	return result;
160 }
161 
162 
163 void BSymLink::_MissingSymLink1() {}
164 void BSymLink::_MissingSymLink2() {}
165 void BSymLink::_MissingSymLink3() {}
166 void BSymLink::_MissingSymLink4() {}
167 void BSymLink::_MissingSymLink5() {}
168 void BSymLink::_MissingSymLink6() {}
169 
170 
171 /*!	Returns the file descriptor of the BSymLink.
172 
173 	This method should be used instead of accessing the private \c fFd member
174 	of the BNode directly.
175 
176 	\return The object's file descriptor, or -1 if not properly initialized.
177 */
178 int
179 BSymLink::get_fd() const
180 {
181 	return fFd;
182 }
183