// Delete an object bool OSToken::deleteObject(OSObject* object) { if (!valid) return false; if (objects.find(object) == objects.end()) { ERROR_MSG("Cannot delete non-existent object 0x%08X", object); return false; } MutexLocker lock(tokenMutex); ObjectFile* fileObject = dynamic_cast<ObjectFile*>(object); if (fileObject == NULL) { ERROR_MSG("Object type not compatible with this token class 0x%08X", object); return false; } // Invalidate the object instance fileObject->invalidate(); // Retrieve the filename of the object std::string objectFilename = fileObject->getFilename(); // Attempt to delete the file if (!tokenDir->remove(objectFilename)) { ERROR_MSG("Failed to delete object file %s", objectFilename.c_str()); return false; } // Retrieve the filename of the lock std::string lockFilename = fileObject->getLockname(); // Attempt to delete the lock if (!tokenDir->remove(lockFilename)) { ERROR_MSG("Failed to delete lock file %s", lockFilename.c_str()); return false; } objects.erase(object); DEBUG_MSG("Deleted object %s", objectFilename.c_str()); gen->update(); gen->commit(); return true; }
// Index the token bool OSToken::index(bool isFirstTime /* = false */) { // Check if re-indexing is required if (!isFirstTime && (!valid || !gen->wasUpdated())) { return true; } // Check the integrity if (!tokenDir->refresh() || !tokenObject->valid) { valid = false; return false; } DEBUG_MSG("Token %s has changed", tokenPath.c_str()); // Retrieve the directory listing std::vector<std::string> tokenFiles = tokenDir->getFiles(); // Filter out the objects std::set<std::string> newSet; for (std::vector<std::string>::iterator i = tokenFiles.begin(); i != tokenFiles.end(); i++) { if ((i->size() > 7) && (!(i->substr(i->size() - 7).compare(".object"))) && (i->compare("token.object"))) { newSet.insert(*i); } else { DEBUG_MSG("Ignored file %s", i->c_str()); } } // Compute the changes compared to the last list of files std::set<std::string> addedFiles; std::set<std::string> removedFiles; // No access to object mutable fields before MutexLocker lock(tokenMutex); if (!isFirstTime) { // First compute which files were added for (std::set<std::string>::iterator i = newSet.begin(); i != newSet.end(); i++) { if (currentFiles.find(*i) == currentFiles.end()) { addedFiles.insert(*i); } } // Now compute which files were removed for (std::set<std::string>::iterator i = currentFiles.begin(); i != currentFiles.end(); i++) { if (newSet.find(*i) == newSet.end()) { removedFiles.insert(*i); } } } else { addedFiles = newSet; } currentFiles = newSet; DEBUG_MSG("%d objects were added and %d objects were removed", addedFiles.size(), removedFiles.size()); DEBUG_MSG("Current directory set contains %d objects", currentFiles.size()); // Now update the set of objects // Add new objects for (std::set<std::string>::iterator i = addedFiles.begin(); i != addedFiles.end(); i++) { if ((i->find_last_of('.') == std::string::npos) || (i->substr(i->find_last_of('.')) != ".object")) { continue; } std::string lockName(*i); lockName.replace(lockName.find_last_of('.'), std::string::npos, ".lock"); // Create a new token object for the added file ObjectFile* newObject = new ObjectFile(this, tokenPath + OS_PATHSEP + *i, tokenPath + OS_PATHSEP + lockName); DEBUG_MSG("(0x%08X) New object %s (0x%08X) added", this, newObject->getFilename().c_str(), newObject); objects.insert(newObject); allObjects.insert(newObject); } // Remove deleted objects std::set<OSObject*> newObjects; for (std::set<OSObject*>::iterator i = objects.begin(); i != objects.end(); i++) { ObjectFile* fileObject = dynamic_cast<ObjectFile*>((*i)); if (fileObject == NULL) { ERROR_MSG("Object type not compatible with this token class 0x%08X", (*i)); return false; } DEBUG_MSG("Processing %s (0x%08X)", fileObject->getFilename().c_str(), *i); if (removedFiles.find(fileObject->getFilename()) == removedFiles.end()) { DEBUG_MSG("Adding object %s", fileObject->getFilename().c_str()); // This object gets to stay in the set newObjects.insert(*i); } else { fileObject->invalidate(); } } // Set the new objects objects = newObjects; DEBUG_MSG("The token now contains %d objects", objects.size()); return true; }