1/* 2 * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include "PackageLinkSymlink.h" 8 9#include <algorithm> 10 11#include <NodeMonitor.h> 12 13#include "DebugSupport.h" 14#include "NodeListener.h" 15#include "PackageLinksListener.h" 16#include "Utils.h" 17#include "Volume.h" 18 19 20static const char* const kSystemLinkPath = "../.."; 21static const char* const kCommonLinkPath = "../../../common"; 22static const char* const kHomeLinkPath = "../../../home/config"; 23 24static const char* const kUnknownLinkTarget = "?"; 25 26 27static const char* 28link_path_for_mount_type(MountType type) 29{ 30 switch (type) { 31 case MOUNT_TYPE_SYSTEM: 32 return kSystemLinkPath; 33 case MOUNT_TYPE_COMMON: 34 return kCommonLinkPath; 35 case MOUNT_TYPE_HOME: 36 return kHomeLinkPath; 37 case MOUNT_TYPE_CUSTOM: 38 default: 39 return "?"; 40 } 41} 42 43 44// #pragma mark - OldAttributes 45 46 47struct PackageLinkSymlink::OldAttributes : OldNodeAttributes { 48 OldAttributes(const timespec& modifiedTime, off_t fileSize) 49 : 50 fModifiedTime(modifiedTime), 51 fFileSize(fileSize) 52 { 53 } 54 55 virtual timespec ModifiedTime() const 56 { 57 return fModifiedTime; 58 } 59 60 virtual off_t FileSize() const 61 { 62 return fFileSize; 63 } 64 65private: 66 timespec fModifiedTime; 67 off_t fFileSize; 68}; 69 70 71// #pragma mark - PackageLinkSymlink 72 73 74PackageLinkSymlink::PackageLinkSymlink(Package* package) 75 : 76 Node(0), 77 fLinkPath(kUnknownLinkTarget) 78{ 79 Update(package, NULL); 80} 81 82 83PackageLinkSymlink::~PackageLinkSymlink() 84{ 85} 86 87 88void 89PackageLinkSymlink::Update(Package* package, PackageLinksListener* listener) 90{ 91 OldAttributes oldAttributes(fModifiedTime, FileSize()); 92 93 if (package != NULL) { 94 fLinkPath = package->InstallPath(); 95 if (fLinkPath == NULL) { 96 fLinkPath = link_path_for_mount_type( 97 package->Domain()->Volume()->MountType()); 98 } 99 } else 100 fLinkPath = kUnknownLinkTarget; 101 102 get_real_time(fModifiedTime); 103 104 if (listener != NULL) { 105 listener->PackageLinkNodeChanged(this, 106 B_STAT_SIZE | B_STAT_MODIFICATION_TIME, oldAttributes); 107 } 108} 109 110 111mode_t 112PackageLinkSymlink::Mode() const 113{ 114 return S_IFLNK | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; 115} 116 117 118timespec 119PackageLinkSymlink::ModifiedTime() const 120{ 121 return fModifiedTime; 122} 123 124 125off_t 126PackageLinkSymlink::FileSize() const 127{ 128 return strlen(fLinkPath); 129} 130 131 132status_t 133PackageLinkSymlink::Read(off_t offset, void* buffer, size_t* bufferSize) 134{ 135 return B_BAD_VALUE; 136} 137 138 139status_t 140PackageLinkSymlink::Read(io_request* request) 141{ 142 return B_BAD_VALUE; 143} 144 145 146status_t 147PackageLinkSymlink::ReadSymlink(void* buffer, size_t* bufferSize) 148{ 149 size_t toCopy = std::min(strlen(fLinkPath), *bufferSize); 150 memcpy(buffer, fLinkPath, toCopy); 151 *bufferSize = toCopy; 152 153 return B_OK; 154} 155