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. 28 BSymLink::BSymLink() 29 { 30 } 31 32 33 // Creates a copy of the supplied BSymLink object. 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. 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 result = _kern_read_link(get_fd(), NULL, buffer, &linkLen); 94 if (result < B_OK) 95 return result; 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 173 This method should be used instead of accessing the private \c fFd member 174 of the BNode directly. 175 176 \return The object's file descriptor, or -1 if not properly initialized. 177 */ 178 int 179 BSymLink::get_fd() const 180 { 181 return fFd; 182 } 183