81c27721cf15749d6f5430e45fcf45b6ef179a0c
[ossec-hids.git] / src / shared / mq_op.c
1 /* @(#) $Id$ */
2
3 /* Copyright (C) 2009 Trend Micro Inc.
4  * All rights reserved.
5  *
6  * This program is a free software; you can redistribute it
7  * and/or modify it under the terms of the GNU General Public
8  * License (version 2) as published by the FSF - Free Software
9  * Foundation
10  */
11
12
13 #include "shared.h"
14 #include "os_net/os_net.h"
15
16
17 #ifndef WIN32
18
19 /* StartMQ v0.2, 2004/07/30
20  * Start the Message Queue. type: WRITE||READ
21  */
22 int StartMQ(char * path, short int type)
23 {
24     
25     if(type == READ)
26     {
27         return(OS_BindUnixDomain(path, 0660, OS_MAXSTR + 512));
28     }
29     
30     /* We give up to 21 seconds for the other end to
31      * start
32      */
33     else
34     {
35         int rc = 0;
36         if(File_DateofChange(path) < 0)
37         {
38             sleep(1);
39             if(File_DateofChange(path) < 0)
40             {
41                 sleep(5);
42                 if(File_DateofChange(path) < 0)
43                 {
44                     merror(QUEUE_ERROR, __local_name, path, "Queue not found");
45                     sleep(15);
46                     if(File_DateofChange(path) < 0)
47                     {
48                         return(-1);
49                     }
50                 }
51             }
52         }
53
54         /* Wait up to 3 seconds to connect to the unix domain.
55          * After three errors, exit.
56          */
57         if((rc = OS_ConnectUnixDomain(path, OS_MAXSTR + 256)) < 0)
58         {
59             sleep(1);
60             if((rc = OS_ConnectUnixDomain(path, OS_MAXSTR + 256)) < 0)
61             {
62                 sleep(2);
63                 if((rc = OS_ConnectUnixDomain(path, OS_MAXSTR + 256)) < 0)
64                 {
65                     merror(QUEUE_ERROR, __local_name, path, 
66                            strerror(errno));
67                     return(-1);
68                 }
69             }
70         }
71
72         debug1(MSG_SOCKET_SIZE, __local_name, OS_getsocketsize(rc));
73         return(rc);
74     }
75 }
76
77
78 /* SendMSG v0.1, 2005/02/15
79  * Send a message to the queue.
80  */
81 int SendMSG(int queue, char *message, char *locmsg, char loc)
82 {
83     int __mq_rcode;
84     char tmpstr[OS_MAXSTR+1];
85
86     tmpstr[OS_MAXSTR] = '\0';
87
88
89     /* Checking for global locks */
90     os_wait();
91     
92     
93     if(loc == SECURE_MQ)
94     {
95         loc = message[0];
96         message++;
97
98         if(message[0] != ':')
99         {
100             merror(FORMAT_ERROR, __local_name);
101             return(0);
102         }
103         
104         message++; /* Pointing now to the location */
105         
106         snprintf(tmpstr,OS_MAXSTR,"%c:%s->%s",loc, locmsg, message);
107     }
108     else
109         snprintf(tmpstr,OS_MAXSTR,"%c:%s:%s",loc,locmsg,message);
110
111
112     /* queue not available */
113     if(queue < 0)
114         return(-1);
115
116         
117     /* We attempt 5 times to send the message if
118      * the receiver socket is busy.
119      * After the first error, we wait 1 second.
120      * After the second error, we wait more 3 seconds.
121      * After the third error, we wait 5 seconds.
122      * After the fourth error, we wait 10 seconds.
123      * If we failed again, the message is not going
124      * to be delivered and an error is sent back.
125      */
126     if((__mq_rcode = OS_SendUnix(queue, tmpstr,0)) < 0)
127     {
128         /* Error on the socket */
129         if(__mq_rcode == OS_SOCKTERR)
130         {
131             merror("%s: socketerr (not available).", __local_name);
132             close(queue);
133             queue = -1;
134             return(-1);
135         }
136
137         
138         /* Unable to send. Socket busy */
139         sleep(1);
140         if(OS_SendUnix(queue, tmpstr, 0) < 0)
141         {
142             /* When the socket is to busy, we may get some
143              * error here. Just sleep 2 second and try
144              * again.
145              */
146             sleep(3);
147             /* merror("%s: socket busy", __local_name); */
148             if(OS_SendUnix(queue, tmpstr,0) < 0)
149             {
150                 sleep(5);
151                 merror("%s: socket busy ..", __local_name);
152                 if(OS_SendUnix(queue, tmpstr,0) < 0)
153                 {
154                     sleep(10);
155                     merror("%s: socket busy ..", __local_name);
156                     if(OS_SendUnix(queue, tmpstr,0) < 0)
157                     {
158                         /* Message is going to be lost
159                          * if the application does not care
160                          * about checking the error 
161                          */ 
162                         close(queue);
163                         queue = -1; 
164                         return(-1);
165                     }
166                 }
167             }
168         }
169     }
170
171     return(0);
172 }
173
174 #endif
175
176 /* EOF */