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