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 /*! \param buf the buffer 97 \param size the size of the buffer 98 \return 99 - the number of bytes written into the buffer 100 - \c B_BAD_VALUE: \c NULL \a buf or the object doesn't refer to a symbolic 101 link. 102 - \c B_FILE_ERROR: The object is not initialized. 103 - some other error code 104 */ 105 ssize_t 106 BSymLink::ReadLink(char *buffer, size_t size) 107 { 108 if (!buffer) 109 return B_BAD_VALUE; 110 if (InitCheck() != B_OK) 111 return B_FILE_ERROR; 112 113 status_t error = _kern_read_link(get_fd(), NULL, buffer, &size); 114 if (error < B_OK) 115 return error; 116 117 return size; 118 } 119 120 // MakeLinkedPath 121 /*! \brief Combines a directory path and the contents of this symbolic link to 122 an absolute path. 123 \param dirPath the path name of the directory 124 \param path the BPath object to be set to the resulting path name 125 \return 126 - \c the length of the resulting path name, 127 - \c B_BAD_VALUE: \c NULL \a dirPath or \a path or the object doesn't 128 refer to a symbolic link. 129 - \c B_FILE_ERROR: The object is not initialized. 130 - \c B_NAME_TOO_LONG: The resulting path name is too long. 131 - some other error code 132 */ 133 ssize_t 134 BSymLink::MakeLinkedPath(const char *dirPath, BPath *path) 135 { 136 // R5 seems to convert the dirPath to a BDirectory, which causes links to 137 // be resolved, i.e. a "/tmp" dirPath expands to "/boot/var/tmp". 138 // That does also mean, that the dirPath must exists! 139 if (!dirPath || !path) 140 return B_BAD_VALUE; 141 BDirectory dir(dirPath); 142 ssize_t result = dir.InitCheck(); 143 if (result == B_OK) 144 result = MakeLinkedPath(&dir, path); 145 return result; 146 } 147 148 // MakeLinkedPath 149 /*! \brief Combines a directory path and the contents of this symbolic link to 150 an absolute path. 151 \param dir the BDirectory referring to the directory 152 \param path the BPath object to be set to the resulting path name 153 \return 154 - \c the length of the resulting path name, 155 - \c B_BAD_VALUE: \c NULL \a dir or \a path or the object doesn't 156 refer to a symbolic link. 157 - \c B_FILE_ERROR: The object is not initialized. 158 - \c B_NAME_TOO_LONG: The resulting path name is too long. 159 - some other error code 160 */ 161 ssize_t 162 BSymLink::MakeLinkedPath(const BDirectory *dir, BPath *path) 163 { 164 if (!dir || !path) 165 return B_BAD_VALUE; 166 char contents[B_PATH_NAME_LENGTH]; 167 ssize_t result = ReadLink(contents, sizeof(contents)); 168 if (result >= 0) { 169 if (BPrivate::Storage::is_absolute_path(contents)) 170 result = path->SetTo(contents); 171 else 172 result = path->SetTo(dir, contents); 173 if (result == B_OK) 174 result = strlen(path->Path()); 175 } 176 return result; 177 } 178 179 // IsAbsolute 180 //! Returns whether this BSymLink refers to an absolute link. 181 /*! /return 182 - \c true, if the object is properly initialized and the symbolic link it 183 refers to is an absolute link, 184 - \c false, otherwise. 185 */ 186 bool 187 BSymLink::IsAbsolute() 188 { 189 char contents[B_PATH_NAME_LENGTH]; 190 bool result = (ReadLink(contents, sizeof(contents)) >= 0); 191 if (result) 192 result = BPrivate::Storage::is_absolute_path(contents); 193 return result; 194 } 195 196 197 void BSymLink::_MissingSymLink1() {} 198 void BSymLink::_MissingSymLink2() {} 199 void BSymLink::_MissingSymLink3() {} 200 void BSymLink::_MissingSymLink4() {} 201 void BSymLink::_MissingSymLink5() {} 202 void BSymLink::_MissingSymLink6() {} 203 204 //! Returns the BSymLink's file descriptor. 205 /*! To be used instead of accessing the BNode's private \c fFd member directly. 206 \return the file descriptor, or -1, if not properly initialized. 207 */ 208 int 209 BSymLink::get_fd() const 210 { 211 return fFd; 212 } 213 214 215 #ifdef USE_OPENBEOS_NAMESPACE 216 }; // namespace OpenBeOS 217 #endif 218 219