Removed odkUtils dependency from IPC code, we now use pcre-cpp for Regular Expresions
[fmail.git] / src / socketipc.cpp
blob36c18e876d9d7492c0cb98acf40caf076a001ca3
1 /*
2 libfmail: Socket Based IPC mechanism
4 Copyright (C) 2007 Carlos Daniel Ruvalcaba Valenzuela <clsdaniel@gmail.com>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
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.
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include <stdio.h>
22 #include <string.h>
23 #include <malloc.h>
25 #include <pcrecpp.h>
27 #include <queue>
29 #include <libfmail/socket.h>
30 #include <libfmail/ipcmsg.h>
31 #include <libfmail/ipc.h>
32 #include <libfmail/socketipc.h>
34 SocketIPC::SocketIPC(Socket *s){
35 sock = s;
38 SocketIPC::SocketIPC(char *uri){
39 char *str;
40 string shost;
41 string options;
42 pcrecpp::RE re("([\\w\\d\\.]+)\\:(\\d*)[/]*(\\w*)");
44 re.FullMatch(uri, &shost, &port, &options);
45 host = (char*)shost.c_str();
47 printf("Started socket on: %s\n", uri);
48 printf("Host: %s\nPort: %i\n", host, port);
49 sock = new Socket();
50 auxsock = NULL;
53 int SocketIPC::RequestIPC(){
54 return sock->Connect(host, port);
57 int SocketIPC::ListenIPC(){
58 sock->Bind(port);
59 sock->Listen(10);
61 auxsock = sock->Accept();
62 return 0;
65 int SocketIPC::CloseIPC(){
66 sock->Close();
67 if (auxsock)
68 auxsock->Close();
71 int SocketIPC::FetchMessage2(){
72 char buffer[255], xbuff[255], tbuff[20], *msgdata;
73 int state, onParse;
74 int i, t, r, mlen, margc;
75 IPCMessage *msg;
77 state = 0;
78 onParse = 1;
80 mlen = 0;
81 margc = 0;
82 msg = NULL;
84 if (auxsock == NULL)
85 auxsock = sock;
87 while (onParse){
89 memset(buffer, 0, 255);
90 r = auxsock->Read(buffer, 255);
92 if (r < 1){
93 return 0;
94 state = -1;
95 onParse = 0;
98 for (i = 0; i < r; i++){
99 switch (state){
100 case 0:
101 if (buffer[i] == 'M')
102 state++;
103 break;
104 case 1:
105 if (buffer[i] == 'S')
106 state++;
107 break;
108 case 2:
109 if (buffer[i] == 'G')
110 state++;
111 break;
112 case 3:
113 if (buffer[i] == '['){
114 state++;
115 memset(tbuff, 0, 20);
116 t = 0;
118 break;
119 case 4:
120 if ((buffer[i] >= 48) && (buffer[i] <= 57)){
121 tbuff[t] = buffer[i];
122 t++;
123 if (t == 20)
124 state = -1;
125 }else{
126 mlen = atoi(tbuff);
127 state++;
129 break;
130 case 5:
131 if (buffer[i] == '['){
132 state++;
133 memset(tbuff, 0, 20);
134 t = 0;
136 break;
137 case 6:
138 if ((buffer[i] >= 48) && (buffer[i] <= 57)){
139 tbuff[t] = buffer[i];
140 t++;
141 if (t == 20)
142 state = -1;
143 }else{
144 margc = atoi(tbuff);
145 state++;
146 if (mlen < 255){
147 msgdata = xbuff;
148 }else{
149 msgdata = (char*)malloc(sizeof(char) * mlen + 1);
151 t = 0;
153 break;
154 case 7:
155 if (t < mlen){
156 msgdata[t] = buffer[i];
157 t++;
158 if (t == mlen){
159 msgdata[t] = 0;
160 state++;
163 break;
164 case 8:
165 msg = new IPCMessage(msgdata);
166 if (msgdata != xbuff)
167 free(msgdata);
168 state++;
170 if (margc == 0)
171 state = 20;
172 i--;
173 break;
174 case 9:
175 if (buffer[i] == 'P')
176 state++;
177 break;
178 case 10:
179 if (buffer[i] == 'A')
180 state++;
181 break;
182 case 11:
183 if (buffer[i] == 'R')
184 state++;
185 break;
186 case 12:
187 if (buffer[i] == 'A')
188 state++;
189 break;
190 case 13:
191 if (buffer[i] == 'M')
192 state++;
193 break;
194 case 14:
195 if (buffer[i] == '['){
196 state++;
197 memset(tbuff, 0, 20);
198 t = 0;
200 break;
201 case 15:
202 if ((buffer[i] >= 48) && (buffer[i] <= 57)){
203 tbuff[t] = buffer[i];
204 t++;
205 if (t == 20)
206 state = -1;
207 }else{
208 mlen = atoi(tbuff);
209 state++;
211 break;
212 case 16:
213 if (mlen < 255){
214 msgdata = xbuff;
215 }else{
216 msgdata = (char*)malloc(sizeof(char) * mlen + 1);
218 t = 0;
219 state++;
220 i--;
221 break;
222 case 17:
223 if (t < mlen){
224 msgdata[t] = buffer[i];
225 t++;
226 if (t == mlen){
227 msgdata[t] = 0;
228 state++;
229 i--;
232 break;
233 case 18:
234 msg->PushParam(msgdata);
235 if (msgdata != xbuff)
236 free(msgdata);
237 if (msg->ParamCount() == margc){
238 state++;
239 }else{
240 state = 9;
242 onParse = 0;
243 break;
244 default:
245 onParse = 0;
246 break;
251 if (state == -1){
252 if (msg)
253 delete msg;
254 return 0;
257 msgQueue.push(msg);
258 return 1;
262 int FetchMessage(){
263 char buffer[255], *param;
264 int i, j, k, s, r;
265 IPCMessage *msg;
267 memset(buffer, 0, 255);
268 r = auxsock->Read(buffer, 255);
270 if (r < 3)
271 return 0;
273 printf("buffer: %s\n", buffer);
274 m = odk_regex_match(re, buffer, 0);
276 if (m == NULL)
277 return 0;
278 printf("Regex Matched!!\n");
279 if (buffer[0] != 'M')
280 return 0;
282 param = odk_submatch_copy(buffer, m, 1);
283 i = atoi(param);
284 free(param);
286 param = odk_submatch_copy(buffer, m, 2);
287 j = atoi(param);
288 free(param);
290 memset(buffer, 0, 255);
291 r = auxsock->Read(buffer, 255);
293 if (r != i)
294 return 0;
296 msg = new IPCMessage(buffer);
297 for (i = 0; i < j; i++){
298 auxsock->Read(buffer, 255);
299 m = odk_regex_match(re, buffer, 0);
301 if ((m == NULL) || (buffer[0] != 'P'))
302 return 0;
303 param = odk_submatch_copy(buffer, m, 1);
304 k = atoi(param);
305 free(param);
307 if ((k < 1) || (k > 32000))
308 return 0;
310 param = (char*)malloc(sizeof(char) * k+1);
312 memset(param, 0, k+1);
313 s = 0;
315 while (s < k){
316 r = auxsock->Read(buffer, 255);
317 memcpy((char*)((int)param+s), buffer, r);
318 s += r;
320 msg->PushParam(param);
323 msgQueue.push(msg);
324 return 1;
328 int SocketIPC::PeekMessage(){
330 if(FetchMessage2())
331 return 1;
333 if (msgQueue.size() > 0)
334 return 1;
336 return 0;
339 int SocketIPC::PushMessage(IPCMessage *msg){
340 char *tmp, buffer[50];
341 int l, blen;
343 tmp = msg->GetMessageName();
344 l = strlen(tmp);
346 sprintf(buffer, "MSG[%i][%i]", l, msg->ParamCount());
347 blen = strlen(buffer);
349 sock->Write(buffer, blen);
350 sock->Write(tmp, l);
352 while(tmp = msg->PopParam()){
353 l = strlen(tmp);
355 sprintf(buffer, "PARAM[%i]", l);
356 blen = strlen(buffer);
358 sock->Write(buffer, blen);
359 sock->Write(tmp, l);
361 free(tmp);
364 return 1;
367 IPCMessage *SocketIPC::PopMessage(){
368 IPCMessage *msg;
370 msg = msgQueue.front();
371 msgQueue.pop();
373 return msg;
376 int SocketIPC::RawRead(char *buff, int size){
377 return sock->Read(buff, size);
380 int SocketIPC::RawWrite(char *buff, int size){
381 return sock->Write(buff, size);