svn update: 48958 (latest:48959)
[framework/uifw/ecore.git] / src / lib / ecore_config / ecore_config_ipc_ecore.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #ifdef HAVE_CONFIG_H
6 # include <config.h>
7 #endif
8
9 /* by Azundris, with thanks to Corey Donohoe <atmos@atmos.org> */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <limits.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <unistd.h>
18 #include <ctype.h>
19
20 #include <Ecore.h>
21 #include "ecore_private.h"
22 #include <Ecore_Ipc.h>
23
24 #include "ecore_config_ipc.h"
25 #include "ecore_config_util.h"
26 #include "ecore_config_private.h"
27
28 #include "Ecore_Config.h"
29
30
31 /*****************************************************************************/
32
33 static int
34 _ecore_config_ipc_ecore_string_get(char **m, char **r)
35 {
36    char               *q;
37    int                 l = 0;
38
39    if (!m || !*m)
40       return ECORE_CONFIG_ERR_NODATA;
41    if (!r)
42       return ECORE_CONFIG_ERR_FAIL;
43    q = *m;
44    if (*q != 's')
45       return ECORE_CONFIG_ERR_TYPEMISMATCH;
46    q++;
47    l = (*(q++)) << 8;
48    l += *(q++);
49    *r = q;
50    q += l;
51    *m = q;
52    WRN("IPC/eCore: got string-%d \"%s\"", l, *r);
53    return ECORE_CONFIG_ERR_SUCC;
54 }
55
56 static char               *
57 _ecore_config_ipc_global_prop_list(Ecore_Config_Server * srv __UNUSED__, long serial __UNUSED__)
58 {
59    Ecore_Config_DB_File  *db;
60    char                 **keys;
61    int                    key_count, x;
62    estring               *s;
63    int                    f;
64    char                   buf[PATH_MAX], *p;    
65    // char              *data;                  UNUSED
66    Ecore_Config_Type      type;
67
68    db = NULL;
69    s = estring_new(8192);
70    f = 0;
71    if ((p = getenv("HOME")))
72      {
73         snprintf(buf, sizeof(buf), "%s/.e/config.eet", p);
74         if (!(db = _ecore_config_db_open_read(buf)))
75           {
76              strcpy(buf, PACKAGE_DATA_DIR"/system.eet");
77              if (!(db = _ecore_config_db_open_read(buf)))
78                return NULL;
79           }
80      }
81    if (!db) return NULL;
82    key_count = 0;
83    keys = _ecore_config_db_keys_get(db, &key_count);
84    if (keys)
85      {
86         for (x = 0; x < key_count; x++)
87           {
88              type = _ecore_config_db_key_type_get(db, keys[x]);
89              switch (type)
90                {
91                   case ECORE_CONFIG_INT:
92                     estring_appendf(s, "%s%s: integer", f ? "\n" : "", keys[x]);
93                     break;
94                   case ECORE_CONFIG_BLN:
95                     estring_appendf(s, "%s%s: boolean", f ? "\n" : "", keys[x]);
96                     break;
97                   case ECORE_CONFIG_FLT:
98                     estring_appendf(s, "%s%s: float", f ? "\n" : "", keys[x]);
99                     break;
100                   case ECORE_CONFIG_STR:
101                     estring_appendf(s, "%s%s: string", f ? "\n" : "", keys[x]);
102                     break;
103                   case ECORE_CONFIG_RGB:
104                     estring_appendf(s, "%s%s: colour", f ? "\n" : "", keys[x]);
105                     break;
106                   case ECORE_CONFIG_THM:
107                     estring_appendf(s, "%s%s: theme", f ? "\n" : "", keys[x]);
108                     break;
109                   case ECORE_CONFIG_SCT:
110                     estring_appendf(s, "%s%s: structure", f ? "\n" : "", keys[x]);
111                     break;
112                   default:
113                     estring_appendf(s, "%s%s: unknown", f ? "\n" : "", keys[x]);
114                     continue;
115                }
116              f = 1;
117           }
118      }
119    _ecore_config_db_close(db);
120    if (keys)
121      {
122         for (x = 0; x < key_count; x++)
123           {
124              free(keys[x]);
125           }
126         free(keys);
127      }
128    
129    return estring_disown(s);
130 }
131
132 /*****************************************************************************/
133
134 static int
135 _ecore_config_ipc_ecore_send(Ecore_Ipc_Event_Client_Data * e, int code,
136                              char *reply)
137 {
138    static int          our_ref = 0;
139    int                 len = reply ? strlen(reply) + 1 : 0;
140
141    our_ref++;
142    WRN("IPC/eCore: replying [0,0] %d IRT %d => %d {\"%s\":%d}", our_ref,
143      e->ref, code, reply ? reply : "", len);
144    return ecore_ipc_client_send(e->client, 0, 0, our_ref, e->ref, code, reply,
145                                 len);
146 }
147
148 /*****************************************************************************/
149
150 static int
151 _ecore_config_ipc_ecore_handle_request(Ecore_Ipc_Server * server,
152                                        Ecore_Ipc_Event_Client_Data * e)
153 {
154    Ecore_Config_Server *srv;
155    long                serial;
156    int                 ret;
157    char               *r, *k, *v, *m;
158
159    srv = _ecore_config_server_convert(server);
160    serial = e->minor;
161    r = NULL;
162    m = (char *)e->data;
163    INF("IPC/eCore: client sent: [%d,%d] #%d (%d) @ %p", e->major, e->minor,
164      e->ref, e->size, server);
165
166    switch (e->major)
167      {
168      case IPC_PROP_LIST:
169         if (srv == __ecore_config_server_global)
170            r = _ecore_config_ipc_global_prop_list(srv, serial);
171         else
172            r = _ecore_config_ipc_prop_list(srv, serial);
173         break;
174      case IPC_PROP_DESC:
175         if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
176            r = _ecore_config_ipc_prop_desc(srv, serial, k);
177         break;
178      case IPC_PROP_GET:
179         if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
180            r = _ecore_config_ipc_prop_get(srv, serial, k);
181         break;
182      case IPC_PROP_SET:
183         if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
184           {
185              if (_ecore_config_ipc_ecore_string_get(&m, &v) ==
186                  ECORE_CONFIG_ERR_SUCC)
187                 return _ecore_config_ipc_ecore_send(e,
188                                                     _ecore_config_ipc_prop_set
189                                                     (srv, serial, k, v), NULL);
190           }
191         break;
192
193      case IPC_BUNDLE_LIST:
194         r = _ecore_config_ipc_bundle_list(srv);
195         break;
196      case IPC_BUNDLE_NEW:
197         if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
198            return _ecore_config_ipc_ecore_send(e,
199                                                k ?
200                                                _ecore_config_ipc_bundle_new(srv,
201                                                                             k) :
202                                                ECORE_CONFIG_ERR_FAIL, NULL);
203         break;
204      case IPC_BUNDLE_LABEL_SET:
205         if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
206            return _ecore_config_ipc_ecore_send(e,
207                                                k ?
208                                                _ecore_config_ipc_bundle_label_set
209                                                (srv, serial,
210                                                 k) : ECORE_CONFIG_ERR_FAIL,
211                                                NULL);
212         break;
213      case IPC_BUNDLE_LABEL_FIND:
214         if (_ecore_config_ipc_ecore_string_get(&m, &k) == ECORE_CONFIG_ERR_SUCC)
215            return _ecore_config_ipc_ecore_send(e,
216                                                _ecore_config_ipc_bundle_label_find
217                                                (srv, k), NULL);
218         break;
219      case IPC_BUNDLE_LABEL_GET:
220         r = _ecore_config_ipc_bundle_label_get(srv, serial);
221         break;
222      }
223
224    ret =
225       _ecore_config_ipc_ecore_send(e,
226                                    r ? ECORE_CONFIG_ERR_SUCC :
227                                    ECORE_CONFIG_ERR_FAIL, r);
228    if (r)
229      {
230         free(r);
231         return ret;
232      }
233    return ECORE_CONFIG_ERR_NOTFOUND;
234 }
235
236 /*****************************************************************************/
237
238 static int
239 _ecore_config_ipc_client_add(void *data, int type __UNUSED__, void *event)
240 {
241    Ecore_Ipc_Server  **server;
242    Ecore_Ipc_Event_Client_Data *e;
243
244    server = (Ecore_Ipc_Server **) data;
245    e = (Ecore_Ipc_Event_Client_Data *) event;
246
247    if (*server != ecore_ipc_client_server_get(e->client))
248       return 1;
249
250    INF("IPC/eCore: Client connected. @ %p", server);
251    return 1;
252 }
253
254 static int
255 _ecore_config_ipc_client_del(void *data, int type __UNUSED__, void *event)
256 {
257    Ecore_Ipc_Server  **server;
258    Ecore_Ipc_Event_Client_Data *e;
259
260    server = (Ecore_Ipc_Server **) data;
261    e = (Ecore_Ipc_Event_Client_Data *) event;
262
263    if (*server != ecore_ipc_client_server_get(e->client))
264       return 1;
265
266    INF("IPC/eCore: Client disconnected. @ %p", server);
267    return 1;
268 }
269
270 static int
271 _ecore_config_ipc_client_sent(void *data, int type __UNUSED__, void *event)
272 {
273    Ecore_Ipc_Server  **server;
274    Ecore_Ipc_Event_Client_Data *e;
275
276    server = (Ecore_Ipc_Server **) data;
277    e = (Ecore_Ipc_Event_Client_Data *) event;
278
279    if (*server != ecore_ipc_client_server_get(e->client))
280       return 1;
281
282    _ecore_config_ipc_ecore_handle_request(*server, e);
283    return 1;
284 }
285
286 /*****************************************************************************/
287
288 int
289 _ecore_config_ipc_ecore_init(const char *pipe_name, void **data)
290 {
291    Ecore_Ipc_Server  **server;
292    struct stat         st;
293    char               *p;
294    int                 port;
295    char                socket[PATH_MAX];
296
297    server = (Ecore_Ipc_Server **) data;
298    port = 0;
299    if (!server)
300       return ECORE_CONFIG_ERR_FAIL;
301
302 /*  if(*server)
303       return ECORE_CONFIG_ERR_IGNORED; */
304
305    ecore_init();
306    if (ecore_ipc_init() < 1)
307       return ECORE_CONFIG_ERR_FAIL;
308
309    if ((p = getenv("HOME")))
310      {                          /* debug-only ### FIXME */
311         int                 stale;
312
313         stale = 1;
314         while (stale)
315           {
316              snprintf(socket, PATH_MAX, "%s/.ecore/%s/%d", p, pipe_name, port);
317
318              if (!stat(socket, &st))
319                {
320                   INF("IPC/eCore: pipe \"%s\" already exists!?", socket);
321 /*      if(unlink(buf))
322         E(0,"IPC/eCore: could not remove pipe \"%s\": %d\n",buf,errno); }}*/
323                   port++;
324                }
325              else
326                {
327                   stale = 0;
328                }
329           }
330      }
331    *server = ecore_ipc_server_add(ECORE_IPC_LOCAL_USER, pipe_name, port, NULL);
332    ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD,
333                            _ecore_config_ipc_client_add, server);
334    ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL,
335                            _ecore_config_ipc_client_del, server);
336    ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA,
337                            _ecore_config_ipc_client_sent, server);
338
339    if (server)
340      {
341         INF("IPC/eCore: Server is listening on %s.", pipe_name);
342      }
343
344    return ECORE_CONFIG_ERR_SUCC;
345 }
346
347 int
348 _ecore_config_ipc_ecore_exit(void **data)
349 {
350    int                 ret;
351    Ecore_Ipc_Server  **server;
352
353    ret = ECORE_CONFIG_ERR_SUCC;
354    server = (Ecore_Ipc_Server **) data;
355
356    if (!server)
357       return ECORE_CONFIG_ERR_FAIL;
358
359    if (*server)
360      {
361         ecore_ipc_server_del(*server);
362         *server = NULL;
363      }
364
365    ecore_ipc_shutdown();
366    ecore_shutdown();
367
368    return ret;
369 }
370
371 /*****************************************************************************/
372
373 int
374 _ecore_config_ipc_ecore_poll(void **data)
375 {
376    Ecore_Ipc_Server  **server;
377
378    server = (Ecore_Ipc_Server **) data;
379
380    if (!server)
381       return ECORE_CONFIG_ERR_FAIL;
382
383    ecore_main_loop_iterate();
384
385    return ECORE_CONFIG_ERR_SUCC;
386 }
387
388 /*****************************************************************************/