xref: /haiku/src/kits/storage/SymLink.cpp (revision e1b7c1c7ac1188a3b3e1694a958042468b95e781)
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.
BSymLink()28 BSymLink::BSymLink()
29 {
30 }
31 
32 
33 // Creates a copy of the supplied BSymLink object.
BSymLink(const BSymLink & other)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.
BSymLink(const entry_ref * 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.
BSymLink(const BEntry * entry)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.
BSymLink(const char * path)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.
BSymLink(const BDirectory * dir,const char * path)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.
~BSymLink()77 BSymLink::~BSymLink()
78 {
79 }
80 
81 
82 // Reads the contents of the symbolic link into a buffer.
83 ssize_t
ReadLink(char * buffer,size_t size)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 	if (linkLen < size)
98 		buffer[linkLen] = '\0';
99 	else if (size > 0)
100 		buffer[size - 1] = '\0';
101 
102 	return linkLen;
103 }
104 
105 
106 // Combines a directory path and the contents of this symbolic link to form an
107 // absolute path.
108 ssize_t
MakeLinkedPath(const char * dirPath,BPath * path)109 BSymLink::MakeLinkedPath(const char* dirPath, BPath* path)
110 {
111 	// BeOS seems to convert the dirPath to a BDirectory, which causes links
112 	// to be resolved. This means that the dirPath must exist!
113 	if (dirPath == NULL || path == NULL)
114 		return B_BAD_VALUE;
115 
116 	BDirectory dir(dirPath);
117 	ssize_t result = dir.InitCheck();
118 	if (result == B_OK)
119 		result = MakeLinkedPath(&dir, path);
120 
121 	return result;
122 }
123 
124 
125 // Combines a directory path and the contents of this symbolic link to form an
126 // absolute path.
127 ssize_t
MakeLinkedPath(const BDirectory * dir,BPath * path)128 BSymLink::MakeLinkedPath(const BDirectory* dir, BPath* path)
129 {
130 	if (dir == NULL || path == NULL)
131 		return B_BAD_VALUE;
132 
133 	char contents[B_PATH_NAME_LENGTH];
134 	ssize_t result = ReadLink(contents, sizeof(contents));
135 	if (result >= 0) {
136 		if (BPrivate::Storage::is_absolute_path(contents))
137 			result = path->SetTo(contents);
138 		else
139 			result = path->SetTo(dir, contents);
140 
141 		if (result == B_OK)
142 			result = strlen(path->Path());
143 	}
144 
145 	return result;
146 }
147 
148 
149 // Returns whether or not the object refers to an absolute path.
150 bool
IsAbsolute()151 BSymLink::IsAbsolute()
152 {
153 	char contents[B_PATH_NAME_LENGTH];
154 	bool result = (ReadLink(contents, sizeof(contents)) >= 0);
155 	if (result)
156 		result = BPrivate::Storage::is_absolute_path(contents);
157 
158 	return result;
159 }
160 
161 
_MissingSymLink1()162 void BSymLink::_MissingSymLink1() {}
_MissingSymLink2()163 void BSymLink::_MissingSymLink2() {}
_MissingSymLink3()164 void BSymLink::_MissingSymLink3() {}
_MissingSymLink4()165 void BSymLink::_MissingSymLink4() {}
_MissingSymLink5()166 void BSymLink::_MissingSymLink5() {}
_MissingSymLink6()167 void BSymLink::_MissingSymLink6() {}
168 
169 
170 /*!	Returns the file descriptor of the BSymLink.
171 
172 	This method should be used instead of accessing the private \c fFd member
173 	of the BNode directly.
174 
175 	\return The object's file descriptor, or -1 if not properly initialized.
176 */
177 int
get_fd() const178 BSymLink::get_fd() const
179 {
180 	return fFd;
181 }
182