mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-26 00:55:59 +00:00
Fix #14335 - Add sort, join and uniq ##core
This commit is contained in:
parent
94746b2f41
commit
2da973ed24
@ -353,6 +353,34 @@ static int r_core_cmd_nullcallback(void *data) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cmd_uniq(void *data, const char *input) { // "uniq"
|
||||
RCore *core = (RCore *)data;
|
||||
const char *arg = strchr (input, ' ');
|
||||
if (arg) {
|
||||
arg = r_str_trim_ro (arg + 1);
|
||||
}
|
||||
switch (*input) {
|
||||
case '?': // "uniq?"
|
||||
eprintf ("Usage: uniq # uniq to list unique strings in file\n");
|
||||
break;
|
||||
default: // "uniq"
|
||||
if (!arg) {
|
||||
arg = "";
|
||||
}
|
||||
if (r_fs_check (core->fs, arg)) {
|
||||
r_core_cmdf (core, "md %s", arg);
|
||||
} else {
|
||||
char *res = r_syscmd_uniq (arg);
|
||||
if (res) {
|
||||
r_cons_print (res);
|
||||
free (res);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_uname(void *data, const char *input) {
|
||||
RCore *core = (RCore *)data;
|
||||
switch (input[0]) {
|
||||
@ -406,6 +434,11 @@ static int cmd_uname(void *data, const char *input) {
|
||||
case 'w': // "uw"
|
||||
r_core_cmdf (data, "wc%s", input + 1);
|
||||
return 1;
|
||||
case 'n': // "un"
|
||||
if (input[1] == 'i' && input[2] == 'q') {
|
||||
cmd_uniq (core, input);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#if __UNIX__
|
||||
struct utsname un;
|
||||
@ -962,6 +995,50 @@ static int cmd_ls(void *data, const char *input) { // "ls"
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_join(void *data, const char *input) { // "join"
|
||||
RCore *core = (RCore *)data;
|
||||
const char *tmp = strdup (input);
|
||||
const char *arg1 = strchr (tmp, ' ');
|
||||
if (!arg1) {
|
||||
goto beach;
|
||||
}
|
||||
arg1 = r_str_trim_ro (arg1);
|
||||
char *end = strchr (arg1, ' ');
|
||||
if (!end) {
|
||||
goto beach;
|
||||
}
|
||||
*end = '\0';
|
||||
const char *arg2 = end+1;
|
||||
if (!arg2) {
|
||||
goto beach;
|
||||
}
|
||||
arg2 = r_str_trim_ro (arg2);
|
||||
switch (*input) {
|
||||
case '?': // "join?"
|
||||
goto beach;
|
||||
default: // "join"
|
||||
if (!arg1) {
|
||||
arg1 = "";
|
||||
}
|
||||
if (!arg2) {
|
||||
arg2 = "";
|
||||
}
|
||||
if (!r_fs_check (core->fs, arg1) && !r_fs_check (core->fs, arg2)) {
|
||||
char *res = r_syscmd_join (arg1, arg2);
|
||||
if (res) {
|
||||
r_cons_print (res);
|
||||
free (res);
|
||||
}
|
||||
R_FREE (tmp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
beach:
|
||||
eprintf ("Usage: join [file1] [file2] # join the contents of the two files\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_stdin(void *data, const char *input) {
|
||||
RCore *core = (RCore *)data;
|
||||
if (input[0] == '?') {
|
||||
@ -4517,6 +4594,7 @@ R_API void r_core_cmd_init(RCore *core) {
|
||||
{"info", "get file info", cmd_info, cmd_info_init},
|
||||
{"kuery", "perform sdb query", cmd_kuery},
|
||||
{"l", "list files and directories", cmd_ls},
|
||||
{"join", "join the contents of the two files", cmd_join},
|
||||
{"L", "manage dynamically loaded plugins", cmd_plugins},
|
||||
{"mount", "mount filesystem", cmd_mount, cmd_mount_init},
|
||||
{"open", "open or map file", cmd_open, cmd_open_init},
|
||||
|
@ -1117,7 +1117,7 @@ rep:
|
||||
free (arg);
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
case 'C': // "fC"
|
||||
if (input[1] == ' ') {
|
||||
RFlagItem *item;
|
||||
char *q, *p = strdup (input + 2), *dec = NULL;
|
||||
|
@ -216,6 +216,34 @@ static void seek_to_register(RCore *core, const char *input, bool is_silent) {
|
||||
}
|
||||
}
|
||||
|
||||
static int cmd_sort(void *data, const char *input) { // "sort"
|
||||
RCore *core = (RCore *)data;
|
||||
const char *arg = strchr (input, ' ');
|
||||
if (arg) {
|
||||
arg = r_str_trim_ro (arg + 1);
|
||||
}
|
||||
switch (*input) {
|
||||
case '?': // "sort?"
|
||||
eprintf ("Usage: sort # sort the contents of the file\n");
|
||||
break;
|
||||
default: // "ls"
|
||||
if (!arg) {
|
||||
arg = "";
|
||||
}
|
||||
if (r_fs_check (core->fs, arg)) {
|
||||
r_core_cmdf (core, "md %s", arg);
|
||||
} else {
|
||||
char *res = r_syscmd_sort (arg);
|
||||
if (res) {
|
||||
r_cons_print (res);
|
||||
free (res);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_seek_opcode_backward(RCore *core, int numinstr) {
|
||||
int i, val = 0;
|
||||
// N previous instructions
|
||||
@ -307,7 +335,7 @@ static int cmd_seek(void *data, const char *input) {
|
||||
free (dup);
|
||||
}
|
||||
const char *inputnum = strchr (input, ' ');
|
||||
{
|
||||
if (r_str_cmp (input, "ort", 3)) { // hack to handle Invalid Argument for sort
|
||||
const char *u_num = inputnum? inputnum + 1: input + 1;
|
||||
off = r_num_math (core->num, u_num);
|
||||
if (*u_num == '-') {
|
||||
@ -710,7 +738,23 @@ static int cmd_seek(void *data, const char *input) {
|
||||
break;
|
||||
}
|
||||
case 'o': // "so"
|
||||
cmd_seek_opcode (core, input + 1);
|
||||
switch (input[1]) {
|
||||
case 'r':
|
||||
if (input[2] == 't') {
|
||||
cmd_sort (core, input);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case ' ':
|
||||
case '\0':
|
||||
case '+':
|
||||
case '-':
|
||||
cmd_seek_opcode (core, input + 1);
|
||||
break;
|
||||
default:
|
||||
return -1; // invalid command
|
||||
}
|
||||
break;
|
||||
case 'g': // "sg"
|
||||
{
|
||||
|
@ -830,7 +830,7 @@ R_API RCore *r_core_new() {
|
||||
/*-----------------------------------*/
|
||||
#define radare_argc (sizeof (radare_argv) / sizeof(const char*) - 1)
|
||||
static const char *radare_argv[] = {
|
||||
"whereis", "which", "ls", "rm", "mkdir", "pwd", "cat", "less", "exit", "quit",
|
||||
"whereis", "which", "ls", "rm", "mkdir", "pwd", "cat", "sort", "uniq", "join", "less", "exit", "quit",
|
||||
"#?", "#!", "#sha1", "#crc32", "#pcprint", "#sha256", "#sha512", "#md4", "#md5",
|
||||
"#!python", "#!vala", "#!pipe",
|
||||
"*?", "*", "$",
|
||||
|
@ -108,6 +108,7 @@ R_API void *r_list_pop(RList *list);
|
||||
R_API void *r_list_pop_head(RList *list);
|
||||
R_API void r_list_reverse(RList *list);
|
||||
R_API RList *r_list_clone(RList *list);
|
||||
R_API char *r_list_to_str(RList *list, char ch);
|
||||
|
||||
/* hashlike api */
|
||||
R_API RListIter *r_list_contains(const RList *list, const void *p);
|
||||
|
@ -131,6 +131,9 @@ R_API char *r_syscmd_ls(const char *input);
|
||||
R_API char *r_syscmd_cat(const char *file);
|
||||
R_API char *r_syscmd_mkdir(const char *dir);
|
||||
R_API bool r_syscmd_mv(const char *input);
|
||||
R_API char *r_syscmd_uniq(const char *file);
|
||||
R_API char *r_syscmd_join(const char *file1, const char *file2);
|
||||
R_API char *r_syscmd_sort(const char *file);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -607,6 +607,18 @@ R_API RList *r_list_uniq(const RList *list, RListComparator cmp) {
|
||||
}
|
||||
return nl;
|
||||
}
|
||||
R_API char *r_list_to_str(RList *list, char ch) {
|
||||
RListIter *iter;
|
||||
RStrBuf *buf = r_strbuf_new ("");
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
char *item;
|
||||
r_list_foreach (list, iter, item) {
|
||||
r_strbuf_appendf (buf, "%s%c", item, ch);
|
||||
}
|
||||
return r_strbuf_drain (buf);
|
||||
}
|
||||
|
||||
#if TEST
|
||||
|
||||
|
@ -250,6 +250,136 @@ R_API char *r_syscmd_ls(const char *input) {
|
||||
return res;
|
||||
}
|
||||
|
||||
static int cmpstr (const void *_a, const void *_b) {
|
||||
const char *a = _a, *b = _b;
|
||||
return (int)strcmp (a, b);
|
||||
}
|
||||
|
||||
R_API char *r_syscmd_sort(const char *file) {
|
||||
int sz;
|
||||
const char *p = NULL;
|
||||
RList *list = NULL;
|
||||
if (file) {
|
||||
if ((p = strchr (file, ' '))) {
|
||||
p = p + 1;
|
||||
} else {
|
||||
p = file;
|
||||
}
|
||||
}
|
||||
if (p && *p) {
|
||||
char *filename = strdup (p);
|
||||
r_str_trim (filename);
|
||||
char *data = r_file_slurp (filename, &sz);
|
||||
if (!data) {
|
||||
eprintf ("No such file or directory\n");
|
||||
} else {
|
||||
list = r_str_split_list (data, "\n");
|
||||
r_list_sort (list, cmpstr);
|
||||
data = r_list_to_str (list, '\n');
|
||||
r_list_free (list);
|
||||
}
|
||||
free (filename);
|
||||
return data;
|
||||
} else {
|
||||
eprintf ("Usage: sort [file]\n");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API char *r_syscmd_uniq(const char *file) {
|
||||
int sz;
|
||||
const char *p = NULL;
|
||||
RList *list = NULL;
|
||||
if (file) {
|
||||
if ((p = strchr (file, ' '))) {
|
||||
p = p + 1;
|
||||
} else {
|
||||
p = file;
|
||||
}
|
||||
}
|
||||
if (p && *p) {
|
||||
char *filename = strdup (p);
|
||||
r_str_trim (filename);
|
||||
char *data = r_file_slurp (filename, &sz);
|
||||
if (!data) {
|
||||
eprintf ("No such file or directory\n");
|
||||
} else {
|
||||
list = r_str_split_list (data, "\n");
|
||||
RList *uniq_list = r_list_uniq (list, cmpstr);
|
||||
data = r_list_to_str (uniq_list, '\n');
|
||||
r_list_free (uniq_list);
|
||||
r_list_free (list);
|
||||
}
|
||||
free (filename);
|
||||
return data;
|
||||
} else {
|
||||
eprintf ("Usage: uniq [file]\n");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API char *r_syscmd_join(const char *file1, const char *file2) {
|
||||
int sz1, sz2;
|
||||
const char *p1 = NULL, *p2 = NULL;
|
||||
RList *list1, *list2, *list = r_list_newf (NULL);
|
||||
if (!list) {
|
||||
return NULL;
|
||||
}
|
||||
if (file1) {
|
||||
if ((p1 = strchr (file1, ' '))) {
|
||||
p1 = p1 + 1;
|
||||
} else {
|
||||
p1 = file1;
|
||||
}
|
||||
}
|
||||
if (file2) {
|
||||
if ((p2 = strchr (file2, ' '))) {
|
||||
p2 = p2 + 1;
|
||||
} else {
|
||||
p2 = file2;
|
||||
}
|
||||
}
|
||||
if (p1 && *p1 && p2 && *p2 ) {
|
||||
char *filename1 = strdup (p1);
|
||||
char *filename2 = strdup (p2);
|
||||
r_str_trim (filename1);
|
||||
r_str_trim (filename2);
|
||||
char *data1 = r_file_slurp (filename1, &sz1);
|
||||
char *data2 = r_file_slurp (filename2, &sz2);
|
||||
char *data = NULL;
|
||||
RListIter *iter1, *iter2;
|
||||
if (!data1 && !data2) {
|
||||
eprintf ("No such files or directory\n");
|
||||
} else {
|
||||
list1 = r_str_split_list (data1, "\n");
|
||||
list2 = r_str_split_list (data2, "\n");
|
||||
iter2 = list1->head;
|
||||
for (iter1 = list1->head, iter2 = list2->head; iter1 || iter2;) {
|
||||
char *data = r_str_new ("");
|
||||
if (iter1) {
|
||||
r_str_appendf (data, "%s ", (char *)iter1->data);
|
||||
iter1 = iter1->n;
|
||||
}
|
||||
if (iter2) {
|
||||
r_str_append (data, (char *)iter2->data);
|
||||
iter2 = iter2->n;
|
||||
}
|
||||
r_list_append (list, data);
|
||||
}
|
||||
data = r_list_to_str (list, '\n');
|
||||
r_list_free (list);
|
||||
r_list_free (list1);
|
||||
r_list_free (list2);
|
||||
}
|
||||
free (filename1);
|
||||
free (filename2);
|
||||
return data;
|
||||
} else {
|
||||
eprintf ("Usage: join file1 file2\n");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API char *r_syscmd_cat(const char *file) {
|
||||
int sz;
|
||||
const char *p = NULL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user