1/* 2 * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include "UnpackingDirectory.h" 8 9#include "DebugSupport.h" 10#include "UnpackingAttributeCookie.h" 11#include "UnpackingAttributeDirectoryCookie.h" 12#include "Utils.h" 13 14 15// #pragma mark - UnpackingDirectory 16 17 18UnpackingDirectory::UnpackingDirectory(ino_t id) 19 : 20 Directory(id) 21{ 22} 23 24 25UnpackingDirectory::~UnpackingDirectory() 26{ 27} 28 29 30mode_t 31UnpackingDirectory::Mode() const 32{ 33 if (PackageDirectory* packageDirectory = fPackageDirectories.Head()) 34 return packageDirectory->Mode(); 35 return S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; 36} 37 38 39uid_t 40UnpackingDirectory::UserID() const 41{ 42 if (PackageDirectory* packageDirectory = fPackageDirectories.Head()) 43 return packageDirectory->UserID(); 44 return 0; 45} 46 47 48gid_t 49UnpackingDirectory::GroupID() const 50{ 51 if (PackageDirectory* packageDirectory = fPackageDirectories.Head()) 52 return packageDirectory->GroupID(); 53 return 0; 54} 55 56 57timespec 58UnpackingDirectory::ModifiedTime() const 59{ 60 if (PackageDirectory* packageDirectory = fPackageDirectories.Head()) 61 return packageDirectory->ModifiedTime(); 62 63 timespec time = { 0, 0 }; 64 return time; 65} 66 67 68off_t 69UnpackingDirectory::FileSize() const 70{ 71 return 0; 72} 73 74 75Node* 76UnpackingDirectory::GetNode() 77{ 78 return this; 79} 80 81 82status_t 83UnpackingDirectory::AddPackageNode(PackageNode* packageNode) 84{ 85 if (!S_ISDIR(packageNode->Mode())) 86 return B_BAD_VALUE; 87 88 PackageDirectory* packageDirectory 89 = dynamic_cast<PackageDirectory*>(packageNode); 90 91 PackageDirectory* other = fPackageDirectories.Head(); 92 bool isNewest = other == NULL 93 || packageDirectory->ModifiedTime() > other->ModifiedTime(); 94 95 if (isNewest) 96 fPackageDirectories.Insert(other, packageDirectory); 97 else 98 fPackageDirectories.Add(packageDirectory); 99 100 return B_OK; 101} 102 103 104void 105UnpackingDirectory::RemovePackageNode(PackageNode* packageNode) 106{ 107 bool isNewest = packageNode == fPackageDirectories.Head(); 108 fPackageDirectories.Remove(dynamic_cast<PackageDirectory*>(packageNode)); 109 110 // when removing the newest node, we need to find the next node (the list 111 // is not sorted) 112 PackageDirectory* newestNode = fPackageDirectories.Head(); 113 if (isNewest && newestNode != NULL) { 114 PackageDirectoryList::Iterator it = fPackageDirectories.GetIterator(); 115 it.Next(); 116 // skip the first one 117 while (PackageDirectory* otherNode = it.Next()) { 118 if (otherNode->ModifiedTime() > newestNode->ModifiedTime()) 119 newestNode = otherNode; 120 } 121 122 fPackageDirectories.Remove(newestNode); 123 fPackageDirectories.Insert(fPackageDirectories.Head(), newestNode); 124 } 125} 126 127 128PackageNode* 129UnpackingDirectory::GetPackageNode() 130{ 131 return fPackageDirectories.Head(); 132} 133 134 135bool 136UnpackingDirectory::IsOnlyPackageNode(PackageNode* node) const 137{ 138 return node == fPackageDirectories.Head() 139 && node == fPackageDirectories.Tail(); 140} 141 142 143bool 144UnpackingDirectory::WillBeFirstPackageNode(PackageNode* packageNode) const 145{ 146 PackageDirectory* packageDirectory 147 = dynamic_cast<PackageDirectory*>(packageNode); 148 if (packageDirectory == NULL) 149 return false; 150 151 PackageDirectory* other = fPackageDirectories.Head(); 152 return other == NULL 153 || packageDirectory->ModifiedTime() > other->ModifiedTime(); 154} 155 156 157void 158UnpackingDirectory::PrepareForRemoval() 159{ 160 fPackageDirectories.MakeEmpty(); 161} 162 163 164status_t 165UnpackingDirectory::OpenAttributeDirectory(AttributeDirectoryCookie*& _cookie) 166{ 167 return UnpackingAttributeDirectoryCookie::Open(fPackageDirectories.Head(), 168 _cookie); 169} 170 171 172status_t 173UnpackingDirectory::OpenAttribute(const char* name, int openMode, 174 AttributeCookie*& _cookie) 175{ 176 return UnpackingAttributeCookie::Open(fPackageDirectories.Head(), name, 177 openMode, _cookie); 178} 179 180 181status_t 182UnpackingDirectory::IndexAttribute(AttributeIndexer* indexer) 183{ 184 return UnpackingAttributeCookie::IndexAttribute(fPackageDirectories.Head(), 185 indexer); 186} 187 188 189void* 190UnpackingDirectory::IndexCookieForAttribute(const char* name) const 191{ 192 if (PackageDirectory* packageDirectory = fPackageDirectories.Head()) 193 return packageDirectory->IndexCookieForAttribute(name); 194 return NULL; 195} 196 197 198// #pragma mark - RootDirectory 199 200 201RootDirectory::RootDirectory(ino_t id, const timespec& modifiedTime) 202 : 203 UnpackingDirectory(id), 204 fModifiedTime(modifiedTime) 205{ 206} 207 208 209timespec 210RootDirectory::ModifiedTime() const 211{ 212 return fModifiedTime; 213} 214