2021-05-23 19:11:39 +00:00
|
|
|
/* radare - LGPL - Copyright 2008-2021 - pancake */
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2021-05-23 19:11:39 +00:00
|
|
|
#include <r_io.h>
|
2017-05-26 00:43:26 +00:00
|
|
|
#include "config.h"
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2020-07-19 16:44:27 +00:00
|
|
|
static volatile RIOPlugin *default_plugin = NULL;
|
2017-05-03 15:19:49 +00:00
|
|
|
|
2016-06-19 22:29:41 +00:00
|
|
|
static RIOPlugin *io_static_plugins[] = {
|
|
|
|
R_IO_STATIC_PLUGINS
|
|
|
|
};
|
2009-08-22 03:11:33 +00:00
|
|
|
|
2016-06-19 22:29:41 +00:00
|
|
|
R_API bool r_io_plugin_add(RIO *io, RIOPlugin *plugin) {
|
2021-05-23 19:11:39 +00:00
|
|
|
r_return_val_if_fail (io && plugin && io->plugins, false);
|
|
|
|
if (!plugin->name) {
|
2015-09-14 00:08:31 +00:00
|
|
|
return false;
|
2016-06-19 22:29:41 +00:00
|
|
|
}
|
2017-05-03 15:19:49 +00:00
|
|
|
ls_append (io->plugins, plugin);
|
2015-09-14 00:08:31 +00:00
|
|
|
return true;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2016-06-19 22:29:41 +00:00
|
|
|
R_API bool r_io_plugin_init(RIO *io) {
|
2010-05-28 00:44:51 +00:00
|
|
|
RIOPlugin *static_plugin;
|
2009-08-22 05:29:58 +00:00
|
|
|
int i;
|
2017-05-03 15:19:49 +00:00
|
|
|
if (!io) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
io->plugins = ls_newf (free);
|
2016-06-19 22:29:41 +00:00
|
|
|
for (i = 0; io_static_plugins[i]; i++) {
|
|
|
|
if (!io_static_plugins[i]->name) {
|
2011-10-08 21:39:06 +00:00
|
|
|
continue;
|
2016-06-19 22:29:41 +00:00
|
|
|
}
|
2017-05-03 15:19:49 +00:00
|
|
|
static_plugin = R_NEW0 (RIOPlugin);
|
2016-06-19 22:29:41 +00:00
|
|
|
if (!static_plugin) {
|
|
|
|
return false;
|
|
|
|
}
|
2010-05-28 00:44:51 +00:00
|
|
|
memcpy (static_plugin, io_static_plugins[i], sizeof (RIOPlugin));
|
2017-05-03 15:19:49 +00:00
|
|
|
r_io_plugin_add (io, static_plugin);
|
2010-05-28 00:44:51 +00:00
|
|
|
}
|
2015-09-14 00:08:31 +00:00
|
|
|
return true;
|
2009-08-22 05:29:58 +00:00
|
|
|
}
|
|
|
|
|
2016-06-19 22:29:41 +00:00
|
|
|
R_API RIOPlugin *r_io_plugin_get_default(RIO *io, const char *filename, bool many) {
|
2020-07-19 16:44:27 +00:00
|
|
|
if (!default_plugin || !default_plugin->check || !default_plugin->check (io, filename, many) ) {
|
2018-01-10 06:43:23 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2020-07-19 16:44:27 +00:00
|
|
|
return (RIOPlugin*) default_plugin;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2016-06-19 22:29:41 +00:00
|
|
|
R_API RIOPlugin *r_io_plugin_resolve(RIO *io, const char *filename, bool many) {
|
2017-05-03 15:19:49 +00:00
|
|
|
SdbListIter *iter;
|
|
|
|
RIOPlugin *ret;
|
|
|
|
ls_foreach (io->plugins, iter, ret) {
|
2017-08-14 00:55:47 +00:00
|
|
|
if (!ret || !ret->check) {
|
2017-05-03 15:19:49 +00:00
|
|
|
continue;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
2018-01-10 06:43:23 +00:00
|
|
|
if (ret->check (io, filename, many)) {
|
2017-05-03 15:19:49 +00:00
|
|
|
return ret;
|
2018-01-10 06:43:23 +00:00
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
2017-05-03 15:19:49 +00:00
|
|
|
return r_io_plugin_get_default (io, filename, many);
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2016-06-20 07:12:44 +00:00
|
|
|
R_API RIOPlugin *r_io_plugin_byname(RIO *io, const char *name) {
|
2017-05-03 15:19:49 +00:00
|
|
|
SdbListIter *iter;
|
2016-06-20 07:12:44 +00:00
|
|
|
RIOPlugin *iop;
|
2017-05-03 15:19:49 +00:00
|
|
|
ls_foreach (io->plugins, iter, iop) {
|
2016-06-20 07:12:44 +00:00
|
|
|
if (!strcmp (name, iop->name)) {
|
|
|
|
return iop;
|
|
|
|
}
|
|
|
|
}
|
2017-05-03 15:19:49 +00:00
|
|
|
return r_io_plugin_get_default (io, name, false);
|
2016-06-20 07:12:44 +00:00
|
|
|
}
|
|
|
|
|
2011-10-08 10:10:30 +00:00
|
|
|
R_API int r_io_plugin_list(RIO *io) {
|
2016-06-19 22:29:41 +00:00
|
|
|
RIOPlugin *plugin;
|
2017-05-03 15:19:49 +00:00
|
|
|
SdbListIter *iter;
|
2016-06-19 22:29:41 +00:00
|
|
|
char str[4];
|
2009-02-05 21:08:46 +00:00
|
|
|
int n = 0;
|
2016-06-19 22:29:41 +00:00
|
|
|
|
2017-05-03 15:19:49 +00:00
|
|
|
ls_foreach (io->plugins, iter, plugin) {
|
2016-06-19 22:29:41 +00:00
|
|
|
str[0] = 'r';
|
|
|
|
str[1] = plugin->write ? 'w' : '_';
|
|
|
|
str[2] = plugin->isdbg ? 'd' : '_';
|
|
|
|
str[3] = 0;
|
2021-05-23 19:11:39 +00:00
|
|
|
io->cb_printf ("%s %-8s %-6s %s.", str,
|
|
|
|
plugin->name, plugin->license, plugin->desc);
|
2019-02-11 09:27:29 +00:00
|
|
|
if (plugin->uris) {
|
|
|
|
io->cb_printf (" %s", plugin->uris);
|
|
|
|
}
|
2017-02-28 01:06:46 +00:00
|
|
|
io->cb_printf ("\n");
|
2009-02-05 21:08:46 +00:00
|
|
|
n++;
|
|
|
|
}
|
|
|
|
return n;
|
|
|
|
}
|
2017-11-04 19:55:26 +00:00
|
|
|
|
|
|
|
R_API int r_io_plugin_list_json(RIO *io) {
|
|
|
|
RIOPlugin *plugin;
|
|
|
|
SdbListIter *iter;
|
2019-02-11 09:27:29 +00:00
|
|
|
PJ *pj = pj_new ();
|
|
|
|
if (!pj) {
|
2019-02-11 11:13:33 +00:00
|
|
|
return 0;
|
2019-02-11 09:27:29 +00:00
|
|
|
}
|
|
|
|
|
2017-11-04 19:55:26 +00:00
|
|
|
char str[4];
|
|
|
|
int n = 0;
|
2019-02-11 09:27:29 +00:00
|
|
|
pj_a (pj);
|
2017-11-04 19:55:26 +00:00
|
|
|
ls_foreach (io->plugins, iter, plugin) {
|
|
|
|
str[0] = 'r';
|
|
|
|
str[1] = plugin->write ? 'w' : '_';
|
|
|
|
str[2] = plugin->isdbg ? 'd' : '_';
|
|
|
|
str[3] = 0;
|
|
|
|
|
2019-02-11 09:27:29 +00:00
|
|
|
pj_o (pj);
|
|
|
|
pj_ks (pj, "permissions", str);
|
|
|
|
pj_ks (pj, "name", plugin->name);
|
|
|
|
pj_ks (pj, "description", plugin->desc);
|
|
|
|
pj_ks (pj, "license", plugin->license);
|
|
|
|
|
|
|
|
if (plugin->uris) {
|
|
|
|
char *uri;
|
|
|
|
char *uris = strdup (plugin->uris);
|
2019-08-28 20:34:16 +00:00
|
|
|
RList *plist = r_str_split_list (uris, ",", 0);
|
2019-02-11 09:27:29 +00:00
|
|
|
RListIter *piter;
|
|
|
|
pj_k (pj, "uris");
|
|
|
|
pj_a (pj);
|
|
|
|
r_list_foreach (plist, piter, uri) {
|
|
|
|
pj_s (pj, uri);
|
|
|
|
}
|
|
|
|
pj_end (pj);
|
|
|
|
r_list_free (plist);
|
|
|
|
free (uris);
|
|
|
|
}
|
2017-11-04 19:55:26 +00:00
|
|
|
if (plugin->version) {
|
2019-02-11 09:27:29 +00:00
|
|
|
pj_ks (pj, "version", plugin->version);
|
2017-11-04 19:55:26 +00:00
|
|
|
}
|
|
|
|
if (plugin->author) {
|
2019-02-11 09:27:29 +00:00
|
|
|
pj_ks (pj, "author", plugin->author);
|
2017-11-04 19:55:26 +00:00
|
|
|
}
|
2019-02-11 09:27:29 +00:00
|
|
|
pj_end (pj);
|
2017-11-04 19:55:26 +00:00
|
|
|
n++;
|
|
|
|
}
|
2019-02-11 09:27:29 +00:00
|
|
|
pj_end (pj);
|
2020-11-09 06:02:25 +00:00
|
|
|
io->cb_printf ("%s", pj_string (pj));
|
2019-02-11 09:27:29 +00:00
|
|
|
pj_free (pj);
|
2017-11-04 19:55:26 +00:00
|
|
|
return n;
|
|
|
|
}
|
2018-05-31 23:46:10 +00:00
|
|
|
|
|
|
|
R_API int r_io_plugin_read(RIODesc *desc, ut8 *buf, int len) {
|
2018-09-21 00:16:54 +00:00
|
|
|
if (!buf || !desc || !desc->plugin || len < 1 || !(desc->perm & R_PERM_R)) {
|
2018-05-31 23:46:10 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (!desc->plugin->read) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return desc->plugin->read (desc->io, desc, buf, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_io_plugin_write(RIODesc *desc, const ut8 *buf, int len) {
|
2018-09-21 00:16:54 +00:00
|
|
|
if (!buf || !desc || !desc->plugin || len < 1 || !(desc->perm & R_PERM_W)) {
|
2018-05-31 23:46:10 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (!desc->plugin->write) {
|
|
|
|
return -1;
|
|
|
|
}
|
2020-10-29 22:46:48 +00:00
|
|
|
const ut64 cur_addr = r_io_desc_seek (desc, 0LL, R_IO_SEEK_CUR);
|
|
|
|
int ret = desc->plugin->write (desc->io, desc, buf, len);
|
|
|
|
REventIOWrite iow = { cur_addr, buf, len };
|
|
|
|
r_event_send (desc->io->event, R_EVENT_IO_WRITE, &iow);
|
|
|
|
return ret;
|
2018-05-31 23:46:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_io_plugin_read_at(RIODesc *desc, ut64 addr, ut8 *buf, int len) {
|
2018-09-08 14:40:09 +00:00
|
|
|
if (r_io_desc_is_chardevice (desc) || (r_io_desc_seek (desc, addr, R_IO_SEEK_SET) == addr)) {
|
2018-05-31 23:46:10 +00:00
|
|
|
return r_io_plugin_read (desc, buf, len);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_io_plugin_write_at(RIODesc *desc, ut64 addr, const ut8 *buf, int len) {
|
2018-09-08 14:40:09 +00:00
|
|
|
if (r_io_desc_is_chardevice (desc) || r_io_desc_seek (desc, addr, R_IO_SEEK_SET) == addr) {
|
2018-05-31 23:46:10 +00:00
|
|
|
return r_io_plugin_write (desc, buf, len);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|