2020-01-12 13:38:54 -08:00
|
|
|
#include "e_system.h"
|
|
|
|
|
2021-04-06 11:25:28 -07:00
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
RFKILL_BLOCK,
|
|
|
|
RFKILL_UNBLOCK,
|
|
|
|
RFKILL_LIST,
|
|
|
|
} RFKill_Action;
|
|
|
|
|
2020-01-12 13:38:54 -08:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
char *dev;
|
|
|
|
Ecore_Event_Handler *handle_del, *handle_data;
|
|
|
|
Ecore_Exe *exe;
|
|
|
|
int id;
|
2021-04-06 11:25:28 -07:00
|
|
|
RFKill_Action act;
|
|
|
|
Eina_Strbuf *list_ret;
|
2020-01-12 13:38:54 -08:00
|
|
|
Eina_Bool doit : 1;
|
|
|
|
} Action;
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_rfkill_dev_verify(const char *dev)
|
|
|
|
{
|
|
|
|
const char *s;
|
|
|
|
|
|
|
|
for (s = dev; *s; s++)
|
|
|
|
{
|
|
|
|
if (!(((*s >= 'a') && (*s <= 'z')) ||
|
|
|
|
((*s >= 'A') && (*s <= 'Z')) ||
|
|
|
|
((*s >= '0') && (*s <= '9')) ||
|
|
|
|
(*s == '-') || (*s == '+') || (*s == ',') || (*s == '.') ||
|
2021-04-06 11:25:28 -07:00
|
|
|
(*s == '/') || (*s == ':') || (*s == '=') || (*s == '@') ||
|
|
|
|
(*s == '_')))
|
2020-01-12 13:38:54 -08:00
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_rfkill_action_free(Action *a)
|
|
|
|
{
|
|
|
|
// a->exe can stay - exe's are auto-freed by ecore on exit
|
|
|
|
// if (a->exe) ecore_exe_free(a->exe);
|
|
|
|
if (a->handle_del) ecore_event_handler_del(a->handle_del);
|
|
|
|
if (a->handle_data) ecore_event_handler_del(a->handle_data);
|
2021-04-06 11:25:28 -07:00
|
|
|
if (a->list_ret) eina_strbuf_free(a->list_ret);
|
2020-01-12 13:38:54 -08:00
|
|
|
free(a->dev);
|
|
|
|
free(a);
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_cb_rfkill_exe_del(void *data, int ev_type EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Action *a = data;
|
|
|
|
Ecore_Exe_Event_Del *ev = event;
|
|
|
|
if (ev->exe != a->exe) return EINA_TRUE;
|
|
|
|
if (a->id >= 0)
|
|
|
|
{
|
|
|
|
if (a->doit)
|
|
|
|
{
|
2021-04-06 11:25:28 -07:00
|
|
|
if (a->act == RFKILL_BLOCK)
|
2020-01-12 13:38:54 -08:00
|
|
|
e_system_inout_command_send("rfkill-block", "%i %s",
|
|
|
|
ev->exit_code, a->dev);
|
2021-04-06 11:25:28 -07:00
|
|
|
else if (a->act == RFKILL_UNBLOCK)
|
2020-01-12 13:38:54 -08:00
|
|
|
e_system_inout_command_send("rfkill-unblock", "%i %s",
|
|
|
|
ev->exit_code, a->dev);
|
|
|
|
_rfkill_action_free(a);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char cmd[1024];
|
|
|
|
|
|
|
|
// a->exe can stay - exe's are auto-freed by ecore on exit
|
|
|
|
// ecore_exe_free(a->exe);
|
|
|
|
a->exe = NULL;
|
2021-04-06 11:25:28 -07:00
|
|
|
if ((a->act == RFKILL_BLOCK) || (a->act == RFKILL_UNBLOCK))
|
|
|
|
{
|
|
|
|
if (snprintf(cmd, sizeof(cmd), "rfkill %s %i",
|
|
|
|
(a->act == RFKILL_BLOCK) ? "block" : "unblock",
|
|
|
|
a->id) < (int)(sizeof(cmd) - 1))
|
|
|
|
{
|
|
|
|
a->doit = EINA_TRUE;
|
|
|
|
a->exe = ecore_exe_pipe_run(cmd,
|
|
|
|
ECORE_EXE_NOT_LEADER |
|
|
|
|
ECORE_EXE_TERM_WITH_PARENT |
|
|
|
|
ECORE_EXE_PIPE_READ |
|
|
|
|
ECORE_EXE_PIPE_WRITE |
|
|
|
|
ECORE_EXE_PIPE_READ_LINE_BUFFERED, NULL);
|
|
|
|
if (!a->exe) _rfkill_action_free(a);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (a->act == RFKILL_LIST)
|
2020-01-12 13:38:54 -08:00
|
|
|
{
|
2021-04-06 11:25:28 -07:00
|
|
|
e_system_inout_command_send("rfkill-list", "-");
|
|
|
|
_rfkill_action_free(a);
|
2020-01-12 13:38:54 -08:00
|
|
|
}
|
|
|
|
else _rfkill_action_free(a);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-04-06 11:25:28 -07:00
|
|
|
if (a->act == RFKILL_BLOCK)
|
2020-01-12 13:38:54 -08:00
|
|
|
e_system_inout_command_send("rfkill-block", "%i %s",
|
|
|
|
123, a->dev);
|
2021-04-06 11:25:28 -07:00
|
|
|
else if (a->act == RFKILL_UNBLOCK)
|
2020-01-12 13:38:54 -08:00
|
|
|
e_system_inout_command_send("rfkill-unblock", "%i %s",
|
|
|
|
123, a->dev);
|
2021-04-06 11:25:28 -07:00
|
|
|
else if (a->act == RFKILL_LIST)
|
|
|
|
{
|
|
|
|
if (a->list_ret)
|
|
|
|
{
|
|
|
|
const char *s = eina_strbuf_string_get(a->list_ret);
|
|
|
|
if (s)
|
|
|
|
e_system_inout_command_send("rfkill-list", "%s", s);
|
|
|
|
else
|
|
|
|
e_system_inout_command_send("rfkill-list", "-");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
e_system_inout_command_send("rfkill-list", "-");
|
|
|
|
_rfkill_action_free(a);
|
|
|
|
}
|
2020-01-12 13:38:54 -08:00
|
|
|
}
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_cb_rfkill_exe_data(void *data, int ev_type EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Action *a = data;
|
|
|
|
Ecore_Exe_Event_Data *ev = event;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (ev->exe != a->exe) return EINA_TRUE;
|
|
|
|
if (a->id >= 0) return EINA_TRUE;
|
|
|
|
for (i = 0; ev->lines[i].line; i++)
|
|
|
|
{
|
|
|
|
int id;
|
2021-04-06 11:25:28 -07:00
|
|
|
char dev[1024], type[1024];
|
2020-01-12 13:38:54 -08:00
|
|
|
|
|
|
|
id = -1;
|
2021-04-06 11:25:28 -07:00
|
|
|
if (sscanf(ev->lines[i].line, "%i: %1023[^:]: %1023[^\n]", &id, dev, type) == 3)
|
2020-01-12 13:38:54 -08:00
|
|
|
{
|
2021-04-06 11:25:28 -07:00
|
|
|
if ((a->act == RFKILL_BLOCK) || (a->act == RFKILL_UNBLOCK))
|
|
|
|
{
|
|
|
|
if (!strcmp(a->dev, dev))
|
|
|
|
{
|
|
|
|
a->id = id;
|
|
|
|
// wait for exit to spawn rfkill again...
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2020-01-12 13:38:54 -08:00
|
|
|
{
|
2021-04-06 11:25:28 -07:00
|
|
|
if (!a->list_ret) a->list_ret = eina_strbuf_new();
|
|
|
|
if (a->list_ret)
|
|
|
|
eina_strbuf_append_printf(a->list_ret, "%s\t%s\n",
|
|
|
|
dev, type);
|
2020-01-12 13:38:54 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2021-04-06 11:25:28 -07:00
|
|
|
_rfkill_do(RFKill_Action act, const char *dev)
|
2020-01-12 13:38:54 -08:00
|
|
|
{
|
|
|
|
Action *a = calloc(1, sizeof(Action));
|
|
|
|
if (!a) return;
|
|
|
|
a->dev = strdup(dev);
|
|
|
|
if (!a->dev) goto err;
|
|
|
|
a->id = -1;
|
2021-04-06 11:25:28 -07:00
|
|
|
a->act = act;
|
2020-01-12 13:38:54 -08:00
|
|
|
a->handle_del = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
|
|
|
|
_cb_rfkill_exe_del, a);
|
|
|
|
a->handle_data = ecore_event_handler_add(ECORE_EXE_EVENT_DATA,
|
|
|
|
_cb_rfkill_exe_data, a);
|
|
|
|
if ((!a->handle_del) || (!a->handle_data)) goto err;
|
|
|
|
// stage 1 - run to get list of devices and id's to know what id to use
|
2020-04-15 07:30:18 -07:00
|
|
|
a->exe = ecore_exe_pipe_run("rfkill list",
|
2020-01-12 13:38:54 -08:00
|
|
|
ECORE_EXE_NOT_LEADER |
|
|
|
|
ECORE_EXE_TERM_WITH_PARENT |
|
|
|
|
ECORE_EXE_PIPE_READ |
|
|
|
|
ECORE_EXE_PIPE_WRITE |
|
|
|
|
ECORE_EXE_PIPE_READ_LINE_BUFFERED, NULL);
|
|
|
|
if (!a->exe) goto err;
|
|
|
|
return;
|
|
|
|
err:
|
|
|
|
ERR("Can't run rfkill\n");
|
|
|
|
_rfkill_action_free(a);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cb_rfkill_block(void *data EINA_UNUSED, const char *params)
|
|
|
|
{
|
|
|
|
if (!_rfkill_dev_verify(params)) return;
|
2021-04-06 11:25:28 -07:00
|
|
|
_rfkill_do(RFKILL_BLOCK, params);
|
2020-01-12 13:38:54 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cb_rfkill_unblock(void *data EINA_UNUSED, const char *params)
|
|
|
|
{
|
|
|
|
if (!_rfkill_dev_verify(params)) return;
|
2021-04-06 11:25:28 -07:00
|
|
|
_rfkill_do(RFKILL_UNBLOCK, params);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cb_rfkill_list(void *data EINA_UNUSED, const char *params EINA_UNUSED)
|
|
|
|
{
|
|
|
|
_rfkill_do(RFKILL_LIST, "");
|
2020-01-12 13:38:54 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
e_system_rfkill_init(void)
|
|
|
|
{
|
|
|
|
e_system_inout_command_register("rfkill-block", _cb_rfkill_block, NULL);
|
|
|
|
e_system_inout_command_register("rfkill-unblock", _cb_rfkill_unblock, NULL);
|
2021-04-06 11:25:28 -07:00
|
|
|
e_system_inout_command_register("rfkill-list", _cb_rfkill_list, NULL);
|
2020-01-12 13:38:54 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
e_system_rfkill_shutdown(void)
|
|
|
|
{
|
|
|
|
// only shutdown things we really have to - no need to free mem etc.
|
|
|
|
}
|