Skip to content

Commit bd2f3bf

Browse files
committed
WIP: Suggest to setup the r2pm bindir in PATH
1 parent 740543f commit bd2f3bf

2 files changed

Lines changed: 170 additions & 3 deletions

File tree

libr/main/r2pm.c

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#endif
1313

1414
static int r2pm_install(RList *targets, bool uninstall, bool clean, bool force, bool global);
15+
static bool r2pm_bindir_in_path = false;
1516

1617
static const char *helpmsg =
1718
"Usage: r2pm [-flags] [pkgs...]\n"
@@ -203,6 +204,139 @@ static char *r2pm_dbdir(void) {
203204
return res;
204205
}
205206

207+
static bool path_has_dir(const char *path, const char *dir) {
208+
char *ptr, *path_copy, *entry;
209+
if (R_STR_ISEMPTY (path) || R_STR_ISEMPTY (dir)) {
210+
return false;
211+
}
212+
path_copy = strdup (path);
213+
if (!path_copy) {
214+
return false;
215+
}
216+
entry = path_copy;
217+
do {
218+
ptr = strchr (entry, R_SYS_ENVSEP[0]);
219+
if (ptr) {
220+
*ptr = '\0';
221+
}
222+
if (!strcmp (entry, dir)) {
223+
free (path_copy);
224+
return true;
225+
}
226+
if (ptr) {
227+
entry = ptr + 1;
228+
}
229+
} while (ptr);
230+
free (path_copy);
231+
return false;
232+
}
233+
234+
static const char *r2pm_shellrc_name(void) {
235+
char *shell = r_sys_getenv ("SHELL");
236+
const char *res = ".profile";
237+
if (R_STR_ISNOTEMPTY (shell)) {
238+
const char *shell_name = r_str_lchr (shell, '/');
239+
shell_name = shell_name? shell_name + 1: shell;
240+
if (!strcmp (shell_name, "bash")) {
241+
res = ".bashrc";
242+
} else if (!strcmp (shell_name, "zsh")) {
243+
res = ".zshrc";
244+
}
245+
}
246+
free (shell);
247+
return res;
248+
}
249+
250+
static void r2pm_suggest_bindir_in_shellrc(void) {
251+
char *bindir = r_sys_getenv ("R2PM_BINDIR");
252+
const char *shellrc;
253+
if (R_STR_ISEMPTY (bindir)) {
254+
free (bindir);
255+
return;
256+
}
257+
shellrc = r2pm_shellrc_name ();
258+
R_LOG_INFO ("Your shell PATH does not include %s", bindir);
259+
R_LOG_INFO ("Add it to ~/%s with:", shellrc);
260+
R_LOG_INFO (" printf '\\nexport PATH=\"$PATH:%s\"\\n' >> ~/%s", bindir, shellrc);
261+
free (bindir);
262+
}
263+
264+
static bool list_has_string(RList *list, const char *name) {
265+
RListIter *iter;
266+
const char *entry;
267+
if (!list || !name) {
268+
return false;
269+
}
270+
r_list_foreach (list, iter, entry) {
271+
if (!strcmp (entry, name)) {
272+
return true;
273+
}
274+
}
275+
return false;
276+
}
277+
278+
static RList *r2pm_bindir_snapshot(void) {
279+
char *bindir = r_sys_getenv ("R2PM_BINDIR");
280+
if (R_STR_ISEMPTY (bindir)) {
281+
free (bindir);
282+
return NULL;
283+
}
284+
RList *files = r_sys_dir (bindir);
285+
free (bindir);
286+
return files;
287+
}
288+
289+
static RList *r2pm_bindir_new_files(RList *before, RList *after) {
290+
RListIter *iter;
291+
const char *file;
292+
RList *res = r_list_newf (free);
293+
if (!res || !after) {
294+
r_list_free (res);
295+
return NULL;
296+
}
297+
r_list_foreach (after, iter, file) {
298+
if (*file == '.') {
299+
continue;
300+
}
301+
if (!list_has_string (before, file)) {
302+
r_list_append (res, strdup (file));
303+
}
304+
}
305+
return res;
306+
}
307+
308+
static void r2pm_report_new_bindir_files(const char *pkg, RList *new_files) {
309+
RListIter *iter;
310+
const char *file;
311+
char *bindir = r_sys_getenv ("R2PM_BINDIR");
312+
RStrBuf *sb;
313+
char *files;
314+
if (R_STR_ISEMPTY (bindir) || !new_files || r_list_empty (new_files)) {
315+
free (bindir);
316+
return;
317+
}
318+
sb = r_strbuf_new ("");
319+
if (!sb) {
320+
free (bindir);
321+
return;
322+
}
323+
r_list_foreach (new_files, iter, file) {
324+
if (!r_strbuf_length (sb)) {
325+
r_strbuf_appendf (sb, "%s", file);
326+
} else {
327+
r_strbuf_appendf (sb, ", %s", file);
328+
}
329+
}
330+
files = r_strbuf_drain (sb);
331+
R_LOG_INFO ("New files in %s after installing %s: %s", bindir, pkg, files);
332+
R_LOG_INFO ("Run them from your shell with 'r2pm -r <programname>'");
333+
if (!r2pm_bindir_in_path) {
334+
r2pm_suggest_bindir_in_shellrc ();
335+
}
336+
free (files);
337+
free (bindir);
338+
}
339+
206340
static char *r2pm_pkgdir(void) {
207341
return r_xdg_datadir ("r2pm/pkg");
208342
}
@@ -562,6 +696,9 @@ static void r2pm_setenv(R2Pm *r2pm) {
562696
free (pkgcfg);
563697

564698
char *r2pm_bindir = r_str_newf ("%s/bin", r2_prefix);
699+
char *path = r_sys_getenv ("PATH");
700+
r2pm_bindir_in_path = path_has_dir (path, r2pm_bindir);
701+
free (path);
565702
r_sys_mkdirp (r2pm_bindir);
566703
r_sys_setenv ("R2PM_BINDIR", r2pm_bindir);
567704
r_sys_setenv_sep ("PATH", r2pm_bindir, false);
@@ -940,6 +1077,7 @@ static int r2pm_install_pkg(const char *pkg, bool clean, bool global) {
9401077
}
9411078
char *srcdir = r2pm_gitdir ();
9421079
R_LOG_DEBUG ("Entering %s", srcdir);
1080+
RList *bindir_before = r2pm_bindir_snapshot ();
9431081
char *qjs_script = r2pm_get (pkg, "\nR2PM_INSTALL_QJS() {\n", TT_CODEBLOCK);
9441082
if (qjs_script) {
9451083
int res = 0;
@@ -950,6 +1088,9 @@ static int r2pm_install_pkg(const char *pkg, bool clean, bool global) {
9501088
int child = fork ();
9511089
if (child == -1) {
9521090
R_LOG_ERROR ("Cannot find radare2 in PATH");
1091+
free (qjs_script);
1092+
r_list_free (bindir_before);
1093+
free (srcdir);
9531094
return -1;
9541095
}
9551096
if (child) {
@@ -963,15 +1104,24 @@ static int r2pm_install_pkg(const char *pkg, bool clean, bool global) {
9631104
R_LOG_WARN ("r2pm.qjs support is experimental");
9641105
res = 1;
9651106
#endif
1107+
if (res == 0) {
1108+
RList *bindir_after = r2pm_bindir_snapshot ();
1109+
RList *new_files = r2pm_bindir_new_files (bindir_before, bindir_after);
1110+
r2pm_report_new_bindir_files (pkg, new_files);
1111+
r_list_free (new_files);
1112+
r_list_free (bindir_after);
1113+
}
9661114
// run script!
9671115
free (qjs_script);
1116+
r_list_free (bindir_before);
9681117
free (srcdir);
9691118
return res;
9701119
}
9711120
#if R2__WINDOWS__
9721121
char *script = r2pm_get (pkg, "\nR2PM_INSTALL_WINDOWS() {\n", TT_CODEBLOCK);
9731122
if (!script) {
9741123
R_LOG_ERROR ("This package does not have R2PM_INSTALL_WINDOWS instructions");
1124+
r_list_free (bindir_before);
9751125
return 1;
9761126
}
9771127
script = r_str_replace_all (script, "\r\n", " & ");
@@ -985,10 +1135,20 @@ static int r2pm_install_pkg(const char *pkg, bool clean, bool global) {
9851135
}
9861136
int res = r_sandbox_system (s, 1);
9871137
free (s);
1138+
if (res == 0) {
1139+
r2pm_register (pkg, global);
1140+
RList *bindir_after = r2pm_bindir_snapshot ();
1141+
RList *new_files = r2pm_bindir_new_files (bindir_before, bindir_after);
1142+
r2pm_report_new_bindir_files (pkg, new_files);
1143+
r_list_free (new_files);
1144+
r_list_free (bindir_after);
1145+
}
1146+
r_list_free (bindir_before);
9881147
#else
9891148
char *script = r2pm_get (pkg, "\nR2PM_INSTALL() {\n", TT_CODEBLOCK);
9901149
if (!script) {
9911150
R_LOG_ERROR ("Cannot find '%s' package or missing R2PM_INSTALL block", pkg);
1151+
r_list_free (bindir_before);
9921152
free (srcdir);
9931153
return 1;
9941154
}
@@ -1004,6 +1164,7 @@ static int r2pm_install_pkg(const char *pkg, bool clean, bool global) {
10041164
if (have_builddir && !r_file_is_directory (pkgdir)) {
10051165
R_LOG_ERROR ("Cannot find directory: %s", pkgdir);
10061166
free (pkgdir);
1167+
r_list_free (bindir_before);
10071168
return 1;
10081169
}
10091170
char *s = have_builddir
@@ -1015,7 +1176,13 @@ static int r2pm_install_pkg(const char *pkg, bool clean, bool global) {
10151176
free (s);
10161177
if (res == 0) {
10171178
r2pm_register (pkg, global);
1179+
RList *bindir_after = r2pm_bindir_snapshot ();
1180+
RList *new_files = r2pm_bindir_new_files (bindir_before, bindir_after);
1181+
r2pm_report_new_bindir_files (pkg, new_files);
1182+
r_list_free (new_files);
1183+
r_list_free (bindir_after);
10181184
}
1185+
r_list_free (bindir_before);
10191186
#endif
10201187
free (script);
10211188
free (srcdir);

test/fuzz/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@
22

33
## Setup
44

5-
Get libFuzzer-capable clang
5+
In macOS:
66

77
```shell
8+
brew install llvm@22 meson ninja
89
eval $(make env)
9-
make setup
10+
make b
1011
```
1112

1213
Running with the provided Makefile
1314

1415
```shell
1516
cd test/fuzz
16-
make setup
1717
make build
1818
make run-fuzzer T=fuzz_types_parser
1919
```

0 commit comments

Comments
 (0)