1 //---------------------------------------------------------------------- 2 // This software is part of the Haiku distribution and is covered 3 // by the MIT license. 4 //--------------------------------------------------------------------- 5 /*! 6 \file SymLink.cpp 7 BSymLink implementation. 8 */ 9 10 #include <new> 11 12 #include <SymLink.h> 13 #include <Directory.h> 14 #include <Entry.h> 15 #include <Path.h> 16 17 #include <syscalls.h> 18 19 #include "storage_support.h" 20 21 using namespace std; 22 23 #ifdef USE_OPENBEOS_NAMESPACE 24 namespace OpenBeOS { 25 #endif 26 27 // constructor 28 //! Creates an uninitialized BSymLink object. 29 BSymLink::BSymLink() 30 : BNode() 31 { 32 } 33 34 // copy constructor 35 //! Creates a copy of the supplied BSymLink. 36 /*! \param link the BSymLink object to be copied 37 */ 38 BSymLink::BSymLink(const BSymLink &link) 39 : BNode(link) 40 { 41 } 42 43 // constructor 44 /*! \brief Creates a BSymLink and initializes it to the symbolic link referred 45 to by the supplied entry_ref. 46 \param ref the entry_ref referring to the symbolic link 47 */ 48 BSymLink::BSymLink(const entry_ref *ref) 49 : BNode(ref) 50 { 51 } 52 53 // constructor 54 /*! \brief Creates a BSymLink and initializes it to the symbolic link referred 55 to by the supplied BEntry. 56 \param entry the BEntry referring to the symbolic link 57 */ 58 BSymLink::BSymLink(const BEntry *entry) 59 : BNode(entry) 60 { 61 } 62 63 // constructor 64 /*! \brief Creates a BSymLink and initializes it to the symbolic link referred 65 to by the supplied path name. 66 \param path the symbolic link's path name 67 */ 68 BSymLink::BSymLink(const char *path) 69 : BNode(path) 70 { 71 } 72 73 // constructor 74 /*! \brief Creates a BSymLink and initializes it to the symbolic link referred 75 to by the supplied path name relative to the specified BDirectory. 76 \param dir the BDirectory, relative to which the symbolic link's path name 77 is given 78 \param path the symbolic link's path name relative to \a dir 79 */ 80 BSymLink::BSymLink(const BDirectory *dir, const char *path) 81 : BNode(dir, path) 82 { 83 } 84 85 // destructor 86 //! Frees all allocated resources. 87 /*! If the BSymLink is properly initialized, the symbolic link's file 88 descriptor is closed. 89 */ 90 BSymLink::~BSymLink() 91 { 92 } 93 94 // ReadLink 95 //! Reads the contents of the symbolic link into a buffer. 96 /*! The string written to the buffer will be null-terminated. 97 \param buf the buffer 98 \param size the size of the buffer 99 \return 100 - the number of bytes written into the buffer 101 - \c B_BAD_VALUE: \c NULL \a buf or the object doesn't refer to a symbolic 102 link. 103 - \c B_FILE_ERROR: The object is not initialized. 104 - some other error code 105 */ 106 ssize_t 107 BSymLink::ReadLink(char *buffer, size_t size) 108 { 109 if (!buffer) 110 return B_BAD_VALUE; 111 if (InitCheck() != B_OK) 112 return B_FILE_ERROR; 113 114 size_t linkLen = size; 115 status_t error = _kern_read_link(get_fd(), NULL, buffer, &linkLen); 116 if (error < B_OK) 117 return error; 118 119 // null-terminate 120 if (linkLen >= size) 121 return B_BUFFER_OVERFLOW; 122 buffer[linkLen] = '\0'; 123 124 return linkLen; 125 } 126 127 // MakeLinkedPath 128 /*! \brief Combines a directory path and the contents of this symbolic link to 129 an absolute path. 130 \param dirPath the path name of the directory 131 \param path the BPath object to be set to the resulting path name 132 \return 133 - \c the length of the resulting path name, 134 - \c B_BAD_VALUE: \c NULL \a dirPath or \a path or the object doesn't 135 refer to a symbolic link. 136 - \c B_FILE_ERROR: The object is not initialized. 137 - \c B_NAME_TOO_LONG: The resulting path name is too long. 138 - some other error code 139 */ 140 ssize_t 141 BSymLink::MakeLinkedPath(const char *dirPath, BPath *path) 142 { 143 // R5 seems to convert the dirPath to a BDirectory, which causes links to 144 // be resolved, i.e. a "/tmp" dirPath expands to "/boot/var/tmp". 145 // That does also mean, that the dirPath must exists! 146 if (!dirPath || !path) 147 return B_BAD_VALUE; 148 BDirectory dir(dirPath); 149 ssize_t result = dir.InitCheck(); 150 if (result == B_OK) 151 result = MakeLinkedPath(&dir, path); 152 return result; 153 } 154 155 // MakeLinkedPath 156 /*! \brief Combines a directory path and the contents of this symbolic link to 157 an absolute path. 158 \param dir the BDirectory referring to the directory 159 \param path the BPath object to be set to the resulting path name 160 \return 161 - \c the length of the resulting path name, 162 - \c B_BAD_VALUE: \c NULL \a dir or \a path or the object doesn't 163 refer to a symbolic link. 164 - \c B_FILE_ERROR: The object is not initialized. 165 - \c B_NAME_TOO_LONG: The resulting path name is too long. 166 - some other error code 167 */ 168 ssize_t 169 BSymLink::MakeLinkedPath(const BDirectory *dir, BPath *path) 170 { 171 if (!dir || !path) 172 return B_BAD_VALUE; 173 char contents[B_PATH_NAME_LENGTH]; 174 ssize_t result = ReadLink(contents, sizeof(contents)); 175 if (result >= 0) { 176 if (BPrivate::Storage::is_absolute_path(contents)) 177 result = path->SetTo(contents); 178 else 179 result = path->SetTo(dir, contents); 180 if (result == B_OK) 181 result = strlen(path->Path()); 182 } 183 return result; 184 } 185 186 // IsAbsolute 187 //! Returns whether this BSymLink refers to an absolute link. 188 /*! /return 189 - \c true, if the object is properly initialized and the symbolic link it 190 refers to is an absolute link, 191 - \c false, otherwise. 192 */ 193 bool 194 BSymLink::IsAbsolute() 195 { 196 char contents[B_PATH_NAME_LENGTH]; 197 bool result = (ReadLink(contents, sizeof(contents)) >= 0); 198 if (result) 199 result = BPrivate::Storage::is_absolute_path(contents); 200 return result; 201 } 202 203 204 void BSymLink::_MissingSymLink1() {} 205 void BSymLink::_MissingSymLink2() {} 206 void BSymLink::_MissingSymLink3() {} 207 void BSymLink::_MissingSymLink4() {} 208 void BSymLink::_MissingSymLink5() {} 209 void BSymLink::_MissingSymLink6() {} 210 211 //! Returns the BSymLink's file descriptor. 212 /*! To be used instead of accessing the BNode's private \c fFd member directly. 213 \return the file descriptor, or -1, if not properly initialized. 214 */ 215 int 216 BSymLink::get_fd() const 217 { 218 return fFd; 219 } 220 221 222 #ifdef USE_OPENBEOS_NAMESPACE 223 }; // namespace OpenBeOS 224 #endif 225 226