2 #include "e_mod_main.h"
3 #include "e_mod_dbus.h"
5 static const char E_FILEMAN_BUS_NAME[] = "org.enlightenment.FileManager";
6 static const char E_FILEMAN_INTERFACE[] = "org.enlightenment.FileManager";
7 static const char E_FILEMAN_ERROR[] = "org.enlightenment.FileManager.Error";
8 static const char E_FILEMAN_PATH[] = "/org/enlightenment/FileManager";
10 typedef struct _E_Fileman_DBus_Daemon E_Fileman_DBus_Daemon;
11 struct _E_Fileman_DBus_Daemon
13 E_DBus_Connection *conn;
14 E_DBus_Interface *iface;
19 DBusPendingCall *request_name;
24 _e_fileman_dbus_daemon_error(DBusMessage *message,
27 return dbus_message_new_error(message, E_FILEMAN_ERROR, msg);
31 _e_fileman_dbus_daemon_object_init(E_Fileman_DBus_Daemon *d)
35 d->obj = e_dbus_object_add(d->conn, E_FILEMAN_PATH, d);
38 fprintf(stderr, "ERROR: cannot add object to %s\n", E_FILEMAN_PATH);
42 e_dbus_object_interface_attach(d->obj, d->iface);
46 _e_fileman_dbus_daemon_free(E_Fileman_DBus_Daemon *d)
48 if (d->pending.request_name)
49 dbus_pending_call_cancel(d->pending.request_name);
53 e_dbus_object_interface_detach(d->obj, d->iface);
54 e_dbus_object_free(d->obj);
58 e_dbus_interface_unref(d->iface);
61 e_dbus_connection_close(d->conn);
67 _e_fileman_dbus_daemon_open_directory_cb(E_DBus_Object *obj __UNUSED__,
71 const char *directory = NULL, *p;
72 char *dev, *to_free = NULL;
75 dbus_message_iter_init(message, &itr);
76 dbus_message_iter_get_basic(&itr, &directory);
78 if ((!directory) || (directory[0] == '\0'))
79 return _e_fileman_dbus_daemon_error(message, "no directory provided.");
81 zone = e_util_zone_current_get(e_manager_current_get());
83 return _e_fileman_dbus_daemon_error(message, "could not find a zone.");
85 if (strstr(directory, "://"))
87 Efreet_Uri *uri = efreet_uri_decode(directory);
92 if ((uri->protocol) && (strcmp(uri->protocol, "file") == 0))
93 directory = to_free = strdup(uri->path);
98 return _e_fileman_dbus_daemon_error(message, "unsupported protocol");
101 p = strchr(directory, '/');
104 int len = p - directory + 1;
106 dev = malloc(len + 1);
110 return _e_fileman_dbus_daemon_error(message,
111 "could not allocate memory.");
114 memcpy(dev, directory, len);
117 if ((dev[0] != '/') && (dev[0] != '~'))
118 dev[len - 1] = '\0'; /* remove trailing '/' */
120 directory += p - directory;
124 dev = strdup(directory);
128 e_fwin_new(zone->container, dev, directory);
131 return dbus_message_new_method_return(message);
135 _mime_shell_script_check(const char *mime)
137 static const struct sh_script_map {
141 #define O(x) {x, sizeof(x) - 1}
142 O("application/x-sh"),
143 O("application/x-shellscript"),
148 const struct sh_script_map *itr;
149 size_t mimelen = strlen(mime);
151 for (itr = options; itr->str != NULL; itr++)
152 if ((mimelen == itr->len) && (memcmp(mime, itr->str, mimelen) == 0))
159 _e_fileman_dbus_daemon_open_file_cb(E_DBus_Object *obj __UNUSED__,
160 DBusMessage *message)
164 const char *param_file = NULL, *mime, *errmsg = "unknow error";
165 char *real_file, *to_free = NULL;
168 dbus_message_iter_init(message, &itr);
169 dbus_message_iter_get_basic(&itr, ¶m_file);
171 if ((!param_file) || (param_file[0] == '\0'))
172 return _e_fileman_dbus_daemon_error(message, "no file provided.");
174 zone = e_util_zone_current_get(e_manager_current_get());
176 return _e_fileman_dbus_daemon_error(message, "could not find a zone.");
178 if (!strstr(param_file, "://"))
180 real_file = ecore_file_realpath(param_file);
183 errmsg = "couldn't get realpath for file.";
189 Efreet_Uri *uri = efreet_uri_decode(param_file);
194 if ((uri->protocol) && (strcmp(uri->protocol, "file") == 0))
196 real_file = ecore_file_realpath(uri->path);
197 param_file = to_free = strdup(uri->path);
199 efreet_uri_free(uri);
204 errmsg = "unsupported protocol";
209 mime = efreet_mime_type_get(real_file);
212 errmsg = "couldn't find mime-type";
216 if (strcmp(mime, "application/x-desktop") == 0)
218 Efreet_Desktop *desktop = efreet_desktop_new(real_file);
221 errmsg = "couldn't open desktop file";
225 e_exec(zone, desktop, NULL, NULL, NULL);
226 efreet_desktop_free(desktop);
229 else if ((strcmp(mime, "application/x-executable") == 0) ||
230 ecore_file_can_exec(param_file))
232 e_exec(zone, NULL, param_file, NULL, NULL);
235 else if (_mime_shell_script_check(mime))
237 Eina_Strbuf *b = eina_strbuf_new();
238 const char *shell = getenv("SHELL");
241 uid_t uid = getuid();
242 struct passwd *pw = getpwuid(uid);
243 if (pw) shell = pw->pw_shell;
245 if (!shell) shell = "/bin/sh";
246 eina_strbuf_append_printf(b, "%s %s %s",
247 e_config->exebuf_term_cmd,
250 e_exec(zone, NULL, eina_strbuf_string_get(b), NULL, NULL);
255 handlers = efreet_util_desktop_mime_list(mime);
258 errmsg = "no handlers for given file";
263 Efreet_Desktop *desktop = handlers->data;
264 Eina_List *files = eina_list_append(NULL, param_file);
266 e_exec(zone, desktop, NULL, files, NULL);
267 eina_list_free(files);
269 EINA_LIST_FREE(handlers, desktop)
270 efreet_desktop_free(desktop);
276 return dbus_message_new_method_return(message);
281 return _e_fileman_dbus_daemon_error(message, errmsg);
285 _e_fileman_dbus_daemon_request_name_cb(void *data,
289 E_Fileman_DBus_Daemon *d = data;
293 d->pending.request_name = NULL;
295 if (dbus_error_is_set(err))
297 fprintf(stderr, "ERROR: FILEMAN: RequestName failed: %s\n",
299 dbus_error_free(err);
303 dbus_error_init(&new_err);
304 dbus_message_get_args(msg, &new_err, DBUS_TYPE_UINT32, &ret,
307 if (dbus_error_is_set(&new_err))
310 "ERROR: FILEMAN: could not get arguments of RequestName: %s\n",
312 dbus_error_free(&new_err);
318 case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
319 case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
320 _e_fileman_dbus_daemon_object_init(d);
323 case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
324 //XXX mark daemon as queued?
327 case DBUS_REQUEST_NAME_REPLY_EXISTS:
333 static E_Fileman_DBus_Daemon *
334 _e_fileman_dbus_daemon_new(void)
339 const char *signature;
340 const char *ret_signature;
341 E_DBus_Method_Cb func;
343 {"OpenDirectory", "s", "", _e_fileman_dbus_daemon_open_directory_cb},
344 {"OpenFile", "s", "", _e_fileman_dbus_daemon_open_file_cb},
345 {NULL, NULL, NULL, NULL}
347 E_Fileman_DBus_Daemon *d;
349 d = calloc(1, sizeof(*d));
352 perror("ERROR: FILEMAN: cannot allocate fileman dbus daemon memory.");
356 d->conn = e_dbus_bus_get(DBUS_BUS_SESSION);
360 d->iface = e_dbus_interface_new(E_FILEMAN_INTERFACE);
364 d->pending.request_name = e_dbus_request_name
365 (d->conn, E_FILEMAN_BUS_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING,
366 _e_fileman_dbus_daemon_request_name_cb, d);
367 if (!d->pending.request_name)
370 for (itr = desc; itr->method; itr++)
371 e_dbus_interface_method_add
372 (d->iface, itr->method, itr->signature, itr->ret_signature, itr->func);
377 fprintf(stderr, "ERROR: FILEMAN: failed to create daemon at %p\n", d);
378 _e_fileman_dbus_daemon_free(d);
382 static E_Fileman_DBus_Daemon *_daemon = NULL;
385 e_fileman_dbus_init(void)
391 _daemon = _e_fileman_dbus_daemon_new();
395 e_fileman_dbus_shutdown(void)
400 _e_fileman_dbus_daemon_free(_daemon);