2 * Copyright 2003-2015, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
7 #include "SyslogDaemon.h"
14 #include <FindDirectory.h>
19 #include <LaunchRoster.h>
21 #include <syslog_daemon.h>
23 #include "listener_output.h"
24 #include "syslog_output.h"
27 #undef B_TRANSLATION_CONTEXT
28 #define B_TRANSLATION_CONTEXT "SyslogDaemon"
31 static const int32 kQuitDaemon
= 'quit';
34 SyslogDaemon::SyslogDaemon()
36 BApplication(B_SYSTEM_LOGGER_SIGNATURE
),
37 fHandlerLock("handler lock")
43 SyslogDaemon::ReadyToRun()
45 fPort
= BLaunchRoster().GetPort("logger");
46 fDaemon
= spawn_thread(_DaemonThread
, "daemon", B_NORMAL_PRIORITY
, this);
48 if (fPort
>= 0 && fDaemon
>= 0) {
49 _kern_register_syslog_daemon(fPort
);
51 init_syslog_output(this);
52 init_listener_output(this);
54 resume_thread(fDaemon
);
61 SyslogDaemon::AboutRequested()
64 find_directory(B_SYSTEM_LOG_DIRECTORY
, &path
);
65 path
.Append("syslog");
67 BString
name(B_TRANSLATE("Syslog Daemon"));
69 snprintf(message
.LockBuffer(512), 512,
70 B_TRANSLATE("%s\n\nThis daemon is responsible for collecting "
71 "all system messages and write them to the system-wide log "
72 "at \"%s\".\n\n"), name
.String(), path
.Path());
73 message
.UnlockBuffer();
75 BAlert
* alert
= new BAlert(name
.String(), message
.String(),
77 BTextView
* view
= alert
->TextView();
80 view
->SetStylable(true);
84 font
.SetFace(B_BOLD_FACE
);
85 view
->SetFontAndColor(0, name
.Length(), &font
);
87 alert
->SetFlags(alert
->Flags() | B_CLOSE_ON_ESCAPE
);
93 SyslogDaemon::QuitRequested()
95 write_port(fPort
, kQuitDaemon
, NULL
, 0);
96 wait_for_thread(fDaemon
, NULL
);
103 SyslogDaemon::MessageReceived(BMessage
* message
)
105 switch (message
->what
) {
106 case SYSLOG_ADD_LISTENER
:
108 BMessenger messenger
;
109 if (message
->FindMessenger("target", &messenger
) == B_OK
)
110 add_listener(&messenger
);
113 case SYSLOG_REMOVE_LISTENER
:
115 BMessenger messenger
;
116 if (message
->FindMessenger("target", &messenger
) == B_OK
)
117 remove_listener(&messenger
);
122 BApplication::MessageReceived(message
);
128 SyslogDaemon::AddHandler(handler_func function
)
130 fHandlers
.AddItem((void*)function
);
135 SyslogDaemon::_Daemon()
137 char buffer
[SYSLOG_MESSAGE_BUFFER_SIZE
+ 1];
138 syslog_message
& message
= *(syslog_message
*)buffer
;
142 ssize_t bytesRead
= read_port(fPort
, &code
, &message
, sizeof(buffer
));
143 if (bytesRead
== B_BAD_PORT_ID
) {
148 if (code
== kQuitDaemon
)
151 // if we don't get what we want, ignore it
152 if (bytesRead
< (ssize_t
)sizeof(syslog_message
)
153 || code
!= SYSLOG_MESSAGE
)
156 // add terminating null byte
157 message
.message
[bytesRead
- sizeof(syslog_message
)] = '\0';
159 if (!message
.message
[0]) {
160 // ignore empty messages
166 for (int32 i
= fHandlers
.CountItems(); i
-- > 0;) {
167 handler_func handle
= (handler_func
)fHandlers
.ItemAt(i
);
172 fHandlerLock
.Unlock();
178 SyslogDaemon::_DaemonThread(void* data
)
180 ((SyslogDaemon
*)data
)->_Daemon();
189 main(int argc
, char** argv
)