diff --git a/src/servers/syslog_daemon/Jamfile b/src/servers/syslog_daemon/Jamfile new file mode 100644 index 0000000000..a6615bfed6 --- /dev/null +++ b/src/servers/syslog_daemon/Jamfile @@ -0,0 +1,13 @@ +SubDir OBOS_TOP src servers syslog_daemon ; + +UsePrivateHeaders syslog_daemon ; + +AddResources syslog_daemon : SyslogDaemon.rsrc ; + +Server syslog_daemon : + SyslogDaemon.cpp + syslog_output.cpp + listener_output.cpp + ; + +LinkSharedOSLibs syslog_daemon : be ; diff --git a/src/servers/syslog_daemon/SyslogDaemon.cpp b/src/servers/syslog_daemon/SyslogDaemon.cpp new file mode 100644 index 0000000000..228ce3c2a8 --- /dev/null +++ b/src/servers/syslog_daemon/SyslogDaemon.cpp @@ -0,0 +1,165 @@ +/* +** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ + + +#include "SyslogDaemon.h" +#include "listener_output.h" +#include "syslog_output.h" + +#include +#include +#include +#include +#include + +#include +#include + + +const char *kSignature = "application/x-vnd.Be-SYSL"; + + +SyslogDaemon::SyslogDaemon() + : BApplication(kSignature), + fHandlerLock("handler lock") +{ +} + + +void +SyslogDaemon::ReadyToRun() +{ + fPort = create_port(256, SYSLOG_PORT_NAME); + fDaemon = spawn_thread(daemon_thread, "daemon", B_NORMAL_PRIORITY, this); + resume_thread(fDaemon); + + if (fPort >= B_OK && fDaemon >= B_OK) { + init_syslog_output(this); + init_listener_output(this); + } else + Quit(); +} + + +void +SyslogDaemon::AboutRequested() +{ + BPath path; + find_directory(B_COMMON_LOG_DIRECTORY, &path); + path.Append("syslog"); + + char message[512]; + sprintf(message, + "Syslog Daemon\n\n" + "This daemon is responsible for collecting " + "all system messages and write them to the " + "system-wide log at \"%s\".\n\n", path.Path()); + + BAlert *alert = new BAlert("Syslog Daemon", message, "Ok"); + BTextView *view = alert->TextView(); + BFont font; + + view->SetStylable(true); + + view->GetFont(&font); + font.SetSize(21); + font.SetFace(B_BOLD_FACE); + view->SetFontAndColor(0, 13, &font); + + alert->Go(NULL); +} + + +bool +SyslogDaemon::QuitRequested() +{ + delete_port(fPort); + + int32 returnCode; + wait_for_thread(fDaemon, &returnCode); + + return true; +} + + +void +SyslogDaemon::MessageReceived(BMessage *msg) +{ + switch (msg->what) { + case SYSLOG_ADD_LISTENER: + { + BMessenger messenger; + if (msg->FindMessenger("target", &messenger) == B_OK) + add_listener(&messenger); + break; + } + case SYSLOG_REMOVE_LISTENER: + { + BMessenger messenger; + if (msg->FindMessenger("target", &messenger) == B_OK) + remove_listener(&messenger); + break; + } + + default: + BApplication::MessageReceived(msg); + } +} + + +void +SyslogDaemon::AddHandler(handler_func function) +{ + fHandlers.AddItem((void *)function); +} + + +void +SyslogDaemon::Daemon() +{ + char buffer[4096]; + syslog_message &message = *(syslog_message *)buffer; + int32 code; + + while (true) { + ssize_t bytesRead = read_port(fPort, &code, &message, sizeof(buffer)); + if (bytesRead == B_BAD_PORT_ID) { + // we've been quit + break; + } + + // if we don't get what we want, ignore it + if (bytesRead < (ssize_t)sizeof(syslog_message) || code != SYSLOG_MESSAGE) + continue; + + fHandlerLock.Lock(); + + for (int32 i = fHandlers.CountItems(); i-- > 0;) { + handler_func handle = (handler_func)fHandlers.ItemAt(i); + + handle(message); + } + + fHandlerLock.Unlock(); + } +} + + +int32 +SyslogDaemon::daemon_thread(void *data) +{ + ((SyslogDaemon *)data)->Daemon(); + return B_OK; +} + + +int +main(int argc, char **argv) +{ + SyslogDaemon daemon; + daemon.Run(); + + return 0; +} diff --git a/src/servers/syslog_daemon/SyslogDaemon.h b/src/servers/syslog_daemon/SyslogDaemon.h new file mode 100644 index 0000000000..af12611fff --- /dev/null +++ b/src/servers/syslog_daemon/SyslogDaemon.h @@ -0,0 +1,42 @@ +/* +** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ +#ifndef _SYSLOG_DAEMON_H_ +#define _SYSLOG_DAEMON_H_ + + +#include +#include +#include +#include + +#include + + +typedef void (*handler_func)(syslog_message &); + + +class SyslogDaemon : public BApplication { + public: + SyslogDaemon(); + + virtual void ReadyToRun(); + virtual void AboutRequested(); + virtual bool QuitRequested(); + virtual void MessageReceived(BMessage *msg); + + void AddHandler(handler_func function); + + void Daemon(); + static int32 daemon_thread(void *data); + + private: + thread_id fDaemon; + port_id fPort; + + BLocker fHandlerLock; + BList fHandlers; +}; + +#endif /* _SYSLOG_DAEMON_H_ */ diff --git a/src/servers/syslog_daemon/SyslogDaemon.rsrc b/src/servers/syslog_daemon/SyslogDaemon.rsrc new file mode 100644 index 0000000000..08e3938568 Binary files /dev/null and b/src/servers/syslog_daemon/SyslogDaemon.rsrc differ diff --git a/src/servers/syslog_daemon/listener_output.cpp b/src/servers/syslog_daemon/listener_output.cpp new file mode 100644 index 0000000000..6644d3dbf0 --- /dev/null +++ b/src/servers/syslog_daemon/listener_output.cpp @@ -0,0 +1,73 @@ +/* +** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ + + +#include "listener_output.h" + +#include + + +static BLocker sLocker; +static BList sListeners; + + +static void +listener_output(syslog_message &message) +{ + // compose the message to be sent to all listeners; just convert + // the syslog_message into a BMessage + BMessage output(SYSLOG_MESSAGE); + + output.AddInt32("from", message.from); + output.AddInt32("when", message.when); + output.AddString("ident", message.ident); + output.AddString("message", message.message); + output.AddInt32("options", message.options); + output.AddInt32("priority", message.priority); + + sLocker.Lock(); + + for (int32 i = sListeners.CountItems(); i-- > 0;) { + BMessenger *target = (BMessenger *)sListeners.ItemAt(i); + + status_t status = target->SendMessage(&output); + if (status < B_OK) { + // remove targets once they can't be reached anymore + sListeners.RemoveItem(target); + } + } + + sLocker.Unlock(); +} + + +void +remove_listener(BMessenger *messenger) +{ + if (sLocker.Lock()) { + sListeners.RemoveItem(messenger); + + sLocker.Unlock(); + } +} + + +void +add_listener(BMessenger *messenger) +{ + if (sLocker.Lock()) { + sListeners.AddItem(messenger); + + sLocker.Unlock(); + } +} + + +void +init_listener_output(SyslogDaemon *daemon) +{ + daemon->AddHandler(listener_output); +} + diff --git a/src/servers/syslog_daemon/listener_output.h b/src/servers/syslog_daemon/listener_output.h new file mode 100644 index 0000000000..e93614bb76 --- /dev/null +++ b/src/servers/syslog_daemon/listener_output.h @@ -0,0 +1,16 @@ +/* +** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ +#ifndef _LISTENER_OUTPUT_H_ +#define _LISTENER_OUTPUT_H_ + +#include +#include "SyslogDaemon.h" + + +void init_listener_output(SyslogDaemon *daemon); +void add_listener(BMessenger *messenger); +void remove_listener(BMessenger *messenger); + +#endif /* _SYSLOG_OUTPUT_H_ */ diff --git a/src/servers/syslog_daemon/syslog_output.cpp b/src/servers/syslog_daemon/syslog_output.cpp new file mode 100644 index 0000000000..83ba6b19ce --- /dev/null +++ b/src/servers/syslog_daemon/syslog_output.cpp @@ -0,0 +1,24 @@ +/* +** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ + + +#include "syslog_output.h" + +#include + + +static void +syslog_output(syslog_message &message) +{ + printf("'%s'[%ld]: %s\n", message.ident, message.from, message.message); +} + + +void +init_syslog_output(SyslogDaemon *daemon) +{ + daemon->AddHandler(syslog_output); +} + diff --git a/src/servers/syslog_daemon/syslog_output.h b/src/servers/syslog_daemon/syslog_output.h new file mode 100644 index 0000000000..501bc4992e --- /dev/null +++ b/src/servers/syslog_daemon/syslog_output.h @@ -0,0 +1,12 @@ +/* +** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ +#ifndef _SYSLOG_OUTPUT_H_ +#define _SYSLOG_OUTPUT_H_ + +#include "SyslogDaemon.h" + +void init_syslog_output(SyslogDaemon *daemon); + +#endif /* _SYSLOG_OUTPUT_H_ */