1284194Sdelphij/* 2284194Sdelphij * Copyright 2002-2009 Haiku, Inc. All rights reserved. 3284194Sdelphij * Distributed under the terms of the MIT License. 4284194Sdelphij * 5284194Sdelphij * Authors: 6284194Sdelphij * Tyler Dauwalder 7284194Sdelphij * Ingo Weinhold, ingo_weinhold@gmx.de 8284194Sdelphij */ 9284194Sdelphij 10284194Sdelphij 11284194Sdelphij#include <new> 12284194Sdelphij#include <string.h> 13284194Sdelphij 14284194Sdelphij#include <SymLink.h> 15284194Sdelphij#include <Directory.h> 16284194Sdelphij#include <Entry.h> 17284194Sdelphij#include <Path.h> 18284194Sdelphij 19284194Sdelphij#include <syscalls.h> 20284194Sdelphij 21284194Sdelphij#include "storage_support.h" 22284194Sdelphij 23284194Sdelphij 24284194Sdelphijusing namespace std; 25284194Sdelphij 26284194Sdelphij 27284194Sdelphij// Creates an uninitialized BSymLink object. 28284194SdelphijBSymLink::BSymLink() 29284194Sdelphij{ 30284194Sdelphij} 31284194Sdelphij 32284194Sdelphij 33284194Sdelphij// Creates a copy of the supplied BSymLink object. 34284194SdelphijBSymLink::BSymLink(const BSymLink& other) 35284194Sdelphij : 36284194Sdelphij BNode(other) 37284194Sdelphij{ 38284194Sdelphij} 39284194Sdelphij 40284194Sdelphij 41284194Sdelphij// Creates a BSymLink object and initializes it to the symbolic link referred 42284194Sdelphij// to by the supplied entry_ref. 43284194SdelphijBSymLink::BSymLink(const entry_ref* ref) 44284194Sdelphij : 45284194Sdelphij BNode(ref) 46284194Sdelphij{ 47284194Sdelphij} 48284194Sdelphij 49284194Sdelphij 50284194Sdelphij// Creates a BSymLink object and initializes it to the symbolic link referred 51284194Sdelphij// to by the supplied BEntry. 52284194SdelphijBSymLink::BSymLink(const BEntry* entry) 53284194Sdelphij : BNode(entry) 54284194Sdelphij{ 55284194Sdelphij} 56284194Sdelphij 57284194Sdelphij 58284194Sdelphij// Creates a BSymLink object and initializes it to the symbolic link referred 59284194Sdelphij// to by the supplied path name. 60284194SdelphijBSymLink::BSymLink(const char* path) 61284194Sdelphij : 62284194Sdelphij BNode(path) 63284194Sdelphij{ 64284194Sdelphij} 65284194Sdelphij 66284194Sdelphij 67284194Sdelphij// Creates a BSymLink object and initializes it to the symbolic link referred 68284194Sdelphij// to by the supplied path name relative to the specified BDirectory. 69284194SdelphijBSymLink::BSymLink(const BDirectory* dir, const char* path) 70284194Sdelphij : 71284194Sdelphij BNode(dir, path) 72284194Sdelphij{ 73284194Sdelphij} 74284194Sdelphij 75284194Sdelphij 76284194Sdelphij// Destroys the object and frees all allocated resources. 77284194SdelphijBSymLink::~BSymLink() 78284194Sdelphij{ 79284194Sdelphij} 80284194Sdelphij 81284194Sdelphij 82284194Sdelphij// Reads the contents of the symbolic link into a buffer. 83284194Sdelphijssize_t 84284194SdelphijBSymLink::ReadLink(char* buffer, size_t size) 85284194Sdelphij{ 86284194Sdelphij if (buffer == NULL) 87284194Sdelphij return B_BAD_VALUE; 88284194Sdelphij 89284194Sdelphij if (InitCheck() != B_OK) 90284194Sdelphij return B_FILE_ERROR; 91284194Sdelphij 92284194Sdelphij size_t linkLen = size; 93284194Sdelphij status_t result = _kern_read_link(get_fd(), NULL, buffer, &linkLen); 94284194Sdelphij if (result < B_OK) 95284194Sdelphij return result; 96284194Sdelphij 97284194Sdelphij if (linkLen < size) 98284194Sdelphij buffer[linkLen] = '\0'; 99284194Sdelphij else if (size > 0) 100284194Sdelphij buffer[size - 1] = '\0'; 101284194Sdelphij 102284194Sdelphij return linkLen; 103284194Sdelphij} 104284194Sdelphij 105284194Sdelphij 106284194Sdelphij// Combines a directory path and the contents of this symbolic link to form an 107284194Sdelphij// absolute path. 108284194Sdelphijssize_t 109284194SdelphijBSymLink::MakeLinkedPath(const char* dirPath, BPath* path) 110284194Sdelphij{ 111284194Sdelphij // BeOS seems to convert the dirPath to a BDirectory, which causes links 112284194Sdelphij // to be resolved. This means that the dirPath must exist! 113284194Sdelphij if (dirPath == NULL || path == NULL) 114284194Sdelphij return B_BAD_VALUE; 115284194Sdelphij 116284194Sdelphij BDirectory dir(dirPath); 117284194Sdelphij ssize_t result = dir.InitCheck(); 118284194Sdelphij if (result == B_OK) 119284194Sdelphij result = MakeLinkedPath(&dir, path); 120284194Sdelphij 121284194Sdelphij return result; 122284194Sdelphij} 123284194Sdelphij 124284194Sdelphij 125284194Sdelphij// Combines a directory path and the contents of this symbolic link to form an 126284194Sdelphij// absolute path. 127284194Sdelphijssize_t 128284194SdelphijBSymLink::MakeLinkedPath(const BDirectory* dir, BPath* path) 129284194Sdelphij{ 130284194Sdelphij if (dir == NULL || path == NULL) 131284194Sdelphij return B_BAD_VALUE; 132284194Sdelphij 133284194Sdelphij char contents[B_PATH_NAME_LENGTH]; 134284194Sdelphij ssize_t result = ReadLink(contents, sizeof(contents)); 135284194Sdelphij if (result >= 0) { 136284194Sdelphij if (BPrivate::Storage::is_absolute_path(contents)) 137284194Sdelphij result = path->SetTo(contents); 138284194Sdelphij else 139284194Sdelphij result = path->SetTo(dir, contents); 140284194Sdelphij 141284194Sdelphij if (result == B_OK) 142284194Sdelphij result = strlen(path->Path()); 143284194Sdelphij } 144284194Sdelphij 145284194Sdelphij return result; 146284194Sdelphij} 147284194Sdelphij 148284194Sdelphij 149284194Sdelphij// Returns whether or not the object refers to an absolute path. 150284194Sdelphijbool 151284194SdelphijBSymLink::IsAbsolute() 152284194Sdelphij{ 153284194Sdelphij char contents[B_PATH_NAME_LENGTH]; 154284194Sdelphij bool result = (ReadLink(contents, sizeof(contents)) >= 0); 155284194Sdelphij if (result) 156284194Sdelphij result = BPrivate::Storage::is_absolute_path(contents); 157284194Sdelphij 158284194Sdelphij return result; 159284194Sdelphij} 160284194Sdelphij 161284194Sdelphij 162284194Sdelphijvoid BSymLink::_MissingSymLink1() {} 163284194Sdelphijvoid BSymLink::_MissingSymLink2() {} 164284194Sdelphijvoid BSymLink::_MissingSymLink3() {} 165284194Sdelphijvoid BSymLink::_MissingSymLink4() {} 166284194Sdelphijvoid BSymLink::_MissingSymLink5() {} 167284194Sdelphijvoid BSymLink::_MissingSymLink6() {} 168284194Sdelphij 169284194Sdelphij 170284194Sdelphij/*! Returns the file descriptor of the BSymLink. 171284194Sdelphij 172284194Sdelphij This method should be used instead of accessing the private \c fFd member 173284194Sdelphij of the BNode directly. 174284194Sdelphij 175284194Sdelphij \return The object's file descriptor, or -1 if not properly initialized. 176284194Sdelphij*/ 177284194Sdelphijint 178284194SdelphijBSymLink::get_fd() const 179284194Sdelphij{ 180284194Sdelphij return fFd; 181284194Sdelphij} 182284194Sdelphij