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