/** * @brief Reloads changed filter files * * Checks if filter file has been modified since it was last time * loaded/reloaded. If file has been modified we reload it. * @todo How to handle an error in reloading filter? */ void FileFilterHelper::ReloadUpdatedFilters() { vector<FileFilterInfo> filters; DirItem fileInfo; String selected; GetFileFilters(&filters, selected); vector<FileFilterInfo>::const_iterator iter = filters.begin(); while (iter != filters.end()) { String path = (*iter).fullpath; fileInfo.Update(path); if (fileInfo.mtime != (*iter).fileinfo.mtime || fileInfo.size != (*iter).fileinfo.size) { // Reload filter after changing it int retval = m_fileFilterMgr->ReloadFilterFromDisk(path); if (retval == FILTER_OK) { // If it was active filter we have to re-set it if (path == selected) SetFileFilterPath(path); } } ++iter; } }
// _VerifyHashFunction bool Volume::_VerifyHashFunction(hash_function_t function) { bool result = true; // iterate over the entries in the root dir until we find an entry, that // doesn't falsify the hash function DirEntryIterator iterator(fTree, fRootVNode->GetDirID(), fRootVNode->GetObjectID(), DOT_DOT_OFFSET + 1); DirItem item; int32 index = 0; while (iterator.GetNext(&item, &index) == B_OK) { DirEntry *entry = item.EntryAt(index); uint64 offset = entry->GetOffset(); // try the hash function size_t nameLen = 0; if (const char *name = item.EntryNameAt(index, &nameLen)) { uint64 testOffset = key_offset_for_name(function, name, nameLen); if (offset_hash_value(offset) != offset_hash_value(testOffset)) { result = false; break; } } // else: bad data } return result; }
/** * @brief Reloads changed filter files * * Checks if filter file has been modified since it was last time * loaded/reloaded. If file has been modified we reload it. * @todo How to handle an error in reloading filter? */ void FileFilterHelper::ReloadUpdatedFilters() { FILEFILTER_INFOLIST filters; DirItem fileInfo; DirItem *fileInfoStored = NULL; FileFilterInfo filter; CString selected; GetFileFilters(&filters, selected); for (int i = 0; i < filters.GetSize(); i++) { filter = filters.GetAt(i); CString path = filter.fullpath; fileInfoStored = &filter.fileinfo; fileInfo.Update((LPCTSTR)path); if (fileInfo.mtime != fileInfoStored->mtime || fileInfo.size != fileInfoStored->size) { // Reload filter after changing it int retval = m_fileFilterMgr->ReloadFilterFromDisk(path); if (retval == FILTER_OK) { // If it was active filter we have to re-set it if (path == selected) SetFileFilterPath(path); } } } }
void MyThread::CloseTreeItem(DirItem* i) { DirItem* parent = i->GetParent(); if(parent) { parent->IncreaseChildrenByteCount(i->GetTotalByteCount()); } }
// FindDirEntry status_t Tree::FindDirEntry(uint32 dirID, uint32 objectID, const char *name, size_t nameLen, DirItem *foundItem, int32 *entryIndex) { status_t error = (name && foundItem && entryIndex ? InitCheck() : B_BAD_VALUE); if (error == B_OK) { uint64 offset = 0; if (fVolume->GetKeyOffsetForName(name, nameLen, &offset) == B_OK) { //PRINT(("Tree::FindDirEntry(): hash function: offset: %Lu (`%.*s', %lu)\n", //offset, (int)nameLen, name, nameLen)); // offset computed -- we can directly iterate only over entries // with that offset DirEntryIterator iterator(this, dirID, objectID, offset, true); DirItem dirItem; int32 index = 0; error = B_ENTRY_NOT_FOUND; while (iterator.GetPrevious(&dirItem, &index) == B_OK) { size_t itemNameLen = 0; if (const char *itemName = dirItem.EntryNameAt(index, &itemNameLen)) { if (itemNameLen == nameLen && !strncmp(name, itemName, nameLen)) { // item found *foundItem = dirItem; *entryIndex = index; error = B_OK; break; } } } } else { //PRINT(("Tree::FindDirEntry(): no hash function\n")); // no offset (no hash function) -- do it the slow way ObjectItemIterator iterator(this, dirID, objectID); DirItem dirItem; error = B_ENTRY_NOT_FOUND; while (iterator.GetNext(&dirItem, TYPE_DIRENTRY) == B_OK) { if (dirItem.Check() != B_OK) // bad data: skip item continue; int32 index = dirItem.IndexOfName(name); if (index >= 0) { // item found *foundItem = dirItem; *entryIndex = index; error = B_OK; //PRINT((" offset: %lu\n", dirItem.EntryAt(index)->GetOffset())); break; } } } } return error; }
DirItem* MyThread::Attach(DirItem* parent, const std::wstring& text, BigNumber sizeInBytes, bool dir) { DirItem* newItem = DirItem::GetPool()->Get(); newItem->SetName(text); newItem->SetByteCount(sizeInBytes); newItem->SetType(dir ? EItemType_Directory : EItemType_File); if(parent) parent->AddChild(newItem); if(!dir) { parent->IncreaseChildrenByteCount(sizeInBytes); } return newItem; }
int DeniedDir::addDir(const char *pDir) { while (1) { //if ( *pDir != '/' ) //{ // LS_ERROR( "[config] failed to add denied dir, need absolute path - %s!", pDir )); // break; //} int len = strlen(pDir); //if ( len >= 256 - 1 ) //{ // LS_ERROR( "[config] denied path is too long - %s!", pDir )); // break; //} char buf[256]; bool includeSub = false; strcpy(buf, pDir); char *pEnd = buf + len - 1; if (*(pEnd) == '*') { includeSub = true; *(pEnd) = 0; } else if (*(pEnd) != '/') { *(++pEnd) = '/'; *(++pEnd) = 0; } //if ( ( GPath::clean(buf) != 0 ) ||!GPath::isValid( buf ) ) //{ // LS_ERROR( "[config] invalid denied path - %s!", buf )); // break; //} DirItem *pos = find(buf); if (pos != NULL) pos->setIncludeSub(includeSub); else { DirItem *pItem = new DirItem(buf, includeSub); insert(pItem); } return 0; } return 1; }
/*! \brief Searches an entry in a directory. \note Must not be called with \a entryName "." or ".."! \param dir The directory. \param entryName Name of the entry. \param foundNode pointer to a pre-allocated VNode to be initialized to the found entry. \param failIfHidden The method shall fail, if the entry is hidden. \return \c B_OK, if everything went fine. */ status_t Volume::FindDirEntry(VNode *dir, const char *entryName, VNode *foundNode, bool failIfHidden) { status_t error = (dir && foundNode ? B_OK : B_BAD_VALUE); // find the DirEntry DirItem item; int32 entryIndex = 0; if (error == B_OK) { error = fTree->FindDirEntry(dir->GetDirID(), dir->GetObjectID(), entryName, &item, &entryIndex); } // find the child node if (error == B_OK) { DirEntry *entry = item.EntryAt(entryIndex); error = FindVNode(entry->GetDirID(), entry->GetObjectID(), foundNode); if (error == B_OK && failIfHidden && entry->IsHidden()) error = B_ENTRY_NOT_FOUND; } return error; }
// _DetectHashFunction uint32 Volume::_DetectHashFunction() { // iterate over the entries in the root dir until we find an entry, that // let us draw an unambiguous conclusion DirEntryIterator iterator(fTree, fRootVNode->GetDirID(), fRootVNode->GetObjectID(), DOT_DOT_OFFSET + 1); uint32 foundCode = UNSET_HASH; DirItem item; int32 index = 0; while (foundCode == UNSET_HASH && iterator.GetNext(&item, &index) == B_OK) { DirEntry *entry = item.EntryAt(index); uint64 offset = entry->GetOffset(); uint32 hashCodes[] = { TEA_HASH, YURA_HASH, R5_HASH }; int32 hashCodeCount = sizeof(hashCodes) / sizeof(uint32); size_t nameLen = 0; const char *name = item.EntryNameAt(index, &nameLen); if (!name) // bad data! continue; // try each hash function -- if there's a single winner, we're done, // otherwise the next entry must help for (int32 i = 0; i < hashCodeCount; i++) { hash_function_t function = hash_function_for_code(hashCodes[i]); uint64 testOffset = key_offset_for_name(function, name, nameLen); if (offset_hash_value(offset) == offset_hash_value(testOffset)) { if (foundCode != UNSET_HASH) { // ambiguous foundCode = UNSET_HASH; break; } else foundCode = hashCodes[i]; } } } return foundCode; }
/*! \brief Finds the node identified by a directory ID, object ID pair. \note The method does not initialize the parent ID for non-directory nodes. \param dirID Directory ID of the node to be found. \param objectID Object ID of the node to be found. \param node pointer to a pre-allocated VNode to be initialized to the found node. \return \c B_OK, if everything went fine. */ status_t Volume::FindVNode(uint32 dirID, uint32 objectID, VNode *node) { // NOTE: The node's parent dir ID is not initialized! status_t error = (node ? B_OK : B_BAD_VALUE); // init the node if (error == B_OK) error = node->SetTo(dirID, objectID); // find the stat item StatItem item; if (error == B_OK) { error = fTree->FindStatItem(dirID, objectID, &item); if (error != B_OK) { FATAL(("Couldn't find stat item for node (%lu, %lu)\n", dirID, objectID)); } } // get the stat data if (error == B_OK) SET_ERROR(error, item.GetStatData(node->GetStatData(), true)); // for dirs get the ".." entry, since we need the parent dir ID if (error == B_OK && node->IsDir()) { DirItem dirItem; int32 index = 0; error = fTree->FindDirEntry(dirID, objectID, "..", &dirItem, &index); if (error == B_OK) { DirEntry *entry = dirItem.EntryAt(index); node->SetParentID(entry->GetDirID(), entry->GetObjectID()); } else { FATAL(("failed to find `..' entry for dir node (%lu, %ld)\n", dirID, objectID)); } } return error; }
// reiserfs_read_dir static status_t reiserfs_read_dir(fs_volume *fs, fs_vnode *_node, void *cookie, struct dirent *buffer, size_t bufferSize, uint32 *count) { // FUNCTION_START(); Volume *volume = (Volume*)fs->private_volume; VNode *node = (VNode*)_node->private_node; FUNCTION(("node: (%Ld: %lu, %lu)\n", node->GetID(), node->GetDirID(), node->GetObjectID())); DirectoryCookie *iterator = (DirectoryCookie*)cookie; status_t error = iterator->Resume(); if (error == B_OK) { // read one entry DirItem item; int32 index = 0; DirEntry *entry = NULL; bool done = false; while (error == B_OK && !done && (error = iterator->GetNext(&item, &index, &entry)) == B_OK) { uint32 dirID = entry->GetDirID(); uint32 objectID = entry->GetObjectID(); // skip hidden entries and entries the user specified to be hidden if (entry->IsHidden() || volume->IsNegativeEntry(dirID, objectID)) continue; // skip entry, if we can't get the stat data, or it is neither a // file, a dir nor a symlink and the user desired to hide those. StatData statData; StatItem statItem; if (volume->GetTree()->FindStatItem(dirID, objectID, &statItem) != B_OK || statItem.GetStatData(&statData) != B_OK || (statData.IsEsoteric() && volume->GetHideEsoteric())) { continue; } if (error == B_OK) { // get the name size_t nameLen = 0; const char *name = item.EntryNameAt(index, &nameLen); if (!name || nameLen == 0) // bad data: skip it gracefully continue; // fill in the entry name -- checks whether the // entry fits into the buffer error = set_dirent_name(buffer, bufferSize, name, nameLen); if (error == B_OK) { // fill in the other data buffer->d_dev = volume->GetID(); buffer->d_ino = VNode::GetIDFor(dirID, objectID); *count = 1; PRINT(("Successfully read entry: dir: (%Ld: %ld, %ld), name: `%s', " "id: (%Ld, %ld, %ld), reclen: %hu\n", node->GetID(), node->GetDirID(), node->GetObjectID(), buffer->d_name, buffer->d_ino, dirID, objectID, buffer->d_reclen)); if (!strcmp("..", buffer->d_name)) iterator->SetEncounteredDotDot(true); done = true; } } } if (error == B_ENTRY_NOT_FOUND) { if (iterator->EncounteredDotDot()) { error = B_OK; *count = 0; } else { // this is necessary for the root directory // it usually has no ".." entry, so we simulate one // get the name const char *name = ".."; size_t nameLen = strlen(name); // fill in the entry name -- checks whether the // entry fits into the buffer error = set_dirent_name(buffer, bufferSize, name, nameLen); if (error == B_OK) { // fill in the other data buffer->d_dev = volume->GetID(); buffer->d_ino = node->GetID(); // < That's not correct! *count = 1; PRINT(("faking `..' entry: dir: (%Ld: %ld, %ld), name: `%s', " "id: (%Ld, %ld, %ld), reclen: %hu\n", node->GetID(), node->GetDirID(), node->GetObjectID(), buffer->d_name, buffer->d_ino, node->GetDirID(), node->GetObjectID(), buffer->d_reclen)); iterator->SetEncounteredDotDot(true); } } } iterator->Suspend(); } PRINT(("returning %ld entries\n", *count)); RETURN_ERROR(error); }