mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-11 23:16:05 +00:00
140 lines
3.3 KiB
C
140 lines
3.3 KiB
C
/* radare2 - LGPL - Copyright 2009-2022 - pancake, condret */
|
|
|
|
#include <r_core.h>
|
|
|
|
static char *getFortuneFile(RCore *core, const char *type) {
|
|
char *ft = r_str_newf(R_JOIN_2_PATHS (R2_HOME_FORTUNES, "fortunes.%s"), type);
|
|
char *path = r_str_home (ft);
|
|
free (ft);
|
|
if (path && r_file_exists (path)) {
|
|
return path;
|
|
}
|
|
free (path);
|
|
path = r_str_newf (R_JOIN_3_PATHS ("%s", R2_FORTUNES, "fortunes.%s"),
|
|
r_sys_prefix (NULL), type);
|
|
if (path && r_file_exists (path)) {
|
|
return path;
|
|
}
|
|
free (path);
|
|
return NULL;
|
|
}
|
|
|
|
static bool _push_types(RList *type_list, char *fortune_dir) {
|
|
RList *files = r_sys_dir (fortune_dir);
|
|
if (!files) {
|
|
return false;
|
|
}
|
|
RListIter *iter;
|
|
char *file;
|
|
r_list_foreach (files, iter, file) {
|
|
if (r_str_startswith (file, "fortunes.") && file[9]) {
|
|
r_list_push (type_list, r_str_new (file + 9));
|
|
}
|
|
}
|
|
r_list_free (files);
|
|
return true;
|
|
}
|
|
|
|
R_IPI RList *r_core_fortune_types(void) { // R_API 5.8
|
|
RList *types = r_list_newf (free);
|
|
if (!types) {
|
|
return NULL;
|
|
}
|
|
char *fortune_dir = r_str_newf (R_JOIN_2_PATHS ("%s", R2_FORTUNES), r_sys_prefix (NULL));
|
|
if (!fortune_dir) {
|
|
r_list_free (types);
|
|
return NULL;
|
|
}
|
|
if (!_push_types (types, fortune_dir)) {
|
|
free (fortune_dir);
|
|
r_list_free (types);
|
|
return NULL;
|
|
}
|
|
free (fortune_dir);
|
|
fortune_dir = r_str_home (R2_HOME_FORTUNES);
|
|
if (fortune_dir) {
|
|
_push_types (types, fortune_dir);
|
|
free (fortune_dir);
|
|
}
|
|
return types;
|
|
}
|
|
|
|
R_API void r_core_fortune_list_types(void) {
|
|
RList *types = r_core_fortune_types ();
|
|
char *fts = r_str_list_join (types, "\n");
|
|
r_list_free (types);
|
|
r_cons_println (fts);
|
|
free (fts);
|
|
}
|
|
|
|
R_API void r_core_fortune_list(RCore *core) {
|
|
// TODO: use file.fortunes // can be dangerous in sandbox mode
|
|
const char *types = (char *)r_config_get (core->config, "cfg.fortunes.type");
|
|
RList *ftypes = r_core_fortune_types ();
|
|
if (!ftypes) {
|
|
return;
|
|
}
|
|
RListIter *iter;
|
|
char *fortunes;
|
|
r_list_foreach (ftypes, iter, fortunes) {
|
|
if (strstr (types, fortunes)) {
|
|
char *file = getFortuneFile (core, fortunes);
|
|
char *str = r_file_slurp (file, NULL);
|
|
if (!str) {
|
|
free (file);
|
|
continue;
|
|
}
|
|
r_cons_println (str);
|
|
free (str);
|
|
free (file);
|
|
}
|
|
}
|
|
r_list_free (ftypes);
|
|
}
|
|
|
|
static char *getrandomline(RCore *core) {
|
|
const char *types = (char *)r_config_get (core->config, "cfg.fortunes.type");
|
|
char *line = NULL, *templine;
|
|
RList *ftypes = r_core_fortune_types ();
|
|
if (!ftypes) {
|
|
return NULL;
|
|
}
|
|
RListIter *iter;
|
|
char *fortunes;
|
|
r_list_foreach (ftypes, iter, fortunes) {
|
|
if (strstr (types, fortunes)) {
|
|
int lines = 0;
|
|
char *file = getFortuneFile (core, fortunes);
|
|
if (file) {
|
|
templine = r_file_slurp_random_line_count (file, &lines);
|
|
if (templine && *templine) {
|
|
free (line);
|
|
line = templine;
|
|
}
|
|
free (file);
|
|
}
|
|
}
|
|
}
|
|
r_list_free (ftypes);
|
|
return line;
|
|
}
|
|
|
|
R_API void r_core_fortune_print_random(RCore *core) {
|
|
// TODO: use file.fortunes // can be dangerous in sandbox mode
|
|
char *line = getrandomline (core);
|
|
if (!line) {
|
|
line = getrandomline (core);
|
|
}
|
|
if (R_STR_ISNOTEMPTY (line)) {
|
|
if (r_config_get_b (core->config, "cfg.fortunes.clippy")) {
|
|
r_core_clippy (core, line);
|
|
} else {
|
|
r_cons_printf (" -- %s\n", line);
|
|
}
|
|
if (r_config_get_b (core->config, "cfg.fortunes.tts")) {
|
|
r_sys_tts (line, true);
|
|
}
|
|
free (line);
|
|
}
|
|
}
|