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 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 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 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 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 162 void BSymLink::_MissingSymLink1() {} 163 void BSymLink::_MissingSymLink2() {} 164 void BSymLink::_MissingSymLink3() {} 165 void BSymLink::_MissingSymLink4() {} 166 void BSymLink::_MissingSymLink5() {} 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 178 BSymLink::get_fd() const 179 { 180 return fFd; 181 } 182