Compare commits
1 Commits
master
...
devs/cedri
Author | SHA1 | Date |
---|---|---|
Cedric Bail | fa33725fdd |
11
configure.ac
11
configure.ac
|
@ -53,6 +53,16 @@ PKG_CHECK_MODULES([ELDBUS],
|
|||
[have_eldbus="no"]
|
||||
)
|
||||
|
||||
PKG_CHECK_MODULES([AVAHI],
|
||||
[avahi-client ecore-avahi],
|
||||
[
|
||||
AC_DEFINE(HAVE_AVAHI, 1, [Avahi support])
|
||||
have_avahi="yes"
|
||||
],
|
||||
[
|
||||
have_avahi="no"
|
||||
])
|
||||
|
||||
AC_CHECK_FUNCS(mkstemps)
|
||||
|
||||
EFL_WITH_BIN([edje], [edje-cc], [edje_cc])
|
||||
|
@ -114,4 +124,5 @@ echo " prefix...................: $prefix"
|
|||
echo
|
||||
echo "Features:"
|
||||
echo " dbus................: $have_eldbus"
|
||||
echo " avahi...............: $have_avahi"
|
||||
echo
|
||||
|
|
|
@ -5,9 +5,9 @@ bin_PROGRAMS = terminology tybg tyalpha typop tyq tycat tyls
|
|||
|
||||
terminology_CPPFLAGS = -I. \
|
||||
-DPACKAGE_BIN_DIR=\"$(bindir)\" -DPACKAGE_LIB_DIR=\"$(libdir)\" \
|
||||
-DPACKAGE_DATA_DIR=\"$(pkgdatadir)\" @TERMINOLOGY_CFLAGS@
|
||||
-DPACKAGE_DATA_DIR=\"$(pkgdatadir)\" @TERMINOLOGY_CFLAGS@ @AVAHI_CFLAGS@
|
||||
|
||||
terminology_LDADD = @TERMINOLOGY_LIBS@ @ELDBUS_LIBS@
|
||||
terminology_LDADD = @TERMINOLOGY_LIBS@ @ELDBUS_LIBS@ @AVAHI_LIBS@
|
||||
|
||||
terminology_SOURCES = \
|
||||
private.h \
|
||||
|
@ -20,6 +20,7 @@ keyin.c keyin.h \
|
|||
main.c main.h \
|
||||
media.c media.h \
|
||||
options.c options.h \
|
||||
options_ssh.h options_ssh.c \
|
||||
options_font.c options_font.h \
|
||||
options_theme.c options_theme.h \
|
||||
options_themepv.c options_themepv.h \
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "main.h"
|
||||
|
||||
static Evas_Object *ct_frame = NULL, *ct_boxh = NULL, *ct_box = NULL;
|
||||
static Evas_Object *ct_box2 = NULL, *ct_over = NULL;
|
||||
static Evas_Object *ct_box2 = NULL, *ct_boxssh = NULL, *ct_over = NULL;
|
||||
static Eina_Bool ct_out = EINA_FALSE;
|
||||
static Ecore_Timer *ct_del_timer = NULL;
|
||||
static Evas_Object *ct_win = NULL, *ct_bg = NULL, *ct_term = NULL;
|
||||
|
@ -240,9 +240,13 @@ controls_toggle(Evas_Object *win, Evas_Object *bg, Evas_Object *term,
|
|||
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
elm_object_text_set(o, "Controls");
|
||||
|
||||
ct_boxssh = o = elm_box_add(win);
|
||||
elm_object_content_set(ct_frame, o);
|
||||
evas_object_show(o);
|
||||
|
||||
ct_boxh = o = elm_box_add(win);
|
||||
elm_box_horizontal_set(o, EINA_TRUE);
|
||||
elm_object_content_set(ct_frame, o);
|
||||
elm_box_pack_end(ct_boxssh, o);
|
||||
evas_object_show(o);
|
||||
|
||||
ct_box2 = o = elm_box_add(win);
|
||||
|
@ -293,6 +297,19 @@ controls_toggle(Evas_Object *win, Evas_Object *bg, Evas_Object *term,
|
|||
o = _button_add(win, "About", "about", _cb_ct_about, NULL);
|
||||
elm_box_pack_end(ct_box, o);
|
||||
|
||||
o = _sep_add_h(win);
|
||||
elm_box_pack_end(ct_boxssh, o);
|
||||
|
||||
o = elm_genlist_add(win);
|
||||
evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||
evas_object_size_hint_align_set(o, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||
evas_object_size_hint_request_set(o, 64, 64);
|
||||
elm_genlist_mode_set(o, ELM_LIST_COMPRESS);
|
||||
elm_genlist_homogeneous_set(o, EINA_TRUE);
|
||||
elm_box_pack_end(ct_boxssh, o);
|
||||
evas_object_show(o);
|
||||
options_genlist_add(o);
|
||||
|
||||
evas_object_event_callback_add(ct_frame, EVAS_CALLBACK_DEL,
|
||||
_cb_frame_del, NULL);
|
||||
|
||||
|
|
|
@ -2704,6 +2704,7 @@ elm_main(int argc, char **argv)
|
|||
elm_app_info_set(elm_main, "terminology", "themes/default.edj");
|
||||
|
||||
config_init();
|
||||
options_ssh_init();
|
||||
|
||||
main_config = config_load("config");
|
||||
|
||||
|
@ -3058,6 +3059,7 @@ remote:
|
|||
termpty_shutdown();
|
||||
|
||||
config_del(main_config);
|
||||
options_ssh_shutdown();
|
||||
config_shutdown();
|
||||
eina_log_domain_unregister(_log_domain);
|
||||
_log_domain = -1;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "options_behavior.h"
|
||||
#include "options_keys.h"
|
||||
#include "options_helpers.h"
|
||||
#include "options_ssh.h"
|
||||
#include "config.h"
|
||||
#include "termio.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,408 @@
|
|||
#include "private.h"
|
||||
|
||||
#include <Elementary.h>
|
||||
|
||||
#ifdef HAVE_AVAHI
|
||||
# include <Ecore_Avahi.h>
|
||||
# include <avahi-client/client.h>
|
||||
# include <avahi-client/lookup.h>
|
||||
# include <avahi-common/error.h>
|
||||
#endif
|
||||
|
||||
#include "options_ssh.h"
|
||||
|
||||
#define FREE_CLEAN(h, cb) do { if (h) cb(h); h = NULL; } while (0);
|
||||
|
||||
typedef struct _SSH_Genlist SSH_Genlist;
|
||||
struct _SSH_Genlist
|
||||
{
|
||||
Evas_Object *gl;
|
||||
Elm_Object_Item *announced_servers;
|
||||
Elm_Object_Item *ww_servers;
|
||||
Eina_List *items;
|
||||
};
|
||||
|
||||
struct _SSH_Server
|
||||
{
|
||||
const char *domain;
|
||||
const char *name;
|
||||
const char *ip;
|
||||
unsigned int port;
|
||||
|
||||
unsigned char announced : 1;
|
||||
};
|
||||
|
||||
static Eina_List *announced_servers = NULL;
|
||||
static Eina_List *ww_servers = NULL;
|
||||
static Eina_List *genlists = NULL;
|
||||
|
||||
static Elm_Genlist_Item_Class *itc_group = NULL;
|
||||
static Elm_Genlist_Item_Class *itc = NULL;
|
||||
|
||||
static void
|
||||
_option_genlist_ssh_add(SSH_Genlist *genlist, unsigned char announced, const SSH_Server *server)
|
||||
{
|
||||
Elm_Object_Item *parent;
|
||||
Elm_Object_Item *it;
|
||||
|
||||
if (announced)
|
||||
{
|
||||
if (!genlist->announced_servers)
|
||||
{
|
||||
genlist->announced_servers = elm_genlist_item_append(genlist->gl, itc_group,
|
||||
(void *)(uintptr_t)1 /* item data */,
|
||||
NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
|
||||
elm_genlist_item_select_mode_set(genlist->announced_servers, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
|
||||
}
|
||||
parent = genlist->announced_servers;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!genlist->ww_servers)
|
||||
{
|
||||
genlist->ww_servers = elm_genlist_item_append(genlist->gl, itc_group, NULL,
|
||||
NULL, ELM_GENLIST_ITEM_GROUP, NULL, NULL);
|
||||
elm_genlist_item_select_mode_set(genlist->ww_servers, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
|
||||
}
|
||||
parent = genlist->ww_servers;
|
||||
}
|
||||
|
||||
it = elm_genlist_item_append(genlist->gl, itc, server /* item data */,
|
||||
parent /* parent */,
|
||||
ELM_GENLIST_ITEM_NONE,
|
||||
NULL /* func */, // FIXME: there should the action come
|
||||
NULL);
|
||||
|
||||
genlist->items = eina_list_append(genlist->items, it);
|
||||
}
|
||||
|
||||
static void
|
||||
_option_genlist_ssh_del(SSH_Genlist *genlist, const SSH_Server *server)
|
||||
{
|
||||
Elm_Object_Item *it;
|
||||
Eina_List *l, *ll;
|
||||
|
||||
EINA_LIST_FOREACH_SAFE(genlist->items, l, ll, it)
|
||||
if (elm_object_item_data_get(it) == server)
|
||||
{
|
||||
elm_object_item_del(it);
|
||||
genlist->items = eina_list_remove_list(genlist->items, l);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
options_ssh_server_add(unsigned char announced, const char *domain, const char *name, const char *ip, unsigned int port)
|
||||
{
|
||||
SSH_Server *srv;
|
||||
SSH_Genlist *genlist;
|
||||
Eina_List* l;
|
||||
|
||||
srv = calloc(1, sizeof (SSH_Server));
|
||||
if (!srv) return ;
|
||||
|
||||
srv->domain = eina_stringshare_add(domain);
|
||||
srv->name = eina_stringshare_add(name);
|
||||
srv->ip = eina_stringshare_add(ip);
|
||||
srv->port = port;
|
||||
srv->announced = announced;
|
||||
|
||||
INF("Avahi discovered new host '%s' (%s:%i) from domain '%s'.",
|
||||
name, ip, port, domain);
|
||||
|
||||
if (announced)
|
||||
announced_servers = eina_list_append(announced_servers, srv);
|
||||
else
|
||||
ww_servers = eina_list_append(ww_servers, srv);
|
||||
|
||||
EINA_LIST_FOREACH(genlists, l, genlist)
|
||||
_option_genlist_ssh_add(genlist, announced, srv);
|
||||
}
|
||||
|
||||
void
|
||||
options_ssh_server_data_del(SSH_Server *server)
|
||||
{
|
||||
SSH_Genlist *genlist;
|
||||
Eina_List *l;
|
||||
|
||||
INF("Avahi discovered host disapeared '%s' (%s:%i) from domain '%s'.",
|
||||
server->name, server->ip, server->port, server->domain);
|
||||
|
||||
EINA_LIST_FOREACH(genlists, l, genlist)
|
||||
_option_genlist_ssh_del(genlist, server);
|
||||
|
||||
eina_stringshare_del(server->name);
|
||||
eina_stringshare_del(server->domain);
|
||||
eina_stringshare_del(server->ip);
|
||||
|
||||
if (server->announced)
|
||||
announced_servers = eina_list_remove(announced_servers, server);
|
||||
else
|
||||
ww_servers = eina_list_remove(ww_servers, server);
|
||||
|
||||
free(server);
|
||||
}
|
||||
|
||||
void
|
||||
options_ssh_server_del(unsigned char announced, const char *domain, const char *name)
|
||||
{
|
||||
SSH_Server *srv;
|
||||
Eina_List *l;
|
||||
|
||||
domain = eina_stringshare_add(domain);
|
||||
name = eina_stringshare_add(name);
|
||||
|
||||
l = announced ? announced_servers : ww_servers;
|
||||
|
||||
EINA_LIST_FOREACH(l, l, srv)
|
||||
if (srv->name == name &&
|
||||
srv->domain == domain)
|
||||
{
|
||||
options_ssh_server_data_del(srv);
|
||||
break;
|
||||
}
|
||||
|
||||
eina_stringshare_del(domain);
|
||||
eina_stringshare_del(name);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_options_genlist_death(void *data, Eo *obj EINA_UNUSED,
|
||||
const Eo_Event_Description *desc EINA_UNUSED,
|
||||
void *event_info EINA_UNUSED)
|
||||
{
|
||||
SSH_Genlist *genlist = data;
|
||||
|
||||
eina_list_free(genlist->items);
|
||||
free(genlist);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
options_genlist_add(Evas_Object *gl)
|
||||
{
|
||||
SSH_Genlist *genlist;
|
||||
SSH_Server *srv;
|
||||
Eina_List *l;
|
||||
|
||||
genlist = calloc(1, sizeof(SSH_Genlist));
|
||||
if (!genlist) return ;
|
||||
|
||||
genlist->gl = gl;
|
||||
|
||||
EINA_LIST_FOREACH(announced_servers, l, srv)
|
||||
_option_genlist_ssh_add(genlist, 1, srv);
|
||||
EINA_LIST_FOREACH(ww_servers, l, srv)
|
||||
_option_genlist_ssh_add(genlist, 0, srv);
|
||||
|
||||
eo_do(gl, eo_event_callback_add(EO_EV_DEL, _options_genlist_death, genlist));
|
||||
}
|
||||
|
||||
static char *
|
||||
gl_text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
|
||||
{
|
||||
SSH_Server *srv = data;
|
||||
Eina_Strbuf *buf;
|
||||
char *r;
|
||||
|
||||
buf = eina_strbuf_new();
|
||||
|
||||
if (srv->port != 22)
|
||||
eina_strbuf_append_printf(buf, "%s:%i", srv->name, srv->port);
|
||||
else
|
||||
eina_strbuf_append_printf(buf, "%s", srv->name);
|
||||
|
||||
r = eina_strbuf_string_steal(buf);
|
||||
eina_strbuf_free(buf);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static char *
|
||||
gl_group_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
|
||||
{
|
||||
if (data) return strdup("Announced server");
|
||||
return strdup("World wide server");
|
||||
}
|
||||
|
||||
#ifdef HAVE_AVAHI
|
||||
static Ecore_Avahi *context = NULL;
|
||||
static AvahiClient *client = NULL;
|
||||
static AvahiServiceBrowser *sb = NULL;
|
||||
static int error = 0;
|
||||
|
||||
// FIXME: Check what it does
|
||||
static void
|
||||
_resolve_callback(AvahiServiceResolver *r,
|
||||
AvahiIfIndex interface EINA_UNUSED,
|
||||
AvahiProtocol protocol EINA_UNUSED,
|
||||
AvahiResolverEvent event,
|
||||
const char *name,
|
||||
const char *type,
|
||||
const char *domain,
|
||||
const char *host_name EINA_UNUSED,
|
||||
const AvahiAddress *address,
|
||||
uint16_t port,
|
||||
AvahiStringList *txt EINA_UNUSED,
|
||||
AvahiLookupResultFlags flags EINA_UNUSED,
|
||||
void* userdata EINA_UNUSED)
|
||||
{
|
||||
/* Called whenever a service has been resolved successfully or timed out */
|
||||
switch (event)
|
||||
{
|
||||
case AVAHI_RESOLVER_FAILURE:
|
||||
ERR("Avahi failed to resolve service '%s' of type '%s' in domain '%s': %s\n",
|
||||
name, type, domain,
|
||||
avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
|
||||
break;
|
||||
|
||||
case AVAHI_RESOLVER_FOUND:
|
||||
{
|
||||
char a[AVAHI_ADDRESS_STR_MAX];
|
||||
|
||||
avahi_address_snprint(a, sizeof(a), address);
|
||||
options_ssh_server_add(1, domain, name, a, port);
|
||||
}
|
||||
}
|
||||
|
||||
avahi_service_resolver_free(r);
|
||||
}
|
||||
|
||||
static void
|
||||
_browse_callback(AvahiServiceBrowser *b EINA_UNUSED,
|
||||
AvahiIfIndex interface,
|
||||
AvahiProtocol protocol,
|
||||
AvahiBrowserEvent event,
|
||||
const char *name,
|
||||
const char *type,
|
||||
const char *domain,
|
||||
AvahiLookupResultFlags flags EINA_UNUSED,
|
||||
void* userdata)
|
||||
{
|
||||
AvahiClient *c = userdata;
|
||||
|
||||
/* Called whenever a new services becomes available on the LAN or is removed from the LAN */
|
||||
switch (event)
|
||||
{
|
||||
case AVAHI_BROWSER_FAILURE:
|
||||
// FIXME: What to do in case of failure ? Schedule another browser ?
|
||||
break;
|
||||
|
||||
case AVAHI_BROWSER_NEW:
|
||||
/* We ignore the returned resolver object. In the callback
|
||||
function we free it. If the server is terminated before
|
||||
the callback function is called the server will free
|
||||
the resolver for us. */
|
||||
|
||||
avahi_service_resolver_new(c, interface,
|
||||
protocol, name, type, domain,
|
||||
AVAHI_PROTO_UNSPEC, 0, _resolve_callback, c);
|
||||
|
||||
break;
|
||||
|
||||
case AVAHI_BROWSER_REMOVE:
|
||||
options_ssh_server_del(1, domain, name);
|
||||
break;
|
||||
|
||||
case AVAHI_BROWSER_ALL_FOR_NOW:
|
||||
case AVAHI_BROWSER_CACHE_EXHAUSTED:
|
||||
/* Nothing to do in our case */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_client_callback(AvahiClient *c, AvahiClientState state, void * userdata EINA_UNUSED)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case AVAHI_CLIENT_S_REGISTERING:
|
||||
case AVAHI_CLIENT_S_COLLISION:
|
||||
case AVAHI_CLIENT_S_RUNNING:
|
||||
if (!sb)
|
||||
{
|
||||
sb = avahi_service_browser_new(c, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ssh._tcp", NULL, 0, _browse_callback, c);
|
||||
if (!sb)
|
||||
{
|
||||
WRN("Failed to setup an Avahi Service Browser.");
|
||||
return ;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AVAHI_CLIENT_FAILURE:
|
||||
WRN("Server connection failure: %s.", avahi_strerror(avahi_client_errno(c)));
|
||||
if (avahi_client_errno(c) == AVAHI_ERR_DISCONNECTED)
|
||||
{
|
||||
FREE_CLEAN(sb, avahi_service_browser_free);
|
||||
FREE_CLEAN(client, avahi_client_free);
|
||||
|
||||
client = avahi_client_new(ecore_avahi_poll_get(context), AVAHI_CLIENT_NO_FAIL, _client_callback, NULL, &error);
|
||||
if (!client)
|
||||
{
|
||||
WRN("Unable to setup an AvahiClient context.");
|
||||
return ;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case AVAHI_CLIENT_CONNECTING:
|
||||
FREE_CLEAN(sb, avahi_service_browser_free);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
options_ssh_init(void)
|
||||
{
|
||||
if (!itc)
|
||||
{
|
||||
itc = elm_genlist_item_class_new();
|
||||
itc->item_style = "default";
|
||||
itc->func.text_get = gl_text_get;
|
||||
itc->func.content_get = NULL;
|
||||
itc->func.state_get = NULL;
|
||||
itc->func.del = NULL;
|
||||
}
|
||||
if (!itc_group)
|
||||
{
|
||||
itc_group = elm_genlist_item_class_new();
|
||||
itc_group->item_style = "group_index";
|
||||
itc_group->func.text_get = gl_group_get;
|
||||
itc_group->func.content_get = NULL;
|
||||
itc_group->func.state_get = NULL;
|
||||
itc_group->func.del = NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_AVAHI
|
||||
if (context) return ;
|
||||
|
||||
context = ecore_avahi_add();
|
||||
if (!context)
|
||||
{
|
||||
WRN("Unable to setup an Ecore_Avahi context.");
|
||||
return ;
|
||||
}
|
||||
|
||||
client = avahi_client_new(ecore_avahi_poll_get(context), AVAHI_CLIENT_NO_FAIL, _client_callback, NULL, &error);
|
||||
if (!client)
|
||||
{
|
||||
WRN("Unable to setup an AvahiClient context.");
|
||||
options_ssh_shutdown();
|
||||
return ;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
options_ssh_shutdown(void)
|
||||
{
|
||||
FREE_CLEAN(itc, elm_genlist_item_class_free);
|
||||
FREE_CLEAN(itc_group, elm_genlist_item_class_free);
|
||||
#ifdef HAVE_AVAHI
|
||||
FREE_CLEAN(sb, avahi_service_browser_free);
|
||||
FREE_CLEAN(client, avahi_client_free);
|
||||
FREE_CLEAN(context, ecore_avahi_del);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef _OPTIONS_SSH_H__
|
||||
#define _OPTIONS_SSH_H__
|
||||
|
||||
typedef struct _SSH_Server SSH_Server;
|
||||
|
||||
void options_ssh_server_add(unsigned char local, const char *domain, const char *name, const char *ip, unsigned int port);
|
||||
void options_ssh_server_data_del(SSH_Server *server);
|
||||
void options_ssh_server_del(unsigned char local, const char *domain, const char *name);
|
||||
void options_genlist_add(Evas_Object *gl);
|
||||
|
||||
void options_ssh_init(void);
|
||||
void options_ssh_shutdown(void);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue