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