* Added "services" to the network settings, and refactored the settings class a bit
to be easier extendable with more classes. * Fixed a bug in the settings that caused updated settings to be appended to the existing ones (missing BMessage::MakeEmpty()). * Started services system, doesn't do anything useful yet (inetd replacement). * Fixed the bug that caused the loopback default netmask to be incorrectly chosen; removed the temporary fix Bruno introduced before. The same bug has been in ifconfig where I copied the code from (but wrote it there, too) :-). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19609 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -526,7 +526,7 @@ configure_interface(int socket, const char* name, char* const* args,
|
|||||||
if (!hasMask && hasAddress && kFamilies[familyIndex].family == AF_INET
|
if (!hasMask && hasAddress && kFamilies[familyIndex].family == AF_INET
|
||||||
&& ioctl(socket, SIOCGIFNETMASK, &request, sizeof(struct ifreq)) == 0
|
&& ioctl(socket, SIOCGIFNETMASK, &request, sizeof(struct ifreq)) == 0
|
||||||
&& request.ifr_mask.sa_family == AF_UNSPEC) {
|
&& request.ifr_mask.sa_family == AF_UNSPEC) {
|
||||||
// generate standard netmask if it doesn't have one yet
|
// generate standard netmask if it doesn't have one yet
|
||||||
sockaddr_in *netmask = (sockaddr_in *)&mask;
|
sockaddr_in *netmask = (sockaddr_in *)&mask;
|
||||||
netmask->sin_len = sizeof(sockaddr_in);
|
netmask->sin_len = sizeof(sockaddr_in);
|
||||||
netmask->sin_family = AF_INET;
|
netmask->sin_family = AF_INET;
|
||||||
@@ -537,7 +537,7 @@ configure_interface(int socket, const char* name, char* const* args,
|
|||||||
|| (ntohl(net) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
|
|| (ntohl(net) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
|
||||||
// class A, or loopback
|
// class A, or loopback
|
||||||
netmask->sin_addr.s_addr = IN_CLASSA_NET;
|
netmask->sin_addr.s_addr = IN_CLASSA_NET;
|
||||||
} if (IN_CLASSB(net)) {
|
} else if (IN_CLASSB(net)) {
|
||||||
// class B
|
// class B
|
||||||
netmask->sin_addr.s_addr = IN_CLASSB_NET;
|
netmask->sin_addr.s_addr = IN_CLASSB_NET;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ Server net_server :
|
|||||||
Settings.cpp
|
Settings.cpp
|
||||||
AutoconfigLooper.cpp
|
AutoconfigLooper.cpp
|
||||||
DHCPClient.cpp
|
DHCPClient.cpp
|
||||||
|
Services.cpp
|
||||||
;
|
;
|
||||||
|
|
||||||
LinkAgainst net_server :
|
LinkAgainst net_server :
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "AutoconfigLooper.h"
|
#include "AutoconfigLooper.h"
|
||||||
#include "NetServer.h"
|
#include "NetServer.h"
|
||||||
|
#include "Services.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
|
||||||
#include <Alert.h>
|
#include <Alert.h>
|
||||||
@@ -56,9 +57,11 @@ class NetServer : public BApplication {
|
|||||||
void _ConfigureDevices(int socket, const char* path);
|
void _ConfigureDevices(int socket, const char* path);
|
||||||
void _ConfigureInterfaces(int socket);
|
void _ConfigureInterfaces(int socket);
|
||||||
void _BringUpInterfaces();
|
void _BringUpInterfaces();
|
||||||
|
void _StartServices();
|
||||||
|
|
||||||
Settings fSettings;
|
Settings fSettings;
|
||||||
LooperMap fDeviceMap;
|
LooperMap fDeviceMap;
|
||||||
|
BMessenger fServices;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -212,6 +215,7 @@ NetServer::ReadyToRun()
|
|||||||
{
|
{
|
||||||
fSettings.StartMonitoring(this);
|
fSettings.StartMonitoring(this);
|
||||||
_BringUpInterfaces();
|
_BringUpInterfaces();
|
||||||
|
_StartServices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -235,6 +239,15 @@ NetServer::MessageReceived(BMessage* message)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kMsgServiceSettingsUpdated:
|
||||||
|
{
|
||||||
|
BMessage update = fSettings.Services();
|
||||||
|
update.what = kMsgUpdateServices;
|
||||||
|
|
||||||
|
fServices.SendMessage(&update);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case kMsgConfigureInterface:
|
case kMsgConfigureInterface:
|
||||||
{
|
{
|
||||||
if (!message->ReturnAddress().IsTargetLocal()) {
|
if (!message->ReturnAddress().IsTargetLocal()) {
|
||||||
@@ -455,7 +468,7 @@ NetServer::_ConfigureInterface(int socket, BMessage& interface, bool fromMessage
|
|||||||
if (!hasMask && hasAddress && kFamilies[familyIndex].family == AF_INET
|
if (!hasMask && hasAddress && kFamilies[familyIndex].family == AF_INET
|
||||||
&& ioctl(familySocket, SIOCGIFNETMASK, &request, sizeof(struct ifreq)) == 0
|
&& ioctl(familySocket, SIOCGIFNETMASK, &request, sizeof(struct ifreq)) == 0
|
||||||
&& request.ifr_mask.sa_family == AF_UNSPEC) {
|
&& request.ifr_mask.sa_family == AF_UNSPEC) {
|
||||||
// generate standard netmask if it doesn't have one yet
|
// generate standard netmask if it doesn't have one yet
|
||||||
sockaddr_in *netmask = (sockaddr_in *)&mask;
|
sockaddr_in *netmask = (sockaddr_in *)&mask;
|
||||||
netmask->sin_len = sizeof(sockaddr_in);
|
netmask->sin_len = sizeof(sockaddr_in);
|
||||||
netmask->sin_family = AF_INET;
|
netmask->sin_family = AF_INET;
|
||||||
@@ -466,7 +479,7 @@ NetServer::_ConfigureInterface(int socket, BMessage& interface, bool fromMessage
|
|||||||
|| (ntohl(net) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
|
|| (ntohl(net) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
|
||||||
// class A, or loopback
|
// class A, or loopback
|
||||||
netmask->sin_addr.s_addr = IN_CLASSA_NET;
|
netmask->sin_addr.s_addr = IN_CLASSA_NET;
|
||||||
} if (IN_CLASSB(net)) {
|
} else if (IN_CLASSB(net)) {
|
||||||
// class B
|
// class B
|
||||||
netmask->sin_addr.s_addr = IN_CLASSB_NET;
|
netmask->sin_addr.s_addr = IN_CLASSB_NET;
|
||||||
} else {
|
} else {
|
||||||
@@ -665,7 +678,6 @@ NetServer::_BringUpInterfaces()
|
|||||||
BMessage address;
|
BMessage address;
|
||||||
address.AddString("family", "inet");
|
address.AddString("family", "inet");
|
||||||
address.AddString("address", "127.0.0.1");
|
address.AddString("address", "127.0.0.1");
|
||||||
address.AddString("mask", "255.0.0.0");
|
|
||||||
interface.AddMessage("address", &address);
|
interface.AddMessage("address", &address);
|
||||||
|
|
||||||
_ConfigureInterface(socket, interface);
|
_ConfigureInterface(socket, interface);
|
||||||
@@ -680,6 +692,17 @@ NetServer::_BringUpInterfaces()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NetServer::_StartServices()
|
||||||
|
{
|
||||||
|
BHandler* services = new (std::nothrow) Services(fSettings.Services());
|
||||||
|
if (services != NULL) {
|
||||||
|
AddHandler(services);
|
||||||
|
fServices = BMessenger(services);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,225 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "Services.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
#include <Autolock.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
struct service_address {
|
||||||
|
int socket;
|
||||||
|
int family;
|
||||||
|
uint16 port;
|
||||||
|
sockaddr address;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef vector<service_address> AddressList;
|
||||||
|
|
||||||
|
struct service {
|
||||||
|
std::string name;
|
||||||
|
std::string launch;
|
||||||
|
int type;
|
||||||
|
int protocol;
|
||||||
|
uint16 port;
|
||||||
|
uid_t user;
|
||||||
|
gid_t group;
|
||||||
|
AddressList addresses;
|
||||||
|
|
||||||
|
~service();
|
||||||
|
bool operator!=(const struct service& other);
|
||||||
|
bool operator==(const struct service& other);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
service::~service()
|
||||||
|
{
|
||||||
|
// close all open sockets
|
||||||
|
AddressList::const_iterator iterator = addresses.begin();
|
||||||
|
for (; iterator != addresses.end(); iterator++) {
|
||||||
|
const service_address& address = *iterator;
|
||||||
|
|
||||||
|
close(address.socket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
service::operator!=(const struct service& other)
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
service::operator==(const struct service& other)
|
||||||
|
{
|
||||||
|
if (name != other.name
|
||||||
|
|| launch != other.launch
|
||||||
|
|| type != other.type
|
||||||
|
|| protocol != other.protocol
|
||||||
|
|| port != other.port)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// TODO: compare addresses!
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
Services::Services(const BMessage& services)
|
||||||
|
:
|
||||||
|
fUpdate(0)
|
||||||
|
{
|
||||||
|
_Update(services);
|
||||||
|
|
||||||
|
fListener = spawn_thread(_Listener, "services listener", B_NORMAL_PRIORITY, this);
|
||||||
|
if (fListener >= B_OK)
|
||||||
|
resume_thread(fListener);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Services::~Services()
|
||||||
|
{
|
||||||
|
wait_for_thread(fListener, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Services::InitCheck() const
|
||||||
|
{
|
||||||
|
return fListener >= B_OK ? B_OK : fListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Services::MessageReceived(BMessage* message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case kMsgServiceSettingsUpdated:
|
||||||
|
_Update(*message);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
BHandler::MessageReceived(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Services::_StartService(struct service& service)
|
||||||
|
{
|
||||||
|
// add service to maps
|
||||||
|
|
||||||
|
fNameMap[service.name] = &service;
|
||||||
|
|
||||||
|
AddressList::const_iterator iterator = service.addresses.begin();
|
||||||
|
for (; iterator != service.addresses.end(); iterator++) {
|
||||||
|
const service_address& address = *iterator;
|
||||||
|
|
||||||
|
fSocketMap[address.socket] = &service;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Services::_StopService(struct service& service)
|
||||||
|
{
|
||||||
|
// remove service from maps
|
||||||
|
{
|
||||||
|
ServiceNameMap::iterator iterator = fNameMap.find(service.name);
|
||||||
|
if (iterator != fNameMap.end())
|
||||||
|
fNameMap.erase(iterator);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
AddressList::const_iterator iterator = service.addresses.begin();
|
||||||
|
for (; iterator != service.addresses.end(); iterator++) {
|
||||||
|
const service_address& address = *iterator;
|
||||||
|
|
||||||
|
ServiceSocketMap::iterator socketIterator = fSocketMap.find(address.socket);
|
||||||
|
if (socketIterator != fSocketMap.end())
|
||||||
|
fSocketMap.erase(socketIterator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete &service;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Services::_ToService(const BMessage& message, struct service*& service)
|
||||||
|
{
|
||||||
|
// get mandatory fields
|
||||||
|
const char* name;
|
||||||
|
const char* launch;
|
||||||
|
if (message.FindString("name", &name) != B_OK
|
||||||
|
|| message.FindString("launch", &launch) != B_OK)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
service = new (std::nothrow) ::service;
|
||||||
|
if (service == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
service->name = name;
|
||||||
|
service->launch = launch;
|
||||||
|
|
||||||
|
// TODO: fill in other fields
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Services::_Update(const BMessage& services)
|
||||||
|
{
|
||||||
|
BAutolock locker(fLock);
|
||||||
|
fUpdate++;
|
||||||
|
|
||||||
|
BMessage message;
|
||||||
|
for (int32 index = 0; services.FindMessage("service", index,
|
||||||
|
&message) == B_OK; index++) {
|
||||||
|
const char* name;
|
||||||
|
if (message.FindString("name", &name) != B_OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
struct service* service;
|
||||||
|
if (_ToService(message, service) != B_OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ServiceNameMap::iterator iterator = fNameMap.find(name);
|
||||||
|
if (iterator == fNameMap.end()) {
|
||||||
|
// this service does not exist yet, start it
|
||||||
|
_StartService(*service);
|
||||||
|
} else {
|
||||||
|
// this service does already exist - check for any changes
|
||||||
|
|
||||||
|
if (service != iterator->second) {
|
||||||
|
_StopService(*iterator->second);
|
||||||
|
_StartService(*service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ status_t
|
||||||
|
Services::_Listener(void* self)
|
||||||
|
{
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
|
*/
|
||||||
|
#ifndef SERVICES_H
|
||||||
|
#define SERVICES_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Handler.h>
|
||||||
|
#include <Locker.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
struct service;
|
||||||
|
typedef std::map<std::string, service*> ServiceNameMap;
|
||||||
|
typedef std::map<int, service*> ServiceSocketMap;
|
||||||
|
|
||||||
|
|
||||||
|
class Services : public BHandler {
|
||||||
|
public:
|
||||||
|
Services(const BMessage& services);
|
||||||
|
virtual ~Services();
|
||||||
|
|
||||||
|
status_t InitCheck() const;
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
status_t _StartService(struct service& service);
|
||||||
|
status_t _StopService(struct service& service);
|
||||||
|
status_t _ToService(const BMessage& message, struct service*& service);
|
||||||
|
void _Update(const BMessage& services);
|
||||||
|
int32 _CompareServices(struct service& a, struct service& b);
|
||||||
|
static status_t _Listener(void* self);
|
||||||
|
|
||||||
|
thread_id fListener;
|
||||||
|
BLocker fLock;
|
||||||
|
ServiceNameMap fNameMap;
|
||||||
|
ServiceSocketMap fSocketMap;
|
||||||
|
int32 fUpdate;
|
||||||
|
};
|
||||||
|
|
||||||
|
const static uint32 kMsgUpdateServices = 'srvU';
|
||||||
|
|
||||||
|
#endif // SERVICES_H
|
||||||
+106
-44
@@ -19,6 +19,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Interface templates
|
||||||
|
|
||||||
const static settings_template kInterfaceAddressTemplate[] = {
|
const static settings_template kInterfaceAddressTemplate[] = {
|
||||||
{B_STRING_TYPE, "family", NULL},
|
{B_STRING_TYPE, "family", NULL},
|
||||||
{B_STRING_TYPE, "address", NULL},
|
{B_STRING_TYPE, "address", NULL},
|
||||||
@@ -30,7 +32,7 @@ const static settings_template kInterfaceAddressTemplate[] = {
|
|||||||
{0, NULL, NULL}
|
{0, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
const static settings_template kInterfaceDeviceTemplate[] = {
|
const static settings_template kInterfaceTemplate[] = {
|
||||||
{B_STRING_TYPE, "device", NULL},
|
{B_STRING_TYPE, "device", NULL},
|
||||||
{B_MESSAGE_TYPE, "address", kInterfaceAddressTemplate},
|
{B_MESSAGE_TYPE, "address", kInterfaceAddressTemplate},
|
||||||
{B_INT32_TYPE, "flags", NULL},
|
{B_INT32_TYPE, "flags", NULL},
|
||||||
@@ -39,8 +41,32 @@ const static settings_template kInterfaceDeviceTemplate[] = {
|
|||||||
{0, NULL, NULL}
|
{0, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
const static settings_template kInterfaceTemplate[] = {
|
const static settings_template kInterfacesTemplate[] = {
|
||||||
{B_MESSAGE_TYPE, "interface", kInterfaceDeviceTemplate},
|
{B_MESSAGE_TYPE, "interface", kInterfaceTemplate},
|
||||||
|
{0, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Service templates
|
||||||
|
|
||||||
|
const static settings_template kServiceAddressTemplate[] = {
|
||||||
|
{B_STRING_TYPE, "family", NULL},
|
||||||
|
{B_STRING_TYPE, "address", NULL},
|
||||||
|
{B_INT32_TYPE, "port", NULL},
|
||||||
|
{0, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
const static settings_template kServiceTemplate[] = {
|
||||||
|
{B_STRING_TYPE, "name", NULL},
|
||||||
|
{B_MESSAGE_TYPE, "address", kServiceAddressTemplate},
|
||||||
|
{B_STRING_TYPE, "user", NULL},
|
||||||
|
{B_STRING_TYPE, "group", NULL},
|
||||||
|
{B_STRING_TYPE, "launch", NULL},
|
||||||
|
{B_INT32_TYPE, "port", NULL},
|
||||||
|
{0, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
const static settings_template kServicesTemplate[] = {
|
||||||
|
{B_MESSAGE_TYPE, "service", kServiceTemplate},
|
||||||
{0, NULL, NULL}
|
{0, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -76,7 +102,8 @@ Settings::_GetPath(const char* name, BPath& path)
|
|||||||
path.Append("network");
|
path.Append("network");
|
||||||
create_directory(path.Path(), 0755);
|
create_directory(path.Path(), 0755);
|
||||||
|
|
||||||
path.Append(name);
|
if (name != NULL)
|
||||||
|
path.Append(name);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,6 +174,8 @@ status_t
|
|||||||
Settings::_ConvertFromDriverSettings(const driver_settings& settings,
|
Settings::_ConvertFromDriverSettings(const driver_settings& settings,
|
||||||
const settings_template* settingsTemplate, BMessage& message)
|
const settings_template* settingsTemplate, BMessage& message)
|
||||||
{
|
{
|
||||||
|
message.MakeEmpty();
|
||||||
|
|
||||||
for (int32 i = 0; i < settings.parameter_count; i++) {
|
for (int32 i = 0; i < settings.parameter_count; i++) {
|
||||||
status_t status = _ConvertFromDriverParameter(settings.parameters[i],
|
status_t status = _ConvertFromDriverParameter(settings.parameters[i],
|
||||||
settingsTemplate, message);
|
settingsTemplate, message);
|
||||||
@@ -185,49 +214,67 @@ Settings::_ConvertFromDriverSettings(const char* name,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Settings::_Load()
|
Settings::_Load(const char* name, uint32* _type)
|
||||||
{
|
{
|
||||||
return _ConvertFromDriverSettings("interfaces", kInterfaceTemplate, fInterfaces);
|
status_t status = B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
|
if (name == NULL || !strcmp(name, "interfaces")) {
|
||||||
|
status = _ConvertFromDriverSettings("interfaces", kInterfacesTemplate,
|
||||||
|
fInterfaces);
|
||||||
|
if (status == B_OK && _type != NULL)
|
||||||
|
*_type = kMsgInterfaceSettingsUpdated;
|
||||||
|
}
|
||||||
|
if (name == NULL || !strcmp(name, "services")) {
|
||||||
|
status = _ConvertFromDriverSettings("services", kServicesTemplate,
|
||||||
|
fServices);
|
||||||
|
if (status == B_OK && _type != NULL)
|
||||||
|
*_type = kMsgServiceSettingsUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Settings::_StartWatching(const char* name, const BMessenger& target)
|
||||||
|
{
|
||||||
|
BPath path;
|
||||||
|
status_t status = _GetPath(name, path);
|
||||||
|
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,
|
||||||
|
target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Settings::StartMonitoring(const BMessenger& target)
|
Settings::StartMonitoring(const BMessenger& target)
|
||||||
{
|
{
|
||||||
|
if (_IsWatching(target))
|
||||||
|
return B_OK;
|
||||||
|
if (_IsWatching())
|
||||||
|
StopMonitoring(fListener);
|
||||||
|
|
||||||
fListener = target;
|
fListener = target;
|
||||||
|
|
||||||
BPath path;
|
status_t status = _StartWatching(NULL, target);
|
||||||
status_t status = _GetPath("interfaces", path);
|
if (status == B_OK)
|
||||||
if (status < B_OK)
|
status = _StartWatching("interfaces", target);
|
||||||
return status;
|
if (status == B_OK)
|
||||||
|
status = _StartWatching("services", target);
|
||||||
|
|
||||||
node_ref ref;
|
return status;
|
||||||
BNode node;
|
|
||||||
|
|
||||||
BPath parent;
|
|
||||||
if (path.GetParent(&parent) == B_OK) {
|
|
||||||
status = node.SetTo(parent.Path());
|
|
||||||
if (status < B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
status = node.GetNodeRef(&ref);
|
|
||||||
if (status < B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
status = watch_node(&ref, B_WATCH_DIRECTORY, target);
|
|
||||||
if (status < B_OK)
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = node.SetTo(path.Path());
|
|
||||||
if (status < B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
status = node.GetNodeRef(&ref);
|
|
||||||
if (status < B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
return watch_node(&ref, B_WATCH_STAT, target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -252,13 +299,9 @@ Settings::Update(BMessage* message)
|
|||||||
if (opcode == B_ENTRY_REMOVED)
|
if (opcode == B_ENTRY_REMOVED)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
if (!strcmp(name, "interfaces")) {
|
uint32 type;
|
||||||
status_t status = _ConvertFromDriverSettings("interfaces",
|
if (_Load(name, &type) == B_OK) {
|
||||||
kInterfaceTemplate, fInterfaces);
|
BMessage update(type);
|
||||||
if (status < B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
BMessage update(kMsgInterfaceSettingsUpdated);
|
|
||||||
fListener.SendMessage(&update);
|
fListener.SendMessage(&update);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,3 +320,22 @@ Settings::GetNextInterface(uint32& cookie, BMessage& interface)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Settings::GetNextService(uint32& cookie, BMessage& service)
|
||||||
|
{
|
||||||
|
status_t status = fServices.FindMessage("service", cookie, &service);
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
cookie++;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const BMessage&
|
||||||
|
Settings::Services() const
|
||||||
|
{
|
||||||
|
return fServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,15 +29,19 @@ class Settings {
|
|||||||
~Settings();
|
~Settings();
|
||||||
|
|
||||||
status_t GetNextInterface(uint32& cookie, BMessage& interface);
|
status_t GetNextInterface(uint32& cookie, BMessage& interface);
|
||||||
|
status_t GetNextService(uint32& cookie, BMessage& service);
|
||||||
|
const BMessage& Services() const;
|
||||||
|
|
||||||
status_t StartMonitoring(const BMessenger& target);
|
status_t StartMonitoring(const BMessenger& target);
|
||||||
status_t StopMonitoring(const BMessenger& target);
|
status_t StopMonitoring(const BMessenger& target);
|
||||||
|
|
||||||
status_t Update(BMessage* message);
|
status_t Update(BMessage* message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _Load();
|
status_t _Load(const char* name = NULL, uint32* _type = NULL);
|
||||||
status_t _GetPath(const char* name, BPath& path);
|
status_t _GetPath(const char* name, BPath& path);
|
||||||
|
|
||||||
|
status_t _StartWatching(const char* name, const BMessenger& target);
|
||||||
const settings_template* _FindSettingsTemplate(const settings_template* settingsTemplate,
|
const settings_template* _FindSettingsTemplate(const settings_template* settingsTemplate,
|
||||||
const char* name);
|
const char* name);
|
||||||
status_t _ConvertFromDriverParameter(const driver_parameter& parameter,
|
status_t _ConvertFromDriverParameter(const driver_parameter& parameter,
|
||||||
@@ -47,11 +51,16 @@ class Settings {
|
|||||||
status_t _ConvertFromDriverSettings(const char* path,
|
status_t _ConvertFromDriverSettings(const char* path,
|
||||||
const settings_template* settingsTemplate, BMessage& message);
|
const settings_template* settingsTemplate, BMessage& message);
|
||||||
|
|
||||||
|
bool _IsWatching(const BMessenger& target) const { return fListener == target; }
|
||||||
|
bool _IsWatching() const { return fListener.IsValid(); }
|
||||||
|
|
||||||
BMessenger fListener;
|
BMessenger fListener;
|
||||||
BMessage fInterfaces;
|
BMessage fInterfaces;
|
||||||
|
BMessage fServices;
|
||||||
bool fUpdated;
|
bool fUpdated;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint32 kMsgInterfaceSettingsUpdated = 'SUif';
|
static const uint32 kMsgInterfaceSettingsUpdated = 'SUif';
|
||||||
|
static const uint32 kMsgServiceSettingsUpdated = 'SUsv';
|
||||||
|
|
||||||
#endif // SETTINGS_H
|
#endif // SETTINGS_H
|
||||||
|
|||||||
Reference in New Issue
Block a user