Skip to content

Commit

Permalink
Fix #14335 - Add sort, join and uniq ##core
Browse files Browse the repository at this point in the history
  • Loading branch information
deepakchethan authored and radare committed Jun 20, 2019
1 parent 94746b2 commit 2da973e
Show file tree
Hide file tree
Showing 8 changed files with 272 additions and 4 deletions.
78 changes: 78 additions & 0 deletions libr/core/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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] == '?') {
Expand Down Expand Up @@ -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},
Expand Down
2 changes: 1 addition & 1 deletion libr/core/cmd_flag.c
Original file line number Diff line number Diff line change
Expand Up @@ -1117,7 +1117,7 @@ static int cmd_flag(void *data, const char *input) {
free (arg);
}
break;
case 'C':
case 'C': // "fC"
if (input[1] == ' ') {
RFlagItem *item;
char *q, *p = strdup (input + 2), *dec = NULL;
Expand Down
48 changes: 46 additions & 2 deletions libr/core/cmd_seek.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 == '-') {
Expand Down Expand Up @@ -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"
{
Expand Down
2 changes: 1 addition & 1 deletion libr/core/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
"*?", "*", "$",
Expand Down
1 change: 1 addition & 0 deletions libr/include/r_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions libr/include/r_util/r_sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
12 changes: 12 additions & 0 deletions libr/util/list.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
130 changes: 130 additions & 0 deletions libr/util/syscmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 2da973e

Please sign in to comment.