1 /* radare - LGPL - Copyright 2008-2018 - pancake */
2 
3 #include "r_io.h"
4 #include "config.h"
5 #include <stdio.h>
6 
7 static volatile RIOPlugin *default_plugin = NULL;
8 
9 static RIOPlugin *io_static_plugins[] = {
10 	R_IO_STATIC_PLUGINS
11 };
12 
r_io_plugin_add(RIO * io,RIOPlugin * plugin)13 R_API bool r_io_plugin_add(RIO *io, RIOPlugin *plugin) {
14 	if (!io || !io->plugins || !plugin || !plugin->name) {
15 		return false;
16 	}
17 	ls_append (io->plugins, plugin);
18 	return true;
19 }
20 
r_io_plugin_init(RIO * io)21 R_API bool r_io_plugin_init(RIO *io) {
22 	RIOPlugin *static_plugin;
23 	int i;
24 	if (!io) {
25 		return false;
26 	}
27 	io->plugins = ls_newf (free);
28 	for (i = 0; io_static_plugins[i]; i++) {
29 		if (!io_static_plugins[i]->name) {
30 			continue;
31 		}
32 		static_plugin = R_NEW0 (RIOPlugin);
33 		if (!static_plugin) {
34 			return false;
35 		}
36 		memcpy (static_plugin, io_static_plugins[i], sizeof (RIOPlugin));
37 		r_io_plugin_add (io, static_plugin);
38 	}
39 	return true;
40 }
41 
r_io_plugin_get_default(RIO * io,const char * filename,bool many)42 R_API RIOPlugin *r_io_plugin_get_default(RIO *io, const char *filename, bool many) {
43 	if (!default_plugin || !default_plugin->check || !default_plugin->check (io, filename, many) ) {
44 		return NULL;
45 	}
46 	return (RIOPlugin*) default_plugin;
47 }
48 
r_io_plugin_resolve(RIO * io,const char * filename,bool many)49 R_API RIOPlugin *r_io_plugin_resolve(RIO *io, const char *filename, bool many) {
50 	SdbListIter *iter;
51 	RIOPlugin *ret;
52 	ls_foreach (io->plugins, iter, ret) {
53 		if (!ret || !ret->check) {
54 			continue;
55 		}
56 		if (ret->check (io, filename, many)) {
57 			return ret;
58 		}
59 	}
60 	return r_io_plugin_get_default (io, filename, many);
61 }
62 
r_io_plugin_byname(RIO * io,const char * name)63 R_API RIOPlugin *r_io_plugin_byname(RIO *io, const char *name) {
64 	SdbListIter *iter;
65 	RIOPlugin *iop;
66 	ls_foreach (io->plugins, iter, iop) {
67 		if (!strcmp (name, iop->name)) {
68 			return iop;
69 		}
70 	}
71 	return r_io_plugin_get_default (io, name, false);
72 }
73 
r_io_plugin_list(RIO * io)74 R_API int r_io_plugin_list(RIO *io) {
75 	RIOPlugin *plugin;
76 	SdbListIter *iter;
77 	char str[4];
78 	int n = 0;
79 
80 	ls_foreach (io->plugins, iter, plugin) {
81 		str[0] = 'r';
82 		str[1] = plugin->write ? 'w' : '_';
83 		str[2] = plugin->isdbg ? 'd' : '_';
84 		str[3] = 0;
85 		io->cb_printf ("%s  %-8s %s (%s)",
86 				str, plugin->name,
87 			plugin->desc, plugin->license);
88 		if (plugin->uris) {
89 			io->cb_printf (" %s", plugin->uris);
90 		}
91 		if (plugin->version) {
92 			io->cb_printf (" v%s", plugin->version);
93 		}
94 		if (plugin->author) {
95 			io->cb_printf (" %s", plugin->author);
96 		}
97 		io->cb_printf ("\n");
98 		n++;
99 	}
100 	return n;
101 }
102 
r_io_plugin_list_json(RIO * io)103 R_API int r_io_plugin_list_json(RIO *io) {
104 	RIOPlugin *plugin;
105 	SdbListIter *iter;
106 	PJ *pj = pj_new ();
107 	if (!pj) {
108 		return 0;
109 	}
110 
111 	char str[4];
112 	int n = 0;
113 	pj_o (pj);
114 	pj_k (pj, "io_plugins");
115 	pj_a (pj);
116 	ls_foreach (io->plugins, iter, plugin) {
117 		str[0] = 'r';
118 		str[1] = plugin->write ? 'w' : '_';
119 		str[2] = plugin->isdbg ? 'd' : '_';
120 		str[3] = 0;
121 
122 		pj_o (pj);
123 		pj_ks (pj, "permissions", str);
124 		pj_ks (pj, "name", plugin->name);
125 		pj_ks (pj, "description", plugin->desc);
126 		pj_ks (pj, "license", plugin->license);
127 
128 		if (plugin->uris) {
129 			char *uri;
130 			char *uris = strdup (plugin->uris);
131 			RList *plist = r_str_split_list (uris, ",",  0);
132 			RListIter *piter;
133 			pj_k (pj, "uris");
134 			pj_a (pj);
135 			r_list_foreach (plist, piter, uri) {
136 				pj_s (pj, uri);
137 			}
138 			pj_end (pj);
139 			r_list_free (plist);
140 			free (uris);
141 		}
142 		if (plugin->version) {
143 			pj_ks (pj, "version", plugin->version);
144 		}
145 		if (plugin->author) {
146 			pj_ks (pj, "author", plugin->author);
147 		}
148 		pj_end (pj);
149 		n++;
150 	}
151 	pj_end (pj);
152 	pj_end (pj);
153 	io->cb_printf ("%s", pj_string (pj));
154 	pj_free (pj);
155 	return n;
156 }
157 
r_io_plugin_read(RIODesc * desc,ut8 * buf,int len)158 R_API int r_io_plugin_read(RIODesc *desc, ut8 *buf, int len) {
159 	if (!buf || !desc || !desc->plugin || len < 1 || !(desc->perm & R_PERM_R)) {
160 		return 0;
161 	}
162 	if (!desc->plugin->read) {
163 		return -1;
164 	}
165 	return desc->plugin->read (desc->io, desc, buf, len);
166 }
167 
r_io_plugin_write(RIODesc * desc,const ut8 * buf,int len)168 R_API int r_io_plugin_write(RIODesc *desc, const ut8 *buf, int len) {
169 	if (!buf || !desc || !desc->plugin || len < 1 || !(desc->perm & R_PERM_W)) {
170 		return 0;
171 	}
172 	if (!desc->plugin->write) {
173 		return -1;
174 	}
175 	const ut64 cur_addr = r_io_desc_seek (desc, 0LL, R_IO_SEEK_CUR);
176 	int ret = desc->plugin->write (desc->io, desc, buf, len);
177 	REventIOWrite iow = { cur_addr, buf, len };
178 	r_event_send (desc->io->event, R_EVENT_IO_WRITE, &iow);
179 	return ret;
180 }
181 
r_io_plugin_read_at(RIODesc * desc,ut64 addr,ut8 * buf,int len)182 R_API int r_io_plugin_read_at(RIODesc *desc, ut64 addr, ut8 *buf, int len) {
183 	if (r_io_desc_is_chardevice (desc) || (r_io_desc_seek (desc, addr, R_IO_SEEK_SET) == addr)) {
184 		return r_io_plugin_read (desc, buf, len);
185 	}
186 	return 0;
187 }
188 
r_io_plugin_write_at(RIODesc * desc,ut64 addr,const ut8 * buf,int len)189 R_API int r_io_plugin_write_at(RIODesc *desc, ut64 addr, const ut8 *buf, int len) {
190 	if (r_io_desc_is_chardevice (desc) || r_io_desc_seek (desc, addr, R_IO_SEEK_SET)  == addr) {
191 		return r_io_plugin_write (desc, buf, len);
192 	}
193 	return 0;
194 }
195