xref: /haiku/src/kits/storage/SymLink.cpp (revision 2b76973fa2401f7a5edf68e6470f3d3210cbcff3)
1 /*
2  * Copyright 2002-2009, Haiku Inc.
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 &link)
35 	:
36 	BNode(link)
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 error = _kern_read_link(get_fd(), NULL, buffer, &linkLen);
94 	if (error < B_OK)
95 		return error;
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 int
173 BSymLink::get_fd() const
174 {
175 	return fFd;
176 }
177