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