31280b68bc01b1bc59447d1d317f0d38a95d8670
[framework/uifw/e17.git] / src / bin / e_ipc.c
1 #include "e.h"
2
3 #ifdef USE_IPC
4 /* local subsystem functions */
5 static Eina_Bool _e_ipc_cb_client_add(void *data __UNUSED__, int type __UNUSED__, void *event);
6 static Eina_Bool _e_ipc_cb_client_del(void *data __UNUSED__, int type __UNUSED__, void *event);
7 static Eina_Bool _e_ipc_cb_client_data(void *data __UNUSED__, int type __UNUSED__, void *event);
8
9 /* local subsystem globals */
10 static Ecore_Ipc_Server *_e_ipc_server = NULL;
11 #endif
12
13 /* externally accessible functions */
14 EINTERN int
15 e_ipc_init(void)
16 {
17 #ifdef USE_IPC
18    char buf[1024];
19    char *tmp, *user, *disp;
20    int pid;
21
22    tmp = getenv("TMPDIR");
23    if (!tmp) tmp = "/tmp";
24    user = getenv("USER");
25    if (!user) user = "__unknown__";
26    disp = getenv("DISPLAY");
27    if (!disp) disp = ":0";
28    pid = (int)getpid();
29    snprintf(buf, sizeof(buf), "%s/enlightenment-%s", tmp, user);
30    if (mkdir(buf, S_IRWXU) == 0)
31      {
32      }
33    else
34      {
35         struct stat st;
36
37         if (stat(buf, &st) == 0)
38           {
39              if ((st.st_uid ==
40                   getuid()) &&
41                  ((st.st_mode & (S_IFDIR|S_IRWXU|S_IRWXG|S_IRWXO)) ==
42                   (S_IRWXU|S_IFDIR)))
43                {
44                }
45              else
46                {
47                   e_error_message_show(_("Possible IPC Hack Attempt. The IPC socket\n"
48                                          "directory already exists BUT has permissions\n"
49                                          "that are too leanient (must only be readable\n" "and writable by the owner, and nobody else)\n"
50                                          "or is not owned by you. Please check:\n"
51                                          "%s/enlightenment-%s\n"), tmp, user);
52                   return 0;
53                }
54           }
55         else
56           {
57              e_error_message_show(_("The IPC socket directory cannot be created or\n"
58                                     "examined.\n"
59                                     "Please check:\n"
60                                     "%s/enlightenment-%s\n"),
61                                   tmp, user);
62              return 0;
63           }
64      }
65    snprintf(buf, sizeof(buf), "%s/enlightenment-%s/disp-%s-%i", tmp, user, disp, pid);
66    _e_ipc_server = ecore_ipc_server_add(ECORE_IPC_LOCAL_SYSTEM, buf, 0, NULL);
67    e_util_env_set("E_IPC_SOCKET", "");
68    if (!_e_ipc_server) return 0;
69    e_util_env_set("E_IPC_SOCKET", buf);
70    printf("INFO: E_IPC_SOCKET=%s\n", buf);
71    ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, _e_ipc_cb_client_add, NULL);
72    ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, _e_ipc_cb_client_del, NULL);
73    ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, _e_ipc_cb_client_data, NULL);
74
75    e_ipc_codec_init();
76 #endif
77    return 1;
78 }
79
80 EINTERN int
81 e_ipc_shutdown(void)
82 {
83 #ifdef USE_IPC
84    e_ipc_codec_shutdown();
85    if (_e_ipc_server)
86      {
87         ecore_ipc_server_del(_e_ipc_server);
88         _e_ipc_server = NULL;
89      }
90 #endif
91    return 1;
92 }
93
94 #ifdef USE_IPC
95 /* local subsystem globals */
96 static Eina_Bool
97 _e_ipc_cb_client_add(void *data __UNUSED__, int type __UNUSED__, void *event)
98 {
99    Ecore_Ipc_Event_Client_Add *e;
100
101    e = event;
102    if (ecore_ipc_client_server_get(e->client) != _e_ipc_server) return ECORE_CALLBACK_PASS_ON;
103    return ECORE_CALLBACK_PASS_ON;
104 }
105
106 static Eina_Bool
107 _e_ipc_cb_client_del(void *data __UNUSED__, int type __UNUSED__, void *event)
108 {
109    Ecore_Ipc_Event_Client_Del *e;
110
111    e = event;
112    if (ecore_ipc_client_server_get(e->client) != _e_ipc_server) return ECORE_CALLBACK_PASS_ON;
113    /* delete client sruct */
114    e_thumb_client_del(e);
115    e_fm2_client_del(e);
116    e_init_client_del(e);
117    ecore_ipc_client_del(e->client);
118    return ECORE_CALLBACK_PASS_ON;
119 }
120
121 static Eina_Bool
122 _e_ipc_cb_client_data(void *data __UNUSED__, int type __UNUSED__, void *event)
123 {
124    Ecore_Ipc_Event_Client_Data *e;
125
126    e = event;
127    if (ecore_ipc_client_server_get(e->client) != _e_ipc_server) return ECORE_CALLBACK_PASS_ON;
128    switch (e->major)
129      {
130       case E_IPC_DOMAIN_SETUP:
131       case E_IPC_DOMAIN_REQUEST:
132       case E_IPC_DOMAIN_REPLY:
133       case E_IPC_DOMAIN_EVENT:
134         switch (e->minor)
135           {
136           case E_IPC_OP_EXEC_ACTION:
137                {
138                   E_Ipc_2Str *req = NULL;
139
140                   if (e_ipc_codec_2str_dec(e->data, e->size, &req))
141                     {
142                        Eina_List *m = e_manager_list();
143                        int len, ok = 0;
144                        void *d;
145
146                        if (m)
147                          {
148                             E_Manager *man = eina_list_data_get(m);
149
150                             if (man)
151                               {
152                                  E_Action *act = e_action_find(req->str1);
153
154                                  if (act && act->func.go)
155                                    {
156                                       act->func.go(E_OBJECT(man), req->str2);
157                                       ok = 1;
158                                    }
159                               }
160                          }
161
162                        d = e_ipc_codec_int_enc(ok, &len);
163                        if (d)
164                          {
165                             ecore_ipc_client_send(e->client,
166                                                   E_IPC_DOMAIN_REPLY,
167                                                   E_IPC_OP_EXEC_ACTION_REPLY,
168                                                   0, 0, 0, d, len);
169                             free(d);
170                          }
171
172                        if (req)
173                          {
174                             E_FREE(req->str1);
175                             E_FREE(req->str2);
176                             E_FREE(req);
177                          }
178                     }
179                }
180              break;
181           default:
182              break;
183           }
184         break;
185       case E_IPC_DOMAIN_THUMB:
186         e_thumb_client_data(e);
187         break;
188       case E_IPC_DOMAIN_FM:
189         e_fm2_client_data(e);
190         break;
191       case E_IPC_DOMAIN_INIT:
192         e_init_client_data(e);
193         break;
194       default:
195         break;
196      }
197    return 1;
198 }
199 #endif