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