update for beta release
[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 == getuid()) &&
40                  ((st.st_mode & (S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO)) ==
41                   (S_IRWXU | S_IFDIR)))
42                {
43                }
44              else
45                {
46                   e_error_message_show(_("Possible IPC Hack Attempt. The IPC socket\n"
47                                          "directory already exists BUT has permissions\n"
48                                          "that are too leanient (must only be readable\n" "and writable by the owner, and nobody else)\n"
49                                                                                           "or is not owned by you. Please check:\n"
50                                                                                           "%s/enlightenment-%s\n"), tmp, user);
51                   return 0;
52                }
53           }
54         else
55           {
56              e_error_message_show(_("The IPC socket directory cannot be created or\n"
57                                     "examined.\n"
58                                     "Please check:\n"
59                                     "%s/enlightenment-%s\n"),
60                                   tmp, user);
61              return 0;
62           }
63      }
64    snprintf(buf, sizeof(buf), "%s/enlightenment-%s/disp-%s-%i", 
65             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, 
72                            _e_ipc_cb_client_add, NULL);
73    ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, 
74                            _e_ipc_cb_client_del, NULL);
75    ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, 
76                            _e_ipc_cb_client_data, NULL);
77
78    e_ipc_codec_init();
79 #endif
80    return 1;
81 }
82
83 EINTERN int
84 e_ipc_shutdown(void)
85 {
86 #ifdef USE_IPC
87    e_ipc_codec_shutdown();
88    if (_e_ipc_server)
89      {
90         ecore_ipc_server_del(_e_ipc_server);
91         _e_ipc_server = NULL;
92      }
93 #endif
94    return 1;
95 }
96
97 #ifdef USE_IPC
98 /* local subsystem globals */
99 static Eina_Bool
100 _e_ipc_cb_client_add(void *data __UNUSED__, int type __UNUSED__, void *event)
101 {
102    Ecore_Ipc_Event_Client_Add *e;
103
104    e = event;
105    if (ecore_ipc_client_server_get(e->client) != _e_ipc_server) 
106      return ECORE_CALLBACK_PASS_ON;
107    return ECORE_CALLBACK_PASS_ON;
108 }
109
110 static Eina_Bool
111 _e_ipc_cb_client_del(void *data __UNUSED__, int type __UNUSED__, void *event)
112 {
113    Ecore_Ipc_Event_Client_Del *e;
114
115    e = event;
116    if (ecore_ipc_client_server_get(e->client) != _e_ipc_server) 
117      return ECORE_CALLBACK_PASS_ON;
118    /* delete client sruct */
119    e_thumb_client_del(e);
120    e_fm2_client_del(e);
121    e_init_client_del(e);
122    ecore_ipc_client_del(e->client);
123    return ECORE_CALLBACK_PASS_ON;
124 }
125
126 static Eina_Bool
127 _e_ipc_cb_client_data(void *data __UNUSED__, int type __UNUSED__, void *event)
128 {
129    Ecore_Ipc_Event_Client_Data *e;
130
131    e = event;
132    if (ecore_ipc_client_server_get(e->client) != _e_ipc_server) 
133      return ECORE_CALLBACK_PASS_ON;
134    switch (e->major)
135      {
136       case E_IPC_DOMAIN_SETUP:
137       case E_IPC_DOMAIN_REQUEST:
138       case E_IPC_DOMAIN_REPLY:
139       case E_IPC_DOMAIN_EVENT:
140         switch (e->minor)
141           {
142            case E_IPC_OP_EXEC_ACTION:
143                {
144                   E_Ipc_2Str *req = NULL;
145
146                   if (e_ipc_codec_2str_dec(e->data, e->size, &req))
147                     {
148                        Eina_List *m = e_manager_list();
149                        int len, ok = 0;
150                        void *d;
151
152                        if (m)
153                          {
154                             E_Manager *man = eina_list_data_get(m);
155
156                             if (man)
157                               {
158                                  E_Action *act = e_action_find(req->str1);
159
160                                  if ((act) && (act->func.go))
161                                    {
162                                       act->func.go(E_OBJECT(man), req->str2);
163                                       ok = 1;
164                                    }
165                               }
166                          }
167
168                        d = e_ipc_codec_int_enc(ok, &len);
169                        if (d)
170                          {
171                             ecore_ipc_client_send(e->client,
172                                                   E_IPC_DOMAIN_REPLY,
173                                                   E_IPC_OP_EXEC_ACTION_REPLY,
174                                                   0, 0, 0, d, len);
175                             free(d);
176                          }
177
178                        if (req)
179                          {
180                             E_FREE(req->str1);
181                             E_FREE(req->str2);
182                             E_FREE(req);
183                          }
184                     }
185                }
186              break;
187
188            default:
189              break;
190           }
191         break;
192
193       case E_IPC_DOMAIN_THUMB:
194         e_thumb_client_data(e);
195         break;
196
197       case E_IPC_DOMAIN_FM:
198         e_fm2_client_data(e);
199         break;
200
201       case E_IPC_DOMAIN_INIT:
202         e_init_client_data(e);
203         break;
204
205       case E_IPC_DOMAIN_ALERT:
206           {
207              switch (e->minor)
208                {
209                 case E_ALERT_OP_RESTART:
210                   if (getenv("E_START_MTRACK"))
211                     e_util_env_set("MTRACK", "track");
212                   ecore_app_restart();
213                   break;
214                 case E_ALERT_OP_EXIT:
215                   exit(-11);
216                   break;
217                }
218           }
219         break;
220       default:
221         break;
222      }
223    return 1;
224 }
225
226 #endif