1 /* radare - LGPL - Copyright 2009-2021 - pancake */
2
3 #include "r_core.h"
4 #include "config.h"
5
6 #define CB(x, y)\
7 static int __lib_ ## x ## _cb (RLibPlugin * pl, void *user, void *data) {\
8 struct r_ ## x ## _plugin_t *hand = (struct r_ ## x ## _plugin_t *)data;\
9 RCore *core = (RCore *) user;\
10 pl->free = NULL; \
11 r_ ## x ## _add (core->y, hand);\
12 return true;\
13 }\
14 static int __lib_ ## x ## _dt (RLibPlugin * pl, void *p, void *u) { return true; }
15
16 // TODO: deprecate this
17 #define CB_COPY(x, y)\
18 static int __lib_ ## x ## _cb (RLibPlugin * pl, void *user, void *data) {\
19 struct r_ ## x ## _plugin_t *hand = (struct r_ ## x ## _plugin_t *)data;\
20 struct r_ ## x ## _plugin_t *instance;\
21 RCore *core = (RCore *) user;\
22 instance = R_NEW (struct r_ ## x ## _plugin_t);\
23 memcpy (instance, hand, sizeof (struct r_ ## x ## _plugin_t));\
24 r_ ## x ## _add (core->y, instance);\
25 return true;\
26 }\
27 static int __lib_ ## x ## _dt (RLibPlugin * pl, void *p, void *u) { return true; }
28
29 // XXX api consistency issues
30 #define r_io_add r_io_plugin_add
CB_COPY(io,io)31 CB_COPY (io, io)
32 #define r_core_add r_core_plugin_add
33 CB (core, rcmd)
34 #define r_debug_add r_debug_plugin_add
35 CB (debug, dbg)
36 #define r_bp_add r_bp_plugin_add
37 CB (bp, dbg->bp)
38 CB (lang, lang)
39 CB (anal, anal)
40 CB (anal_esil, anal)
41 CB (asm, rasm)
42 CB (parse, parser)
43 CB (bin, bin)
44 CB (egg, egg)
45 CB (fs, fs)
46
47 static void __openPluginsAt(RCore *core, const char *arg, const char *user_path) {
48 if (arg && *arg) {
49 if (user_path) {
50 if (r_str_endswith (user_path, arg)) {
51 return;
52 }
53 }
54 char *pdir = r_str_r2_prefix (arg);
55 if (pdir) {
56 r_lib_opendir (core->lib, pdir);
57 free (pdir);
58 }
59 }
60 }
61
__loadSystemPlugins(RCore * core,int where,const char * path)62 static void __loadSystemPlugins(RCore *core, int where, const char *path) {
63 #if R2_LOADLIBS
64 if (!where) {
65 where = -1;
66 }
67 if (path) {
68 r_lib_opendir (core->lib, path);
69 }
70 const char *dir_plugins = r_config_get (core->config, "dir.plugins");
71 if (where & R_CORE_LOADLIBS_CONFIG) {
72 r_lib_opendir (core->lib, dir_plugins);
73 }
74 if (where & R_CORE_LOADLIBS_ENV) {
75 char *p = r_sys_getenv (R_LIB_ENV);
76 if (p && *p) {
77 r_lib_opendir (core->lib, p);
78 }
79 free (p);
80 }
81 if (where & R_CORE_LOADLIBS_HOME) {
82 char *hpd = r_str_home (R2_HOME_PLUGINS);
83 if (hpd) {
84 r_lib_opendir (core->lib, hpd);
85 free (hpd);
86 }
87 }
88 if (where & R_CORE_LOADLIBS_SYSTEM) {
89 __openPluginsAt (core, R2_PLUGINS, dir_plugins);
90 __openPluginsAt (core, R2_EXTRAS, dir_plugins);
91 __openPluginsAt (core, R2_BINDINGS, dir_plugins);
92 }
93 #endif
94 }
95
r_core_loadlibs_init(RCore * core)96 R_API void r_core_loadlibs_init(RCore *core) {
97 ut64 prev = r_time_now_mono ();
98 #define DF(x, y, z) r_lib_add_handler (core->lib, R_LIB_TYPE_ ## x, y, &__lib_ ## z ## _cb, &__lib_ ## z ## _dt, core);
99 core->lib = r_lib_new (NULL, NULL);
100 DF (IO, "io plugins", io);
101 DF (CORE, "core plugins", core);
102 DF (DBG, "debugger plugins", debug);
103 DF (BP, "debugger breakpoint plugins", bp);
104 DF (LANG, "language plugins", lang);
105 DF (ANAL, "analysis plugins", anal);
106 DF (ESIL, "esil emulation plugins", anal_esil);
107 DF (ASM, "(dis)assembler plugins", asm);
108 DF (PARSE, "parsing plugins", parse);
109 DF (BIN, "bin plugins", bin);
110 DF (EGG, "egg plugins", egg);
111 DF (FS, "fs plugins", fs);
112 core->times->loadlibs_init_time = r_time_now_mono () - prev;
113 }
114
__isScriptFilename(const char * name)115 static bool __isScriptFilename(const char *name) {
116 const char *ext = r_str_lchr (name, '.');
117 if (ext) {
118 ext++;
119 if (!strcmp (ext, "py")
120 || !strcmp (ext, "js")
121 || !strcmp (ext, "v")
122 || !strcmp (ext, "c")
123 || !strcmp (ext, "vala")
124 || !strcmp (ext, "pl")
125 || !strcmp (ext, "lua")) {
126 return true;
127 }
128 }
129 return false;
130 }
131
r_core_loadlibs(RCore * core,int where,const char * path)132 R_API bool r_core_loadlibs(RCore *core, int where, const char *path) {
133 ut64 prev = r_time_now_mono ();
134 __loadSystemPlugins (core, where, path);
135 /* TODO: all those default plugin paths should be defined in r_lib */
136 if (!r_config_get_i (core->config, "cfg.plugins")) {
137 core->times->loadlibs_time = 0;
138 return false;
139 }
140 // load script plugins
141 char *homeplugindir = r_str_home (R2_HOME_PLUGINS);
142 RList *files = r_sys_dir (homeplugindir);
143 RListIter *iter;
144 char *file;
145 r_list_foreach (files, iter, file) {
146 if (__isScriptFilename (file)) {
147 r_core_cmdf (core, "\". %s/%s\"", homeplugindir, file);
148 }
149 }
150 r_list_free (files);
151 free (homeplugindir);
152 core->times->loadlibs_time = r_time_now_mono () - prev;
153 return true;
154 }
155