* Now uses BPathMonitor instead of the node monitor; this fixes several issues with

changes to settings files that were ignored (for example, watching "services" did
  only work if "interfaces" existed).
* On services update, Services::_Update() accidently compared the pointers of the
  service objects, instead of the objects themselves.
* Implemented comparison of address changes in service objects; IOW when you change
  the addresses a service should bind itself to, but leave the rest of the service
  unchanged, this will now be detected as well.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21555 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2007-07-04 18:53:51 +00:00
parent 2702a877ac
commit 43d946d6d6
4 changed files with 69 additions and 32 deletions

View File

@ -1,6 +1,6 @@
SubDir HAIKU_TOP src servers net ;
UsePrivateHeaders app net ;
UsePrivateHeaders app net storage ;
#UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libppp headers ] ;
#UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel network ppp shared libkernelppp headers ] ;

View File

@ -16,8 +16,8 @@
#include <Deskbar.h>
#include <Directory.h>
#include <Entry.h>
#include <NodeMonitor.h>
#include <Path.h>
#include <PathMonitor.h>
#include <Roster.h>
#include <Server.h>
#include <TextView.h>
@ -278,7 +278,7 @@ void
NetServer::MessageReceived(BMessage* message)
{
switch (message->what) {
case B_NODE_MONITOR:
case B_PATH_MONITOR:
fSettings.Update(message);
break;

View File

@ -30,6 +30,8 @@ struct service_address {
int type;
int protocol;
sockaddr address;
bool operator==(const struct service_address& other) const;
};
typedef vector<service_address> AddressList;
@ -42,8 +44,8 @@ struct service {
AddressList addresses;
~service();
bool operator!=(const struct service& other);
bool operator==(const struct service& other);
bool operator!=(const struct service& other) const;
bool operator==(const struct service& other) const;
};
@ -86,6 +88,20 @@ type_for_protocol(int protocol)
// #pragma mark -
bool
service_address::operator==(const struct service_address& other) const
{
return family == other.family
&& type == other.type
&& protocol == other.protocol
&& address.sa_len == other.address.sa_len
&& !memcmp(&address, &other.address, address.sa_len);
}
// #pragma mark -
service::~service()
{
// close all open sockets
@ -99,20 +115,38 @@ service::~service()
bool
service::operator!=(const struct service& other)
service::operator!=(const struct service& other) const
{
return !(*this == other);
}
bool
service::operator==(const struct service& other)
service::operator==(const struct service& other) const
{
if (name != other.name
|| launch != other.launch)
|| launch != other.launch
|| addresses.size() != other.addresses.size())
return false;
// TODO: compare addresses!
// compare addresses
AddressList::const_iterator iterator = addresses.begin();
for (; iterator != addresses.end(); iterator++) {
const service_address& address = *iterator;
// find address in other addresses
AddressList::const_iterator otherIterator = other.addresses.begin();
for (; otherIterator != other.addresses.end(); otherIterator++) {
if (address == *otherIterator)
break;
}
if (otherIterator == other.addresses.end())
return false;
}
return true;
}
@ -419,7 +453,7 @@ Services::_Update(const BMessage& services)
} else {
// this service does already exist - check for any changes
if (service != iterator->second) {
if (*service != *iterator->second) {
_StopService(*iterator->second);
_StartService(*service);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2006, Haiku, Inc. All Rights Reserved.
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -11,8 +11,9 @@
#include <Directory.h>
#include <FindDirectory.h>
#include <NodeMonitor.h>
#include <fs_interface.h>
#include <Path.h>
#include <PathMonitor.h>
#include <stdio.h>
#include <stdlib.h>
@ -158,7 +159,8 @@ Settings::_ConvertFromDriverParameter(const driver_parameter& parameter,
}
}
if (settingsTemplate->type == B_MESSAGE_TYPE && parameter.parameter_count > 0) {
if (settingsTemplate->type == B_MESSAGE_TYPE
&& parameter.parameter_count > 0) {
status_t status = B_OK;
BMessage subMessage;
for (int32 j = 0; j < parameter.parameter_count; j++) {
@ -248,17 +250,7 @@ Settings::_StartWatching(const char* name, const BMessenger& target)
if (status < B_OK)
return status;
BNode node;
status = node.SetTo(path.Path());
if (status < B_OK)
return status;
node_ref ref;
status = node.GetNodeRef(&ref);
if (status < B_OK)
return status;
return watch_node(&ref, name != NULL ? B_WATCH_STAT : B_WATCH_DIRECTORY,
return BPrivate::BPathMonitor::StartWatching(path.Path(), B_WATCH_STAT,
target);
}
@ -273,9 +265,7 @@ Settings::StartMonitoring(const BMessenger& target)
fListener = target;
status_t status = _StartWatching(NULL, target);
if (status == B_OK)
status = _StartWatching("interfaces", target);
status_t status = _StartWatching("interfaces", target);
if (status == B_OK)
status = _StartWatching("services", target);
@ -288,24 +278,37 @@ Settings::StopMonitoring(const BMessenger& target)
{
// TODO: this needs to be changed in case the server will watch
// anything else but settings
return stop_watching(target);
return BPrivate::BPathMonitor::StopWatching(target);
}
status_t
Settings::Update(BMessage* message)
{
const char* name;
message->PrintToStream();
const char* pathName;
int32 opcode;
if (message->FindInt32("opcode", &opcode) < B_OK
|| message->FindString("name", &name) < B_OK)
|| message->FindString("path", &pathName) < B_OK)
return B_BAD_VALUE;
if (opcode == B_ENTRY_REMOVED)
if (message->FindBool("removed")) {
// for now, we only consider existing settings files
// (ie. deleting "services" won't stop any)
return B_OK;
}
int32 fields;
if (opcode == B_STAT_CHANGED
&& message->FindInt32("fields", &fields) == B_OK
&& (fields & FS_WRITE_STAT_MTIME) == 0) {
// only update when the modified time has changed
return B_OK;
}
BPath path(pathName);
uint32 type;
if (_Load(name, &type) == B_OK) {
if (_Load(path.Leaf(), &type) == B_OK) {
BMessage update(type);
fListener.SendMessage(&update);
}