1 /* 2 * Copyright 2002-2009, Haiku Inc. 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 &link) 35 : 36 BNode(link) 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 error = _kern_read_link(get_fd(), NULL, buffer, &linkLen); 94 if (error < B_OK) 95 return error; 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 int 173 BSymLink::get_fd() const 174 { 175 return fFd; 176 } 177