source: trunk/src/sh_err_console.c@ 370

Last change on this file since 370 was 362, checked in by katerina, 13 years ago

Fix for ticket #267 (Multiple compiler warnings with gcc 4.6.1).

File size: 9.5 KB
Line 
1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 2000 Rainer Wichmann */
3/* */
4/* This program is free software; you can redistribute it */
5/* and/or modify */
6/* it under the terms of the GNU General Public License as */
7/* published by */
8/* the Free Software Foundation; either version 2 of the License, or */
9/* (at your option) any later version. */
10/* */
11/* This program is distributed in the hope that it will be useful, */
12/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14/* GNU General Public License for more details. */
15/* */
16/* You should have received a copy of the GNU General Public License */
17/* along with this program; if not, write to the Free Software */
18/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include "config_xor.h"
21
22#include <string.h>
23
24#include "samhain.h"
25#include "sh_error.h"
26#include "sh_utils.h"
27
28#undef FIL__
29#define FIL__ _("sh_err_console.c")
30
31#include <stdio.h>
32#include <sys/types.h>
33#include <fcntl.h>
34#include <unistd.h>
35#include <signal.h>
36
37extern int OnlyStderr;
38
39
40#if !defined(O_NONBLOCK)
41#if defined(O_NDELAY)
42#define O_NONBLOCK O_NDELAY
43#else
44#define O_NONBLOCK 0
45#endif
46#endif
47
48#if defined(WITH_MESSAGE_QUEUE)
49
50#if defined(HAVE_SYS_MSG_H)
51
52#include <sys/ipc.h>
53#include <sys/msg.h>
54
55struct sh_msgbuf {
56 long mtype;
57 char mtext[1]; /* <-- sizeof(mtext) will be 1+MY_MAX_MSG */
58};
59
60static int msgq_enabled = S_FALSE;
61
62/* The identifier of the message queue
63 */
64static int msgid = -1;
65
66/* Open the SysV message queue, creating it when neccesary
67 */
68static int open_ipc(void)
69{
70 key_t key;
71#if defined(WITH_TPT)
72 int error = 0;
73 char errbuf[SH_ERRBUF_SIZE];
74#endif
75
76 SL_ENTER(_("open_ipc"));
77
78 /* get key
79 */
80 key = ftok ("/tmp", '#');
81 if (key == (key_t) -1)
82 {
83#if defined(WITH_TPT)
84 error = errno;
85#endif
86 TPT(( 0, FIL__, __LINE__, _("msg=<ftok: %s> errno=<%d>\n"),
87 sh_error_message(error, errbuf, sizeof(errbuf)), error));
88 SL_RETURN(-1, _("open_ipc"));
89 }
90
91 /* get message identifier
92 */
93 msgid = msgget (key, IPC_CREAT|MESSAGE_QUEUE_MODE);
94
95 if (msgid < 0)
96 {
97#if defined(WITH_TPT)
98 error = errno;
99#endif
100 TPT(( 0, FIL__, __LINE__, _("msg=<msgget: %s> errno=<%d>\n"),
101 sh_error_message(error, errbuf, sizeof(errbuf)), error));
102 SL_RETURN(-1, _("open_ipc"));
103 }
104
105 SL_RETURN(0, _("open_ipc"));
106}
107
108/* Close the SysV message queue
109 */
110void close_ipc (void)
111{
112 SL_ENTER(_("close_ipc"));
113
114 if (msgid != (-1))
115 (void) msgctl (msgid, IPC_RMID, NULL);
116 SL_RET0(_("close_ipc"));
117}
118
119/* Enable the message queue
120 */
121int enable_msgq(const char * foo)
122{
123 int i;
124
125 SL_ENTER(_("enable_msgq"));
126 i = sh_util_flagval(foo, &msgq_enabled);
127 SL_RETURN(i, _("enable_msgq"));
128}
129
130/* #define MY_MAX_MSG 254 */
131#define MY_MAX_MSG 1022
132
133static int push_message_queue (const char * msg)
134{
135 struct sh_msgbuf* recv_msg = NULL;
136 int rc = -1;
137 static int status = -1;
138 int count = 0;
139#if defined(WITH_TPT)
140 int error = 0;
141 char errbuf[SH_ERRBUF_SIZE];
142#endif
143
144 SL_ENTER(_("push_message_queue"));
145
146 if (msgq_enabled == -1)
147 {
148 TPT(( 0, FIL__, __LINE__, _("msg=<msg_queue not enabled>\n")));
149 SL_RETURN(0, _("push_message_queue"));
150 }
151
152 if (status < 0)
153 {
154 TPT(( 0, FIL__, __LINE__, _("msg=<msg_queue not open>\n")));
155 status = open_ipc();
156 }
157
158 if (status < 0)
159 {
160 TPT(( 0, FIL__, __LINE__, _("msg=<open_ipc() failed>\n")));
161 SL_RETURN(-1, _("push_message_queue"));
162 }
163
164 /* struct msgbuf {
165 * long mtype;
166 * char mtext[1]; <-- sizeof(mtext) will be 1+MY_MAX_MSG
167 * }
168 */
169 recv_msg = (struct sh_msgbuf*) SH_ALLOC(sizeof(struct sh_msgbuf)+MY_MAX_MSG);
170 recv_msg->mtype = 1;
171 sl_strlcpy (recv_msg->mtext, msg, MY_MAX_MSG+1);
172
173 count = 0;
174
175 send_it:
176
177 if (count > 1)
178 {
179 SH_FREE(recv_msg);
180 SL_RETURN(-1, _("push_message_queue"));
181 }
182
183 /* send the message
184 */
185 do {
186 errno = 0;
187 rc = msgsnd(msgid, recv_msg, strlen(recv_msg->mtext)+1, IPC_NOWAIT);
188 }
189 while (rc < 0 && errno == EINTR);
190
191 if (rc == -1 && errno != EAGAIN)
192 {
193 /* EIDRM is not in OpenBSD
194 */
195 if (errno == EINVAL
196#if defined(EIDRM)
197 || errno == EIDRM
198#endif
199 )
200 {
201 TPT(( 0, FIL__, __LINE__, _("msg=<msg_queue not open>\n")));
202 status = open_ipc();
203 if (status == 0)
204 {
205 ++count;
206 goto send_it;
207 }
208 }
209 else
210 {
211#if defined(WITH_TPT)
212 error = errno;
213#endif
214 TPT(( 0, FIL__, __LINE__, _("msg=<msgsnd: %s> errno=<%d>\n"),
215 sh_error_message(error, errbuf, sizeof(errbuf)), error));
216 SH_FREE(recv_msg);
217 SL_RETURN(-1, _("push_message_queue"));
218 }
219 }
220
221 SH_FREE(recv_msg);
222 SL_RETURN(0, _("push_message_queue"));
223}
224/* if defined(HAVE_SYS_MSG_H) */
225#else
226
227#error **********************************************
228#error
229#error The sys/msg.h header was not found,
230#error cannot compile with --enable-message-queue
231#error
232#error **********************************************
233
234#endif
235
236#endif
237
238static int count_dev_console = 0;
239
240void reset_count_dev_console(void)
241{
242 count_dev_console = 0;
243 return;
244}
245
246/* ---- Set the console device. ----
247 */
248int sh_log_set_console (const char * address)
249{
250 SL_ENTER(_("sh_log_set_console"));
251 if (address != NULL && count_dev_console < 2
252 && sl_strlen(address) < SH_PATHBUF)
253 {
254 if (count_dev_console == 0)
255 (void) sl_strlcpy (sh.srvcons.name, address, SH_PATHBUF);
256 else
257 (void) sl_strlcpy (sh.srvcons.alt, address, SH_PATHBUF);
258
259 ++count_dev_console;
260 SL_RETURN(0, _("sh_log_set_console"));
261 }
262 SL_RETURN((-1), _("sh_log_set_console"));
263}
264
265#if defined(WITH_TRACE) || defined(WITH_TPT)
266char * sh_log_console_name (void)
267{
268 if (! sh.srvcons.name || sh.srvcons.name[0] == '\0' ||
269 0 == strcmp(sh.srvcons.name, _("NULL")))
270 return (_("/dev/console"));
271 return sh.srvcons.name;
272}
273#endif
274
275#ifndef STDERR_FILENO
276#define STDERR_FILENO 2
277#endif
278
279/* ---- Print out a message. ----
280 */
281int sh_log_console (const /*@null@*/char *errmsg)
282{
283 static int service_failure[2] = { 0, 0};
284 int fd[2] = { -1, -1};
285 int sflags;
286 int cc;
287 size_t len;
288 int ccMax = 1;
289 int retval = -1;
290 /* static int logkey_seen = 0; */
291 int error;
292 struct sigaction sa_new, sa_old;
293 static int blockMe = 0;
294 int val_return;
295
296 SL_ENTER(_("sh_log_console"));
297
298 if (errmsg == NULL || blockMe == 1)
299 {
300 SL_RETURN(0, _("sh_log_console"));
301 }
302 else
303 blockMe = 1;
304
305
306#ifdef WITH_MESSAGE_QUEUE
307 if (0 != push_message_queue (errmsg))
308 {
309 TPT(( 0, FIL__, __LINE__, _("msg=<push_message_queue() failed>\n")));
310 }
311#endif
312
313 sa_new.sa_handler = SIG_IGN;
314 (void) sigemptyset(&sa_new.sa_mask);
315 sa_new.sa_flags = 0;
316
317 /* Ignore SIGPIPE in case the console is actually a pipe.
318 */
319 (void) retry_sigaction(FIL__, __LINE__, SIGPIPE, &sa_new, &sa_old);
320
321 if (sh.flag.isdaemon == S_FALSE || OnlyStderr == S_TRUE)
322 {
323 len = strlen(errmsg);
324 do {
325 val_return = write(STDERR_FILENO, errmsg, len);
326 } while (val_return < 0 && errno == EINTR);
327 do {
328 val_return = write(STDERR_FILENO, "\n", 1);
329 } while (val_return < 0 && errno == EINTR);
330 /*
331 * fprintf (stderr, "%s\n", errmsg);
332 */
333 (void) retry_sigaction(FIL__, __LINE__, SIGPIPE, &sa_old, NULL);
334 blockMe = 0;
335 SL_RETURN(0, _("sh_log_console"));
336 }
337
338 /* --- daemon && initialized ---
339 */
340 if ( (OnlyStderr == S_FALSE) )
341 {
342 fd[0] = open ( sh.srvcons.name, O_WRONLY|O_APPEND|O_NOCTTY|O_NONBLOCK);
343 if (fd[0] >= 0) {
344 sflags = (int) retry_fcntl(FIL__, __LINE__, fd[0], F_GETFL, 0);
345 if (sflags >= 0)
346 {
347 (void) retry_fcntl(FIL__, __LINE__, fd[0],
348 F_SETFL, sflags & ~O_NONBLOCK);
349 }
350 }
351
352 if (sh.srvcons.alt != NULL && sh.srvcons.alt[0] != '\0')
353 {
354 fd[1] = open (sh.srvcons.alt, O_WRONLY|O_APPEND|O_NOCTTY|O_NONBLOCK);
355 if (fd[1] >= 0) {
356 sflags = (int) retry_fcntl(FIL__, __LINE__, fd[1], F_GETFL, 0);
357 if (sflags >= 0)
358 {
359 (void) retry_fcntl(FIL__, __LINE__, fd[1],
360 F_SETFL, sflags & ~O_NONBLOCK);
361 }
362 ccMax = 2;
363 }
364 }
365
366 for (cc = 0; cc < ccMax; ++cc)
367 {
368
369 if (fd[cc] < 0 && service_failure[cc] == 0)
370 {
371 error = errno;
372 sh_error_handle ((-1), FIL__, __LINE__, error, MSG_SRV_FAIL,
373 _("console"),
374 (cc == 0) ? sh.srvcons.name : sh.srvcons.alt);
375 service_failure[cc] = 1;
376 }
377
378 if (fd[cc] >= 0)
379 {
380 do {
381 val_return = write(fd[cc], errmsg, strlen(errmsg));
382 } while (val_return < 0 && errno == EINTR);
383 do {
384 val_return = write(fd[cc], "\r\n", 2);
385 } while (val_return < 0 && errno == EINTR);
386 (void) sl_close_fd(FIL__, __LINE__, fd[cc]);
387 service_failure[cc] = 0;
388 }
389 }
390 }
391 else
392 retval = 0;
393
394 (void) retry_sigaction(FIL__, __LINE__, SIGPIPE, &sa_old, NULL);
395 blockMe = 0;
396 SL_RETURN(retval, _("sh_log_console"));
397}
398
399
Note: See TracBrowser for help on using the repository browser.