2008-10-18 13:53:03 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright 2004-2008, Haiku, Inc. All rights reserved.
|
|
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
|
*
|
|
|
|
|
* Authors:
|
|
|
|
|
* Andrew Bachmann
|
|
|
|
|
*/
|
|
|
|
|
|
2004-02-01 05:49:14 +00:00
|
|
|
#include "AddOnMonitorHandler.h"
|
2008-10-18 13:53:03 +00:00
|
|
|
|
2009-01-23 03:05:15 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
|
2004-02-01 05:49:14 +00:00
|
|
|
#include <Directory.h>
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
|
2004-10-04 14:53:19 +00:00
|
|
|
#ifndef ADD_ON_STABLE_SECONDS
|
2008-10-18 13:53:03 +00:00
|
|
|
# define ADD_ON_STABLE_SECONDS 5
|
2004-10-04 14:53:19 +00:00
|
|
|
#endif
|
2004-02-01 05:49:14 +00:00
|
|
|
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
AddOnMonitorHandler::AddOnMonitorHandler(const char* name)
|
|
|
|
|
: NodeMonitorHandler(name != NULL ? name : "AddOnMonitorHandler")
|
2004-02-01 05:49:14 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AddOnMonitorHandler::~AddOnMonitorHandler()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
void
|
|
|
|
|
AddOnMonitorHandler::MessageReceived(BMessage* msg)
|
2004-02-01 05:49:14 +00:00
|
|
|
{
|
2008-10-18 13:53:03 +00:00
|
|
|
if (msg->what == B_PULSE)
|
|
|
|
|
_HandlePulse();
|
|
|
|
|
|
2004-02-01 05:49:14 +00:00
|
|
|
inherited::MessageReceived(msg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
status_t
|
|
|
|
|
AddOnMonitorHandler::AddDirectory(const node_ref* nref)
|
2004-02-01 05:49:14 +00:00
|
|
|
{
|
2004-02-02 05:26:40 +00:00
|
|
|
// ignore directories added twice
|
2008-10-18 13:53:03 +00:00
|
|
|
std::list<add_on_directory_info>::iterator iterator = fDirectories.begin();
|
|
|
|
|
for (; iterator != fDirectories.end() ; iterator++) {
|
|
|
|
|
if (iterator->nref == *nref)
|
2004-02-02 05:26:40 +00:00
|
|
|
return B_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2004-02-01 05:49:14 +00:00
|
|
|
BDirectory directory(nref);
|
|
|
|
|
status_t status = directory.InitCheck();
|
2008-10-18 13:53:03 +00:00
|
|
|
if (status != B_OK)
|
2004-02-01 05:49:14 +00:00
|
|
|
return status;
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
add_on_directory_info dirInfo;
|
|
|
|
|
dirInfo.nref = *nref;
|
|
|
|
|
fDirectories.push_back(dirInfo);
|
2004-02-01 05:49:14 +00:00
|
|
|
|
|
|
|
|
status = watch_node(nref, B_WATCH_DIRECTORY, this);
|
|
|
|
|
if (status != B_OK) {
|
2008-10-18 13:53:03 +00:00
|
|
|
fDirectories.pop_back();
|
2004-02-01 05:49:14 +00:00
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BEntry entry;
|
|
|
|
|
while (directory.GetNextEntry(&entry, true) == B_OK) {
|
2008-10-18 13:53:03 +00:00
|
|
|
add_on_entry_info entryInfo;
|
|
|
|
|
if (entry.GetName(entryInfo.name) != B_OK
|
|
|
|
|
|| entry.GetNodeRef(&entryInfo.nref) != B_OK) {
|
|
|
|
|
continue;
|
2004-02-01 05:49:14 +00:00
|
|
|
}
|
2008-10-18 13:53:03 +00:00
|
|
|
|
|
|
|
|
entryInfo.dir_nref = *nref;
|
|
|
|
|
fPendingEntries.push_back(entryInfo);
|
2004-02-01 05:49:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
// #pragma mark - AddOnMonitorHandler hooks
|
|
|
|
|
|
2004-02-01 05:49:14 +00:00
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
void
|
|
|
|
|
AddOnMonitorHandler::AddOnCreated(const add_on_entry_info* entryInfo)
|
2004-02-01 05:49:14 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
void
|
|
|
|
|
AddOnMonitorHandler::AddOnEnabled(const add_on_entry_info* entryInfo)
|
2004-02-01 05:49:14 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
void
|
|
|
|
|
AddOnMonitorHandler::AddOnDisabled(const add_on_entry_info* entryInfo)
|
2004-02-01 05:49:14 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
void
|
|
|
|
|
AddOnMonitorHandler::AddOnRemoved(const add_on_entry_info* entryInfo)
|
2004-02-01 05:49:14 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
// #pragma mark - NodeMonitorHandler hooks
|
2004-02-01 05:49:14 +00:00
|
|
|
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
void
|
|
|
|
|
AddOnMonitorHandler::EntryCreated(const char* name, ino_t directory,
|
|
|
|
|
dev_t device, ino_t node)
|
2004-02-01 05:49:14 +00:00
|
|
|
{
|
2008-10-18 13:53:03 +00:00
|
|
|
add_on_entry_info entryInfo;
|
|
|
|
|
strncpy(entryInfo.name, name, sizeof(entryInfo.name));
|
|
|
|
|
make_node_ref(device, node, &entryInfo.nref);
|
|
|
|
|
make_node_ref(device, directory, &entryInfo.dir_nref);
|
|
|
|
|
fPendingEntries.push_back(entryInfo);
|
2004-02-01 05:49:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
void
|
2004-02-01 05:49:14 +00:00
|
|
|
AddOnMonitorHandler::EntryRemoved(ino_t directory, dev_t device, ino_t node)
|
|
|
|
|
{
|
2008-10-18 13:53:03 +00:00
|
|
|
node_ref entryNodeRef;
|
|
|
|
|
make_node_ref(device, node, &entryNodeRef);
|
2004-02-01 05:49:14 +00:00
|
|
|
|
|
|
|
|
// Search pending entries first, which can simply be discarded
|
|
|
|
|
// We might have this entry in the pending list multiple times,
|
|
|
|
|
// so we search entire list through, even after finding one.
|
2008-10-18 13:53:03 +00:00
|
|
|
std::list<add_on_entry_info>::iterator eiter = fPendingEntries.begin();
|
|
|
|
|
while (eiter != fPendingEntries.end()) {
|
|
|
|
|
if (eiter->nref == entryNodeRef) {
|
|
|
|
|
eiter = fPendingEntries.erase(eiter);
|
2004-02-01 05:49:14 +00:00
|
|
|
} else {
|
|
|
|
|
eiter++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
add_on_entry_info info;
|
2008-10-18 13:53:03 +00:00
|
|
|
node_ref dirNodeRef;
|
|
|
|
|
make_node_ref(device, directory, &dirNodeRef);
|
2004-02-01 05:49:14 +00:00
|
|
|
|
|
|
|
|
// find the entry's info, and the entry's directory info
|
2008-10-18 13:53:03 +00:00
|
|
|
std::list<add_on_directory_info>::iterator diter = fDirectories.begin();
|
|
|
|
|
for (; diter != fDirectories.end() ; diter++) {
|
|
|
|
|
if (diter->nref == dirNodeRef) {
|
|
|
|
|
std::list<add_on_entry_info>::iterator eiter
|
|
|
|
|
= diter->entries.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; eiter != diter->entries.end() ; eiter++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
info = *eiter;
|
2008-10-18 13:53:03 +00:00
|
|
|
if (eiter->nref == entryNodeRef) {
|
2004-02-01 05:49:14 +00:00
|
|
|
info = *eiter;
|
|
|
|
|
diter->entries.erase(eiter);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if it was not found, we're done
|
2008-10-18 13:53:03 +00:00
|
|
|
if (diter == fDirectories.end()) {
|
2004-02-01 05:49:14 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Start at the top again, and search until the directory we found
|
2008-10-18 13:53:03 +00:00
|
|
|
// the old add-on in. If we find a add-on with the same name then
|
|
|
|
|
// the old add-on was not enabled. So we deallocate the old
|
|
|
|
|
// add-on and return.
|
|
|
|
|
std::list<add_on_directory_info>::iterator diter2 = fDirectories.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; diter2 != diter ; diter2++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
std::list<add_on_entry_info>::iterator eiter = diter2->entries.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; eiter != diter2->entries.end() ; eiter++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
if (strcmp(eiter->name, info.name) == 0) {
|
|
|
|
|
AddOnRemoved(&info);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
// The active add-on was removed. We need to disable and
|
2004-02-01 05:49:14 +00:00
|
|
|
// then subsequently deallocate it.
|
|
|
|
|
AddOnDisabled(&info);
|
|
|
|
|
AddOnRemoved(&info);
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
// Continue searching for a add-on below us. If we find a add-on
|
2004-02-01 05:49:14 +00:00
|
|
|
// with the same name, we must enable it.
|
2008-10-18 13:53:03 +00:00
|
|
|
for (diter++ ; diter != fDirectories.end() ; diter++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
std::list<add_on_entry_info>::iterator eiter = diter->entries.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; eiter != diter->entries.end() ; eiter++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
if (strcmp(eiter->name, info.name) == 0) {
|
|
|
|
|
AddOnEnabled(&*eiter);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
void
|
|
|
|
|
AddOnMonitorHandler::EntryMoved(const char* name, ino_t fromDirectory,
|
|
|
|
|
ino_t toDirectory, dev_t device, ino_t node)
|
2004-02-01 05:49:14 +00:00
|
|
|
{
|
2008-10-18 13:53:03 +00:00
|
|
|
// Search the "from" directory in the known entries
|
|
|
|
|
node_ref fromNodeRef;
|
|
|
|
|
make_node_ref(device, fromDirectory, &fromNodeRef);
|
|
|
|
|
std::list<add_on_directory_info>::iterator from_iter = fDirectories.begin();
|
|
|
|
|
for (; from_iter != fDirectories.end(); from_iter++) {
|
|
|
|
|
if (from_iter->nref == fromNodeRef)
|
2004-02-01 05:49:14 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
// Search the "to" directory in the known entries
|
|
|
|
|
node_ref toNodeRef;
|
|
|
|
|
make_node_ref(device, toDirectory, &toNodeRef);
|
|
|
|
|
std::list<add_on_directory_info>::iterator to_iter = fDirectories.begin();
|
|
|
|
|
for ( ; to_iter != fDirectories.end() ; to_iter++) {
|
|
|
|
|
if (to_iter->nref == toNodeRef) {
|
2004-02-01 05:49:14 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
if (from_iter == fDirectories.end() && to_iter == fDirectories.end()) {
|
2004-02-01 05:49:14 +00:00
|
|
|
// huh? whatever...
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
add_on_entry_info info;
|
2008-10-18 13:53:03 +00:00
|
|
|
node_ref entryNodeRef;
|
|
|
|
|
make_node_ref(device, node, &entryNodeRef);
|
2004-02-01 05:49:14 +00:00
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
if (to_iter == fDirectories.end()) {
|
2004-02-01 05:49:14 +00:00
|
|
|
// moved out of our view
|
2008-10-18 13:53:03 +00:00
|
|
|
std::list<add_on_entry_info>::iterator eiter
|
|
|
|
|
= from_iter->entries.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; eiter != from_iter->entries.end() ; eiter++) {
|
2008-10-18 13:53:03 +00:00
|
|
|
if (entryNodeRef == eiter->nref) {
|
2004-02-01 05:49:14 +00:00
|
|
|
// save the info and remove the entry
|
|
|
|
|
info = *eiter;
|
|
|
|
|
from_iter->entries.erase(eiter);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (eiter == from_iter->entries.end()) {
|
|
|
|
|
// we don't know anything about this entry yet.. ignore it
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if the name is the same, save the information about this
|
2008-10-18 13:53:03 +00:00
|
|
|
// add-on into fFormerEntries for later use
|
|
|
|
|
if (strcmp(info.name, name) == 0)
|
|
|
|
|
fFormerEntries.push_back(info);
|
2004-02-01 05:49:14 +00:00
|
|
|
|
|
|
|
|
// Start at the top again, and search until the from directory.
|
2008-10-18 13:53:03 +00:00
|
|
|
// If we find a add-on with the same name then the moved add-on
|
2004-02-01 05:49:14 +00:00
|
|
|
// was not enabled. So we are done.
|
2008-10-18 13:53:03 +00:00
|
|
|
std::list<add_on_directory_info>::iterator diter = fDirectories.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; diter != from_iter ; diter++) {
|
2008-10-18 13:53:03 +00:00
|
|
|
std::list<add_on_entry_info>::iterator eiter2
|
|
|
|
|
= diter->entries.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; eiter2 != diter->entries.end() ; eiter2++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
if (strcmp(eiter2->name, info.name) == 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
// finally disable the add-on
|
2004-02-01 05:49:14 +00:00
|
|
|
AddOnDisabled(&info);
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
// Continue searching for a add-on below us. If we find a add-on
|
2004-02-01 05:49:14 +00:00
|
|
|
// with the same name, we must enable it.
|
2008-10-18 13:53:03 +00:00
|
|
|
for (from_iter++ ; from_iter != fDirectories.end() ; from_iter++) {
|
|
|
|
|
std::list<add_on_entry_info>::iterator eiter2
|
|
|
|
|
= from_iter->entries.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; eiter2 != from_iter->entries.end() ; eiter2++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
if (strcmp(eiter2->name, info.name) == 0) {
|
|
|
|
|
AddOnEnabled(&*eiter2);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// finally, if the new name is different, destroy the addon
|
|
|
|
|
if (strcmp(info.name, name) != 0) {
|
|
|
|
|
AddOnRemoved(&info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// done
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
if (from_iter == fDirectories.end()) {
|
2004-02-01 05:49:14 +00:00
|
|
|
// moved into our view
|
2008-10-18 13:53:03 +00:00
|
|
|
std::list<add_on_entry_info>::iterator eiter = fFormerEntries.begin();
|
|
|
|
|
for (; eiter != fFormerEntries.end() ; eiter++) {
|
|
|
|
|
if (entryNodeRef == eiter->nref) {
|
2004-02-01 05:49:14 +00:00
|
|
|
// save the info and remove the entry
|
|
|
|
|
info = *eiter;
|
2008-10-18 13:53:03 +00:00
|
|
|
fFormerEntries.erase(eiter);
|
2004-02-01 05:49:14 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
if (eiter != fFormerEntries.end()) {
|
2004-02-01 05:49:14 +00:00
|
|
|
if (strcmp(info.name, name) != 0) {
|
|
|
|
|
// name changed on the way in, remove the old one
|
|
|
|
|
AddOnRemoved(&info);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// update the info
|
|
|
|
|
strncpy(info.name, name, sizeof(info.name));
|
2008-10-18 13:53:03 +00:00
|
|
|
info.nref = entryNodeRef;
|
|
|
|
|
info.dir_nref = toNodeRef;
|
2004-02-01 05:49:14 +00:00
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
if (eiter == fFormerEntries.end()) {
|
|
|
|
|
// this add-on was not seen before
|
2004-02-01 05:49:14 +00:00
|
|
|
AddOnCreated(&info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Start at the top again, and search until the to directory.
|
2008-10-18 13:53:03 +00:00
|
|
|
// If we find an add-on with the same name then the moved add-on
|
|
|
|
|
// is not to be enabled. So we are done.
|
|
|
|
|
std::list<add_on_directory_info>::iterator diter = fDirectories.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; diter != to_iter ; diter++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
std::list<add_on_entry_info>::iterator eiter2 = diter->entries.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; eiter2 != diter->entries.end() ; eiter2++) {
|
2008-10-18 13:53:03 +00:00
|
|
|
if (strcmp(eiter2->name, info.name) == 0)
|
2004-02-01 05:49:14 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
// The new add-on should be enabled, but first we check to see
|
|
|
|
|
// if there is an add-on below us. If we find one, we disable it.
|
2004-02-01 05:49:14 +00:00
|
|
|
bool shadowing = false;
|
2008-10-18 13:53:03 +00:00
|
|
|
for (diter++ ; diter != fDirectories.end() ; diter++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
std::list<add_on_entry_info>::iterator eiter2 = diter->entries.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; eiter2 != diter->entries.end() ; eiter2++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
if (strcmp(eiter2->name, info.name) == 0) {
|
|
|
|
|
AddOnDisabled(&*eiter2);
|
|
|
|
|
shadowing = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-10-18 13:53:03 +00:00
|
|
|
if (shadowing)
|
2004-02-01 05:49:14 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2008-10-18 13:53:03 +00:00
|
|
|
|
|
|
|
|
// enable the new add-on
|
2004-02-01 05:49:14 +00:00
|
|
|
AddOnEnabled(&info);
|
2008-10-18 13:53:03 +00:00
|
|
|
|
2004-02-01 05:49:14 +00:00
|
|
|
// put the new entry into the target directory
|
|
|
|
|
to_iter->entries.push_back(info);
|
|
|
|
|
|
|
|
|
|
// done
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::list<add_on_entry_info>::iterator eiter = from_iter->entries.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; eiter != from_iter->entries.end() ; eiter++) {
|
2008-10-18 13:53:03 +00:00
|
|
|
if (entryNodeRef == eiter->nref) {
|
2004-02-01 05:49:14 +00:00
|
|
|
// save the old info and remove the entry
|
|
|
|
|
info = *eiter;
|
|
|
|
|
from_iter->entries.erase(eiter);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strcmp(info.name, name) == 0) {
|
|
|
|
|
// same name moved in heirarchy
|
2008-10-18 13:53:03 +00:00
|
|
|
debugger("add-on moved inside the heirarchy");
|
2004-02-01 05:49:14 +00:00
|
|
|
} else {
|
|
|
|
|
// check to see if it was formerly enabled
|
|
|
|
|
bool was_enabled = true;
|
2008-10-18 13:53:03 +00:00
|
|
|
std::list<add_on_directory_info>::iterator old_iter
|
|
|
|
|
= fDirectories.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; old_iter != from_iter ; old_iter++) {
|
2008-10-18 13:53:03 +00:00
|
|
|
std::list<add_on_entry_info>::iterator eiter2
|
|
|
|
|
= old_iter->entries.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; eiter2 != old_iter->entries.end() ; eiter2++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
if (strcmp(eiter2->name, info.name) == 0) {
|
|
|
|
|
was_enabled = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!was_enabled) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-10-18 13:53:03 +00:00
|
|
|
|
|
|
|
|
// if it was enabled, disable it and enable the one under us, if it
|
|
|
|
|
// exists
|
2004-02-01 05:49:14 +00:00
|
|
|
if (was_enabled) {
|
|
|
|
|
AddOnDisabled(&info);
|
|
|
|
|
bool done = false;
|
2008-10-18 13:53:03 +00:00
|
|
|
for (; old_iter != fDirectories.end() ; old_iter++) {
|
|
|
|
|
std::list<add_on_entry_info>::iterator eiter2
|
|
|
|
|
= old_iter->entries.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; eiter2 != old_iter->entries.end() ; eiter2++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
if (strcmp(eiter2->name, info.name) == 0) {
|
|
|
|
|
AddOnEnabled(&*eiter2);
|
|
|
|
|
done = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-10-18 13:53:03 +00:00
|
|
|
if (done)
|
2004-02-01 05:49:14 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// kaboom!
|
|
|
|
|
AddOnRemoved(&info);
|
|
|
|
|
|
|
|
|
|
// set up new addon info
|
|
|
|
|
strncpy(info.name, name, sizeof(info.name));
|
2008-10-18 13:53:03 +00:00
|
|
|
info.dir_nref = toNodeRef;
|
2004-02-01 05:49:14 +00:00
|
|
|
|
|
|
|
|
// presto!
|
|
|
|
|
AddOnCreated(&info);
|
2008-10-18 13:53:03 +00:00
|
|
|
|
2004-02-01 05:49:14 +00:00
|
|
|
// check to see if we are newly enabled
|
2008-10-18 13:53:03 +00:00
|
|
|
bool isEnabled = true;
|
|
|
|
|
std::list<add_on_directory_info>::iterator new_iter
|
|
|
|
|
= fDirectories.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; new_iter != to_iter ; new_iter++) {
|
2008-10-18 13:53:03 +00:00
|
|
|
std::list<add_on_entry_info>::iterator eiter2
|
|
|
|
|
= new_iter->entries.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; eiter2 != new_iter->entries.end() ; eiter2++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
if (strcmp(eiter2->name, info.name) == 0) {
|
2008-10-18 13:53:03 +00:00
|
|
|
isEnabled = false;
|
2004-02-01 05:49:14 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-10-18 13:53:03 +00:00
|
|
|
if (!isEnabled)
|
2004-02-01 05:49:14 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
// if it is newly enabled, check under us for an enabled one, and
|
|
|
|
|
// disable that first
|
|
|
|
|
if (isEnabled) {
|
2004-02-01 05:49:14 +00:00
|
|
|
bool done = false;
|
2008-10-18 13:53:03 +00:00
|
|
|
for (; new_iter != fDirectories.end() ; new_iter++) {
|
|
|
|
|
std::list<add_on_entry_info>::iterator eiter2
|
|
|
|
|
= new_iter->entries.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; eiter2 != new_iter->entries.end() ; eiter2++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
if (strcmp(eiter2->name, info.name) == 0) {
|
|
|
|
|
AddOnDisabled(&*eiter2);
|
|
|
|
|
done = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-10-18 13:53:03 +00:00
|
|
|
if (done)
|
2004-02-01 05:49:14 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
AddOnEnabled(&info);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// put the new entry into the target directory
|
|
|
|
|
to_iter->entries.push_back(info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
//! Process pending entries.
|
2004-02-01 05:49:14 +00:00
|
|
|
void
|
2008-10-18 13:53:03 +00:00
|
|
|
AddOnMonitorHandler::_HandlePulse()
|
2004-02-01 05:49:14 +00:00
|
|
|
{
|
|
|
|
|
BDirectory directory;
|
2008-10-18 13:53:03 +00:00
|
|
|
std::list<add_on_entry_info>::iterator iter = fPendingEntries.begin();
|
|
|
|
|
while (iter != fPendingEntries.end()) {
|
2004-02-01 05:49:14 +00:00
|
|
|
add_on_entry_info info = *iter;
|
2008-10-18 13:53:03 +00:00
|
|
|
|
|
|
|
|
node_ref dirNodeRef;
|
|
|
|
|
if ((directory.GetNodeRef(&dirNodeRef) != B_OK) ||
|
|
|
|
|
(dirNodeRef != info.dir_nref)) {
|
2004-02-01 05:49:14 +00:00
|
|
|
if (directory.SetTo(&info.dir_nref) != B_OK) {
|
|
|
|
|
// invalid directory, discard this pending entry
|
2008-10-18 13:53:03 +00:00
|
|
|
iter = fPendingEntries.erase(iter);
|
2004-02-01 05:49:14 +00:00
|
|
|
continue;
|
|
|
|
|
}
|
2008-10-18 13:53:03 +00:00
|
|
|
dirNodeRef = info.dir_nref;
|
2004-02-01 05:49:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct stat st;
|
|
|
|
|
if (directory.GetStatFor(info.name, &st) != B_OK) {
|
|
|
|
|
// invalid file name, discard this pending entry
|
2008-10-18 13:53:03 +00:00
|
|
|
iter = fPendingEntries.erase(iter);
|
2004-02-01 05:49:14 +00:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// stat units are seconds, real_time_clock units are seconds
|
|
|
|
|
if (real_time_clock() - st.st_mtime < ADD_ON_STABLE_SECONDS) {
|
|
|
|
|
// entry not stable, skip the entry for this pulse
|
|
|
|
|
iter++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// we are going to deal with the stable entry, so remove it
|
2008-10-18 13:53:03 +00:00
|
|
|
iter = fPendingEntries.erase(iter);
|
2004-02-01 05:49:14 +00:00
|
|
|
|
|
|
|
|
// put the new entry into the directory info
|
2008-10-18 13:53:03 +00:00
|
|
|
std::list<add_on_directory_info>::iterator diter = fDirectories.begin();
|
|
|
|
|
for (; diter != fDirectories.end() ; diter++) {
|
|
|
|
|
if (diter->nref == dirNodeRef) {
|
2004-02-01 05:49:14 +00:00
|
|
|
diter->entries.push_back(info);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// report it
|
|
|
|
|
AddOnCreated(&info);
|
|
|
|
|
|
|
|
|
|
// Start at the top again, and search until the directory we put
|
2008-10-18 13:53:03 +00:00
|
|
|
// the new add-on in. If we find a add-on with the same name then
|
|
|
|
|
// the new add-on should not be enabled.
|
2004-02-01 05:49:14 +00:00
|
|
|
bool enabled = true;
|
2008-10-18 13:53:03 +00:00
|
|
|
std::list<add_on_directory_info>::iterator diter2
|
|
|
|
|
= fDirectories.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; diter2 != diter ; diter2++) {
|
2008-10-18 13:53:03 +00:00
|
|
|
std::list<add_on_entry_info>::iterator eiter
|
|
|
|
|
= diter2->entries.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; eiter != diter2->entries.end() ; eiter++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
if (strcmp(eiter->name, info.name) == 0) {
|
|
|
|
|
enabled = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-10-18 13:53:03 +00:00
|
|
|
if (!enabled)
|
2004-02-01 05:49:14 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!enabled) {
|
|
|
|
|
// if we are not enabled, go on to the next pending entry
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2008-10-18 13:53:03 +00:00
|
|
|
// The new add-on should be enabled, but first we check to see
|
|
|
|
|
// if there is an add-on below us. If we find one, we disable it.
|
2004-02-01 05:49:14 +00:00
|
|
|
bool shadowing = false;
|
2008-10-18 13:53:03 +00:00
|
|
|
for (diter++ ; diter != fDirectories.end() ; diter++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
std::list<add_on_entry_info>::iterator eiter = diter->entries.begin();
|
2008-04-26 12:16:53 +00:00
|
|
|
for (; eiter != diter->entries.end() ; eiter++) {
|
2004-02-01 05:49:14 +00:00
|
|
|
if (strcmp(eiter->name, info.name) == 0) {
|
|
|
|
|
AddOnDisabled(&*eiter);
|
|
|
|
|
shadowing = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-10-18 13:53:03 +00:00
|
|
|
if (shadowing)
|
2004-02-01 05:49:14 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// finally, enable the new entry
|
|
|
|
|
AddOnEnabled(&info);
|
|
|
|
|
}
|
|
|
|
|
}
|