1 /* 2 ** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 ** Distributed under the terms of the OpenBeOS License. 4 */ 5 6 7 #include "SyslogDaemon.h" 8 #include "listener_output.h" 9 #include "syslog_output.h" 10 11 #include <Alert.h> 12 #include <TextView.h> 13 #include <Font.h> 14 #include <FindDirectory.h> 15 #include <Path.h> 16 17 #include <stdio.h> 18 #include <string.h> 19 20 21 const char *kSignature = "application/x-vnd.Be-SYSL"; 22 23 24 SyslogDaemon::SyslogDaemon() 25 : BApplication(kSignature), 26 fHandlerLock("handler lock") 27 { 28 } 29 30 31 void 32 SyslogDaemon::ReadyToRun() 33 { 34 fPort = create_port(256, SYSLOG_PORT_NAME); 35 fDaemon = spawn_thread(daemon_thread, "daemon", B_NORMAL_PRIORITY, this); 36 resume_thread(fDaemon); 37 38 if (fPort >= B_OK && fDaemon >= B_OK) { 39 init_syslog_output(this); 40 init_listener_output(this); 41 } else 42 Quit(); 43 } 44 45 46 void 47 SyslogDaemon::AboutRequested() 48 { 49 BPath path; 50 find_directory(B_COMMON_LOG_DIRECTORY, &path); 51 path.Append("syslog"); 52 53 char message[512]; 54 sprintf(message, 55 "Syslog Daemon\n\n" 56 "This daemon is responsible for collecting " 57 "all system messages and write them to the " 58 "system-wide log at \"%s\".\n\n", path.Path()); 59 60 BAlert *alert = new BAlert("Syslog Daemon", message, "Ok"); 61 BTextView *view = alert->TextView(); 62 BFont font; 63 64 view->SetStylable(true); 65 66 view->GetFont(&font); 67 font.SetSize(21); 68 font.SetFace(B_BOLD_FACE); 69 view->SetFontAndColor(0, 13, &font); 70 71 alert->Go(NULL); 72 } 73 74 75 bool 76 SyslogDaemon::QuitRequested() 77 { 78 delete_port(fPort); 79 80 int32 returnCode; 81 wait_for_thread(fDaemon, &returnCode); 82 83 return true; 84 } 85 86 87 void 88 SyslogDaemon::MessageReceived(BMessage *msg) 89 { 90 switch (msg->what) { 91 case SYSLOG_ADD_LISTENER: 92 { 93 BMessenger messenger; 94 if (msg->FindMessenger("target", &messenger) == B_OK) 95 add_listener(&messenger); 96 break; 97 } 98 case SYSLOG_REMOVE_LISTENER: 99 { 100 BMessenger messenger; 101 if (msg->FindMessenger("target", &messenger) == B_OK) 102 remove_listener(&messenger); 103 break; 104 } 105 106 default: 107 BApplication::MessageReceived(msg); 108 } 109 } 110 111 112 void 113 SyslogDaemon::AddHandler(handler_func function) 114 { 115 fHandlers.AddItem((void *)function); 116 } 117 118 119 void 120 SyslogDaemon::Daemon() 121 { 122 char buffer[4096]; 123 syslog_message &message = *(syslog_message *)buffer; 124 int32 code; 125 126 while (true) { 127 ssize_t bytesRead = read_port(fPort, &code, &message, sizeof(buffer)); 128 if (bytesRead == B_BAD_PORT_ID) { 129 // we've been quit 130 break; 131 } 132 133 // if we don't get what we want, ignore it 134 if (bytesRead < (ssize_t)sizeof(syslog_message) || code != SYSLOG_MESSAGE) 135 continue; 136 137 fHandlerLock.Lock(); 138 139 for (int32 i = fHandlers.CountItems(); i-- > 0;) { 140 handler_func handle = (handler_func)fHandlers.ItemAt(i); 141 142 handle(message); 143 } 144 145 fHandlerLock.Unlock(); 146 } 147 } 148 149 150 int32 151 SyslogDaemon::daemon_thread(void *data) 152 { 153 ((SyslogDaemon *)data)->Daemon(); 154 return B_OK; 155 } 156 157 158 int 159 main(int argc, char **argv) 160 { 161 SyslogDaemon daemon; 162 daemon.Run(); 163 164 return 0; 165 } 166