mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-23 05:09:43 +00:00
* Implement r_str_argv()
- Use it from p/debug - Now is possible to debug programs with arguments - Added test program in util/t/argv * Fix pd/pD * Clean and fix the native debugger plugin * More random code syntax cleanup * Rename io plugin names without the deprecated 'io_' prefix * Fix mk/stat-make.pl (missing ;)
This commit is contained in:
parent
a536777d35
commit
020686b86f
@ -106,3 +106,4 @@ Enjoy the 'two girls one backup' viral video
|
||||
A C program is like a fast dance on a newly waxed dance floor by people carrying razors - Waldi Ravens
|
||||
radare2 is like windows 7 but even better
|
||||
Enlarge your radare2
|
||||
Excellent; we can attack in any direction!
|
||||
|
180
libr/core/cmd.c
180
libr/core/cmd.c
@ -11,6 +11,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
#if __UNIX__
|
||||
// TODO: move this outside
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
@ -173,12 +174,12 @@ static int cmd_yank_to(struct r_core_t *core, char *arg) {
|
||||
char *str;
|
||||
ut8 *buf;
|
||||
|
||||
while(*arg==' ')arg=arg+1;
|
||||
while (*arg==' ')arg=arg+1;
|
||||
str = strchr(arg, ' ');
|
||||
if (str) {
|
||||
str[0]='\0';
|
||||
len = r_num_math(&core->num, arg);
|
||||
pos = r_num_math(&core->num, str+1);
|
||||
len = r_num_math (&core->num, arg);
|
||||
pos = r_num_math (&core->num, str+1);
|
||||
str[0]=' ';
|
||||
}
|
||||
if ( (str == NULL) || (pos == -1) || (len == 0) ) {
|
||||
@ -191,13 +192,13 @@ static int cmd_yank_to(struct r_core_t *core, char *arg) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
buf = (ut8*)malloc( len );
|
||||
buf = (ut8*)malloc (len);
|
||||
r_core_read_at (core, src, buf, len);
|
||||
r_core_write_at (core, pos, buf, len);
|
||||
free(buf);
|
||||
|
||||
core->offset = src;
|
||||
r_core_block_read(core, 0);
|
||||
r_core_block_read (core, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -240,8 +241,7 @@ static int cmd_yank(void *data, const char *input) {
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int cmd_quit(void *data, const char *input)
|
||||
{
|
||||
static int cmd_quit(void *data, const char *input) {
|
||||
struct r_core_t *core = (struct r_core_t *)data;
|
||||
switch (input[0]) {
|
||||
case '?':
|
||||
@ -258,7 +258,7 @@ static int cmd_quit(void *data, const char *input)
|
||||
// TODO
|
||||
default:
|
||||
r_line_hist_save (".radare2_history");
|
||||
exit(*input?r_num_math(&core->num, input+1):0);
|
||||
exit (*input?r_num_math (&core->num, input+1):0);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@ -266,19 +266,19 @@ static int cmd_quit(void *data, const char *input)
|
||||
|
||||
static int cmd_interpret(void *data, const char *input) {
|
||||
char *str, *ptr, *eol;
|
||||
struct r_core_t *core = (struct r_core_t *)data;
|
||||
switch(input[0]) {
|
||||
RCore *core = (RCore *)data;
|
||||
switch (input[0]) {
|
||||
case ' ':
|
||||
/* interpret file */
|
||||
r_core_cmd_file(core, input+1);
|
||||
r_core_cmd_file (core, input+1);
|
||||
break;
|
||||
case '!':
|
||||
/* from command */
|
||||
r_core_cmd_command(core, input+1);
|
||||
r_core_cmd_command (core, input+1);
|
||||
break;
|
||||
case '(':
|
||||
//fprintf(stderr, "macro call (%s)\n", input+1);
|
||||
r_macro_call(&core->macro, input+1);
|
||||
r_macro_call (&core->macro, input+1);
|
||||
break;
|
||||
case '?':
|
||||
r_cons_printf (
|
||||
@ -289,15 +289,15 @@ static int cmd_interpret(void *data, const char *input) {
|
||||
" ./m ELF ; interpret output of command /m ELF as r. commands\n");
|
||||
break;
|
||||
default:
|
||||
ptr = str = r_core_cmd_str(core, input);
|
||||
ptr = str = r_core_cmd_str (core, input);
|
||||
for (;;) {
|
||||
eol = strchr(ptr, '\n');
|
||||
eol = strchr (ptr, '\n');
|
||||
if (eol) eol[0]='\0';
|
||||
r_core_cmd(core, ptr, 0);
|
||||
r_core_cmd (core, ptr, 0);
|
||||
if (!eol) break;
|
||||
ptr = eol+1;
|
||||
}
|
||||
free(str);
|
||||
free (str);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@ -416,11 +416,9 @@ static int cmd_seek(void *data, const char *input) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_help(void *data, const char *input)
|
||||
{
|
||||
struct r_core_t *core = (struct r_core_t *)data;
|
||||
static int cmd_help(void *data, const char *input) {
|
||||
RCore *core = (RCore *)data;
|
||||
ut64 n;
|
||||
|
||||
switch (input[0]) {
|
||||
case ' ':
|
||||
n = r_num_math (&core->num, input+1);
|
||||
@ -525,8 +523,7 @@ static int cmd_help(void *data, const char *input)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_bsize(void *data, const char *input)
|
||||
{
|
||||
static int cmd_bsize(void *data, const char *input) {
|
||||
struct r_core_t *core = (struct r_core_t *)data;
|
||||
switch (input[0]) {
|
||||
case '\0':
|
||||
@ -534,7 +531,7 @@ static int cmd_bsize(void *data, const char *input)
|
||||
break;
|
||||
default:
|
||||
//input = r_str_clean(input);
|
||||
r_core_block_size (core, r_num_math (NULL, input));
|
||||
r_core_block_size (core, r_num_math (&core->num, input));
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@ -661,9 +658,8 @@ static int cmd_info(void *data, const char *input) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_print(void *data, const char *input)
|
||||
{
|
||||
struct r_core_t *core = (struct r_core_t *)data;
|
||||
static int cmd_print(void *data, const char *input) {
|
||||
RCore *core = (RCore *)data;
|
||||
int l, len = core->blocksize;
|
||||
ut32 tbs = core->blocksize;
|
||||
int show_offset = r_config_get_i (&core->config, "asm.offset");
|
||||
@ -679,13 +675,15 @@ static int cmd_print(void *data, const char *input)
|
||||
if (r_config_get_i (&core->config, "asm.reflineswide"))
|
||||
linesopts |= R_ANAL_REFLINE_WIDE;
|
||||
|
||||
/* XXX: This is only for pd/pD ??? */
|
||||
if (input[0] && input[1]) {
|
||||
l = (int) r_num_get (&core->num, input+2);
|
||||
l = (int) r_num_math (&core->num, input+2);
|
||||
if (input[0] != 'd') {
|
||||
if (l>0) len = l;
|
||||
if (l>tbs) r_core_block_size (core, l);
|
||||
l = 9999;
|
||||
}
|
||||
}
|
||||
} else l = 9999;
|
||||
|
||||
switch(input[0]) {
|
||||
case 'D':
|
||||
@ -704,7 +702,6 @@ static int cmd_print(void *data, const char *input)
|
||||
|
||||
//r_anal_set_pc(&core->anal, core->offset);
|
||||
r_asm_set_pc (&core->assembler, core->offset);
|
||||
l = 9999; // number of lines
|
||||
|
||||
reflines = r_anal_reflines_get (&core->anal, core->offset,
|
||||
buf, len, -1, linesout);
|
||||
@ -868,8 +865,7 @@ static int cmd_flag(void *data, const char *input) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_anal(void *data, const char *input)
|
||||
{
|
||||
static int cmd_anal(void *data, const char *input) {
|
||||
struct r_core_t *core = (struct r_core_t *)data;
|
||||
int l, len = core->blocksize;
|
||||
ut32 tbs = core->blocksize;
|
||||
@ -915,8 +911,7 @@ static int cmd_anal(void *data, const char *input)
|
||||
}
|
||||
|
||||
/* TODO: simplify using r_write */
|
||||
static int cmd_write(void *data, const char *input)
|
||||
{
|
||||
static int cmd_write(void *data, const char *input) {
|
||||
int i, len = strlen(input);
|
||||
char *tmp, *str = alloca(len)+1;
|
||||
struct r_core_t *core = (struct r_core_t *)data;
|
||||
@ -1148,8 +1143,7 @@ static int __cb_hit(struct r_search_kw_t *kw, void *user, ut64 addr)
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int cmd_search(void *data, const char *input)
|
||||
{
|
||||
static int cmd_search(void *data, const char *input) {
|
||||
struct r_core_t *core = (struct r_core_t *)data;
|
||||
ut64 at;
|
||||
ut32 n32;
|
||||
@ -1238,8 +1232,7 @@ static int cmd_search(void *data, const char *input)
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int cmd_eval(void *data, const char *input)
|
||||
{
|
||||
static int cmd_eval(void *data, const char *input) {
|
||||
struct r_core_t *core = (struct r_core_t *)data;
|
||||
switch (input[0]) {
|
||||
case '\0':
|
||||
@ -1274,8 +1267,7 @@ static int cmd_eval(void *data, const char *input)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_hash(void *data, const char *input)
|
||||
{
|
||||
static int cmd_hash(void *data, const char *input) {
|
||||
char algo[32];
|
||||
struct r_core_t *core = (struct r_core_t *)data;
|
||||
ut32 len = core->blocksize;
|
||||
@ -1331,13 +1323,11 @@ static int cmd_hash(void *data, const char *input)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_visual(void *data, const char *input)
|
||||
{
|
||||
static int cmd_visual(void *data, const char *input) {
|
||||
return r_core_visual ((RCore *)data, input);
|
||||
}
|
||||
|
||||
static int cmd_system(void *data, const char *input)
|
||||
{
|
||||
static int cmd_system(void *data, const char *input) {
|
||||
//struct r_core_t *core = (struct r_core_t *)data;
|
||||
// slurped from teh old radare_system
|
||||
#if __FreeBSD__
|
||||
@ -1363,8 +1353,7 @@ static int cmd_system(void *data, const char *input)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int cmd_open(void *data, const char *input)
|
||||
{
|
||||
static int cmd_open(void *data, const char *input) {
|
||||
RCore *core = (RCore*)data;
|
||||
RCoreFile *file;
|
||||
ut64 addr, size;
|
||||
@ -1407,9 +1396,8 @@ static int cmd_open(void *data, const char *input)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_meta(void *data, const char *input)
|
||||
{
|
||||
struct r_core_t *core = (struct r_core_t *)data;
|
||||
static int cmd_meta(void *data, const char *input) {
|
||||
RCore *core = (RCore*)data;
|
||||
int ret, line = 0;
|
||||
char file[1024];
|
||||
switch(input[0]) {
|
||||
@ -1441,19 +1429,19 @@ static int cmd_meta(void *data, const char *input)
|
||||
char fun_name[128];
|
||||
int size = atoi(input);
|
||||
int type = R_META_FUNCTION;
|
||||
char *t, *p = strchr(input+1, ' ');
|
||||
char *t, *p = strchr (input+1, ' ');
|
||||
if (p) {
|
||||
t = strdup(p+1);
|
||||
printf("T=(%s)\n", t);
|
||||
t = strdup (p+1);
|
||||
eprintf ("T=(%s)\n", t);
|
||||
p = strchr(t, ' ');
|
||||
if (p) {
|
||||
*p='\0';
|
||||
strncpy(fun_name, p+1, sizeof(fun_name));
|
||||
} else sprintf(fun_name, "sub_%08llx", addr);
|
||||
addr = r_num_math(&core->num, t);
|
||||
strncpy (fun_name, p+1, sizeof (fun_name));
|
||||
} else sprintf (fun_name, "sub_%08llx", addr);
|
||||
addr = r_num_math (&core->num, t);
|
||||
free(t);
|
||||
}
|
||||
r_meta_add(&core->meta, type, addr, size, fun_name);
|
||||
r_meta_add (&core->meta, type, addr, size, fun_name);
|
||||
}
|
||||
break;
|
||||
case '\0':
|
||||
@ -1467,35 +1455,32 @@ printf("T=(%s)\n", t);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int cmd_undowrite(void *data, const char *input)
|
||||
{
|
||||
static int cmd_undowrite(void *data, const char *input) {
|
||||
//struct r_core_t *core = (struct r_core_t *)data;
|
||||
// TODO:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_io_system(void *data, const char *input)
|
||||
{
|
||||
static int cmd_io_system(void *data, const char *input) {
|
||||
struct r_core_t *core = (struct r_core_t *)data;
|
||||
r_io_set_fd(&core->io, core->file->fd);
|
||||
return r_io_system(&core->io, input);
|
||||
}
|
||||
|
||||
static int cmd_macro(void *data, const char *input)
|
||||
{
|
||||
struct r_core_t *core = (struct r_core_t *)data;
|
||||
static int cmd_macro(void *data, const char *input) {
|
||||
RCore *core = (RCore*)data;
|
||||
switch(input[0]) {
|
||||
case ')':
|
||||
r_macro_break(&core->macro, input+1);
|
||||
r_macro_break (&core->macro, input+1);
|
||||
break;
|
||||
case '-':
|
||||
r_macro_rm(&core->macro, input+1);
|
||||
r_macro_rm (&core->macro, input+1);
|
||||
break;
|
||||
case '\0':
|
||||
r_macro_list(&core->macro);
|
||||
r_macro_list (&core->macro);
|
||||
break;
|
||||
case '?':
|
||||
eprintf(
|
||||
eprintf (
|
||||
"Usage: (foo\\n..cmds..\\n)\n"
|
||||
" Record macros grouping commands\n"
|
||||
" (foo args\\n ..) ; define a macro\n"
|
||||
@ -1511,7 +1496,7 @@ static int cmd_macro(void *data, const char *input)
|
||||
);
|
||||
break;
|
||||
default:
|
||||
r_macro_add(&core->macro, input);
|
||||
r_macro_add (&core->macro, input);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@ -1557,35 +1542,34 @@ static int r_core_cmd_subst(struct r_core_t *core, char *cmd)
|
||||
if (!*cmd || cmd[0]=='\0')
|
||||
return 0;
|
||||
|
||||
cmd = r_str_trim_head_tail(cmd);
|
||||
cmd = r_str_trim_head_tail (cmd);
|
||||
|
||||
/* quoted / raw command */
|
||||
if (cmd[0] =='"') {
|
||||
if (cmd[len-1] != '"') {
|
||||
fprintf(stderr, "parse: Missing ending '\"'\n");
|
||||
eprintf ("parse: Missing ending '\"'\n");
|
||||
return -1;
|
||||
} else {
|
||||
cmd[len-1]='\0';
|
||||
ret = r_cmd_call(&core->cmd, cmd+1);
|
||||
return ret;
|
||||
}
|
||||
cmd[len-1]='\0';
|
||||
ret = r_cmd_call (&core->cmd, cmd+1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* multiple commands */
|
||||
ptr = strrchr(cmd, ';');
|
||||
ptr = strrchr (cmd, ';');
|
||||
if (ptr) {
|
||||
ptr[0]='\0';
|
||||
if (r_core_cmd_subst(core, cmd) == -1)
|
||||
if (r_core_cmd_subst (core, cmd) == -1)
|
||||
return -1;
|
||||
cmd = ptr+1;
|
||||
r_cons_flush();
|
||||
r_cons_flush ();
|
||||
}
|
||||
|
||||
/* pipe console to shell process */
|
||||
ptr = strchr(cmd, '|');
|
||||
ptr = strchr (cmd, '|');
|
||||
if (ptr) {
|
||||
ptr[0] = '\0';
|
||||
r_core_cmd_pipe(core, cmd, ptr+1);
|
||||
r_core_cmd_pipe (core, cmd, ptr+1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1593,19 +1577,19 @@ static int r_core_cmd_subst(struct r_core_t *core, char *cmd)
|
||||
ptr = strchr(cmd, '&');
|
||||
while (ptr&&ptr[1]=='&') {
|
||||
ptr[0]='\0';
|
||||
ret = r_cmd_call(&core->cmd, cmd);
|
||||
ret = r_cmd_call (&core->cmd, cmd);
|
||||
if (ret == -1){
|
||||
fprintf(stderr, "command error(%s)\n", cmd);
|
||||
eprintf ("command error(%s)\n", cmd);
|
||||
return ret;
|
||||
}
|
||||
for(cmd=ptr+2;cmd&&cmd[0]==' ';cmd=cmd+1);
|
||||
ptr = strchr(cmd, '&');
|
||||
for (cmd=ptr+2;cmd&&cmd[0]==' ';cmd=cmd+1);
|
||||
ptr = strchr (cmd, '&');
|
||||
}
|
||||
|
||||
/* Out Of Band Input */
|
||||
free(core->oobi);
|
||||
free (core->oobi);
|
||||
core->oobi = NULL;
|
||||
ptr = strchr(cmd, '<');
|
||||
ptr = strchr (cmd, '<');
|
||||
if (ptr) {
|
||||
ptr[0] = '\0';
|
||||
if (ptr[1]=='<') {
|
||||
@ -1707,8 +1691,7 @@ static int r_core_cmd_subst(struct r_core_t *core, char *cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
R_API int r_core_cmd_foreach(struct r_core_t *core, const char *cmd, char *each)
|
||||
{
|
||||
R_API int r_core_cmd_foreach(RCore *core, const char *cmd, char *each) {
|
||||
int i=0,j;
|
||||
char ch;
|
||||
char *word = NULL;
|
||||
@ -1821,7 +1804,7 @@ R_API int r_core_cmd_foreach(struct r_core_t *core, const char *cmd, char *each)
|
||||
radare_cmd(cmd,0);
|
||||
}
|
||||
#else
|
||||
printf("No flags foreach implemented\n");
|
||||
eprintf ("No flags foreach implemented\n");
|
||||
#endif
|
||||
} else {
|
||||
/* for all flags in current flagspace */
|
||||
@ -1867,8 +1850,7 @@ printf("No flags foreach implemented\n");
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
R_API int r_core_cmd(struct r_core_t *core, const char *command, int log)
|
||||
{
|
||||
R_API int r_core_cmd(struct r_core_t *core, const char *command, int log) {
|
||||
int len, rep, ret = R_FALSE;
|
||||
char *cmd, *ocmd;
|
||||
if (command != NULL) {
|
||||
@ -1905,8 +1887,7 @@ R_API int r_core_cmd(struct r_core_t *core, const char *command, int log)
|
||||
return ret;
|
||||
}
|
||||
|
||||
R_API int r_core_cmd_file(struct r_core_t *core, const char *file)
|
||||
{
|
||||
R_API int r_core_cmd_file(struct r_core_t *core, const char *file) {
|
||||
char buf[1024];
|
||||
FILE *fd = fopen(file, "r");
|
||||
if (fd == NULL) {
|
||||
@ -1926,8 +1907,7 @@ R_API int r_core_cmd_file(struct r_core_t *core, const char *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
R_API int r_core_cmd_command(struct r_core_t *core, const char *command)
|
||||
{
|
||||
R_API int r_core_cmd_command(struct r_core_t *core, const char *command) {
|
||||
int len;
|
||||
char *buf, *rcmd, *ptr;
|
||||
rcmd = ptr = buf = r_sys_cmd_str (command, 0, &len);
|
||||
@ -2081,8 +2061,7 @@ static int cmd_debug(void *data, const char *input) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
R_API int r_core_cmd_buffer(void *user, const char *buf)
|
||||
{
|
||||
R_API int r_core_cmd_buffer(void *user, const char *buf) {
|
||||
char *str = strdup(buf);
|
||||
char *ptr = strchr(str, '\n');
|
||||
char *optr = str;
|
||||
@ -2097,8 +2076,7 @@ R_API int r_core_cmd_buffer(void *user, const char *buf)
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
R_API int r_core_cmdf(void *user, const char *fmt, ...)
|
||||
{
|
||||
R_API int r_core_cmdf(void *user, const char *fmt, ...) {
|
||||
char string[1024];
|
||||
int ret;
|
||||
va_list ap;
|
||||
@ -2109,8 +2087,7 @@ R_API int r_core_cmdf(void *user, const char *fmt, ...)
|
||||
return ret;
|
||||
}
|
||||
|
||||
R_API int r_core_cmd0(void *user, const char *cmd)
|
||||
{
|
||||
R_API int r_core_cmd0(void *user, const char *cmd) {
|
||||
return r_core_cmd ((struct r_core_t *)user, cmd, 0);
|
||||
}
|
||||
|
||||
@ -2134,8 +2111,7 @@ R_API char *r_core_cmd_str(struct r_core_t *core, const char *cmd)
|
||||
return retstr;
|
||||
}
|
||||
|
||||
int r_core_cmd_init(struct r_core_t *core)
|
||||
{
|
||||
int r_core_cmd_init(struct r_core_t *core) {
|
||||
r_cmd_init (&core->cmd);
|
||||
r_cmd_set_data (&core->cmd, core);
|
||||
r_cmd_add (&core->cmd, "x", "alias for px", &cmd_hexdump);
|
||||
|
@ -77,7 +77,6 @@
|
||||
#define DEBUGGER 0
|
||||
#endif // ARCH
|
||||
|
||||
|
||||
#if DEBUGGER
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/types.h>
|
||||
@ -120,21 +119,16 @@ static void debug_arch_x86_trap_set(int pid, int foo) {
|
||||
if (foo) regs.__eflags |= EFLAGS_TRAP_FLAG;
|
||||
else regs.__eflags &= ~EFLAGS_TRAP_FLAG;
|
||||
debug_setregs (pid_to_task (pid), ®s);
|
||||
#else
|
||||
/* void */
|
||||
#endif // __i386__ || __x86_64__
|
||||
#endif
|
||||
}
|
||||
#endif // __APPLE__
|
||||
|
||||
static int r_debug_native_step(int pid) {
|
||||
int ret = R_FALSE;
|
||||
#if __APPLE__
|
||||
//R_DEBUG_REG_T regs;
|
||||
|
||||
#if __APPLE__
|
||||
debug_arch_x86_trap_set (pid, 1);
|
||||
|
||||
#define OLD_PANCAKE_CODE 1
|
||||
#if OLD_PANCAKE_CODE
|
||||
//eprintf ("stepping from pc = %08x\n", (ut32)get_offset("eip"));
|
||||
//ret = ptrace (PT_STEP, ps.tid, (caddr_t)get_offset("eip"), SIGSTOP);
|
||||
ret = ptrace (PT_STEP, pid, (caddr_t)1, SIGTRAP); //SIGINT);
|
||||
@ -154,7 +148,7 @@ static int r_debug_native_step(int pid) {
|
||||
perror ("native-singlestep");
|
||||
ret = R_FALSE;
|
||||
} else ret = R_TRUE;
|
||||
#endif // __APPLE__
|
||||
#endif // __APPLE_
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -186,6 +180,7 @@ static int r_debug_native_continue(int pid, int sig) {
|
||||
#if __APPLE__
|
||||
eprintf ("debug_contp: program is now running...\n");
|
||||
|
||||
/* XXX */
|
||||
/* only stopped with ptrace the first time */
|
||||
//ptrace(PT_CONTINUE, pid, 0, 0);
|
||||
ptrace (PT_DETACH, pid, 0, 0);
|
||||
@ -374,7 +369,7 @@ static const char *r_debug_native_reg_profile() {
|
||||
|
||||
// TODO: what about float and hardware regs here ???
|
||||
// TODO: add flag for type
|
||||
static int r_debug_native_reg_read(struct r_debug_t *dbg, int type, ut8 *buf, int size)
|
||||
static int r_debug_native_reg_read(RDebug *dbg, int type, ut8 *buf, int size)
|
||||
{
|
||||
int ret;
|
||||
int pid = dbg->pid;
|
||||
@ -396,7 +391,7 @@ static int r_debug_native_reg_read(struct r_debug_t *dbg, int type, ut8 *buf, in
|
||||
|
||||
if (inferior_thread_count>0) {
|
||||
/* TODO: allow to choose the thread */
|
||||
if ((ret = thread_get_state (inferior_threads[0], R_DEBUG_STATE_T,
|
||||
if ((ret = thread_get_state (inferior_threads[0], R_DEBUG_STATE_T,
|
||||
(thread_state_t) regs, &gp_count)) != KERN_SUCCESS) {
|
||||
eprintf ("debug_getregs: Failed to get thread %d %d.error (%x). (%s)\n",
|
||||
(int)pid, pid_to_task (pid), (int)ret, MACH_ERROR_STRING (ret));
|
||||
@ -415,8 +410,10 @@ static int r_debug_native_reg_read(struct r_debug_t *dbg, int type, ut8 *buf, in
|
||||
R_DEBUG_REG_T regs;
|
||||
memset (®s, 0, sizeof (regs));
|
||||
memset (buf, 0, size);
|
||||
|
||||
#if __NetBSD__ || __FreeBSD__ || __OpenBSD__
|
||||
ret = ptrace (PTRACE_GETREGS, pid, ®s, sizeof (regs));
|
||||
|
||||
#elif __linux__ && __powerpc__
|
||||
ret = ptrace (PTRACE_GETREGS, pid, ®s, NULL);
|
||||
#else
|
||||
@ -431,7 +428,6 @@ static int r_debug_native_reg_read(struct r_debug_t *dbg, int type, ut8 *buf, in
|
||||
return sizeof (regs);
|
||||
}
|
||||
break;
|
||||
//r_reg_set_bytes(reg, ®s, sizeof(struct user_regs));
|
||||
}
|
||||
return R_TRUE;
|
||||
#else
|
||||
@ -476,7 +472,7 @@ static RList *r_debug_native_map_get(struct r_debug_t *dbg)
|
||||
sprintf (path, "/proc/%d/maps", dbg->pid);
|
||||
#endif
|
||||
fd = fopen (path, "r");
|
||||
if(!fd) {
|
||||
if (!fd) {
|
||||
perror ("debug_init_maps");
|
||||
return NULL;
|
||||
}
|
||||
@ -491,9 +487,10 @@ static RList *r_debug_native_map_get(struct r_debug_t *dbg)
|
||||
path[0]='\0';
|
||||
line[strlen (line)-1]='\0';
|
||||
#if __FreeBSD__
|
||||
// 0x8070000 0x8072000 2 0 0xc1fde948 rw- 1 0 0x2180 COW NC vnode /usr/bin/gcc
|
||||
// 0x8070000 0x8072000 2 0 0xc1fde948 rw- 1 0 0x2180 COW NC vnode /usr/bin/gcc
|
||||
sscanf (line, "%s %s %d %d 0x%s %3s %d %d",
|
||||
®ion[2], ®ion2[2], &ign, &ign, unkstr, perms, &ign, &ign);
|
||||
®ion[2], ®ion2[2], &ign, &ign,
|
||||
unkstr, perms, &ign, &ign);
|
||||
pos_c = strchr (line, '/');
|
||||
if (pos_c) strcpy (path, pos_c);
|
||||
else path[0]='\0';
|
||||
@ -555,7 +552,7 @@ static RList *r_debug_native_map_get(struct r_debug_t *dbg)
|
||||
#endif
|
||||
r_list_append (list, map);
|
||||
}
|
||||
fclose(fd);
|
||||
fclose (fd);
|
||||
#endif // __sun
|
||||
return list;
|
||||
}
|
||||
@ -589,14 +586,6 @@ static int r_debug_get_arch()
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int r_debug_native_import(struct r_debug_handle_t *from)
|
||||
{
|
||||
//int pid = from->export(R_DEBUG_GET_PID);
|
||||
//int maps = from->export(R_DEBUG_GET_MAPS);
|
||||
return R_FALSE;
|
||||
}
|
||||
#endif
|
||||
#if __i386__
|
||||
const char *archlist[3] = { "x86", "x86-32", 0 };
|
||||
#elif __x86_64__
|
||||
@ -634,8 +623,8 @@ struct r_lib_struct_t radare_plugin = {
|
||||
};
|
||||
#endif // CORELIB
|
||||
|
||||
#endif
|
||||
#else
|
||||
//#endif
|
||||
#else // DEBUGGER
|
||||
struct r_debug_handle_t r_debug_plugin_native = {
|
||||
.name = "native",
|
||||
};
|
||||
|
@ -156,6 +156,8 @@ R_API void r_num_init(struct r_num_t *num);
|
||||
#define ishexchar(x) ((x>='0'&&x<='9') || (x>='a'&&x<='f') || (x>='A'&&x<='F')) {
|
||||
|
||||
/* strings */
|
||||
R_API char **r_str_argv(const char *str, int *_argc);
|
||||
R_API void r_str_argv_free(char **argv);
|
||||
R_API char *r_str_new(char *str);
|
||||
R_API const char *r_str_bool(int b);
|
||||
R_API const char *r_str_ansi_chrn(const char *str, int n);
|
||||
|
@ -32,39 +32,6 @@ static void inferior_abort_handler(int pid) {
|
||||
#include <mach-o/loader.h>
|
||||
#include <mach-o/nlist.h>
|
||||
|
||||
// XXX this is OSX
|
||||
static pid_t start_inferior(int argc, char **argv) {
|
||||
char **child_args;
|
||||
int status;
|
||||
pid_t kid;
|
||||
|
||||
eprintf ("Starting process...\n");
|
||||
|
||||
if ((kid = fork ())) {
|
||||
//waitpid (kid, &status, 0);
|
||||
wait (&status);
|
||||
if (WIFSTOPPED (status)) {
|
||||
eprintf ("Process with PID %d started...\n", (int)kid);
|
||||
return kid;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
child_args = (char **)malloc (sizeof (char *) * (argc + 1));
|
||||
memcpy (child_args, argv, sizeof(char *) * argc);
|
||||
child_args[argc] = NULL;
|
||||
|
||||
ptrace (PT_TRACE_ME, 0, 0, 0);
|
||||
/* why altering these signals? */
|
||||
/* XXX this can be monitorized by the child */
|
||||
signal (SIGTRAP, SIG_IGN); // SINO NO FUNCIONA EL STEP
|
||||
signal (SIGABRT, inferior_abort_handler);
|
||||
|
||||
execvp (argv[0], child_args);
|
||||
|
||||
eprintf ("Failed to start inferior.\n");
|
||||
exit (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __waitpid(int pid) {
|
||||
@ -80,25 +47,20 @@ static int __waitpid(int pid) {
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
// TODO: move to common os/ directory
|
||||
|
||||
/*
|
||||
* Creates a new process and returns the result:
|
||||
* -1 : error
|
||||
* 0 : ok
|
||||
* TODO: should be pid number?
|
||||
* TODO: should accept argv and so as arguments
|
||||
*/
|
||||
//#include <linux/user.h>
|
||||
#define MAGIC_EXIT 31337
|
||||
static int fork_and_ptraceme(const char *cmd)
|
||||
{
|
||||
static int fork_and_ptraceme(const char *cmd) {
|
||||
char **argv;
|
||||
int status, pid = -1;
|
||||
|
||||
pid = vfork();
|
||||
pid = vfork ();
|
||||
switch (pid) {
|
||||
case -1:
|
||||
fprintf(stderr, "Cannot fork.\n");
|
||||
perror ("fork_and_ptraceme");
|
||||
break;
|
||||
case 0:
|
||||
#if __APPLE__
|
||||
@ -111,46 +73,24 @@ static int fork_and_ptraceme(const char *cmd)
|
||||
eprintf ("ptrace-traceme failed\n");
|
||||
exit (MAGIC_EXIT);
|
||||
}
|
||||
#if 0
|
||||
eprintf ("argv = [ ");
|
||||
for (i=0;ps.argv[i];i++)
|
||||
eprintf ("'%s', ", ps.argv[i]);
|
||||
eprintf ("]\n");
|
||||
#endif
|
||||
// TODO: Add support to redirect filedescriptors
|
||||
// TODO: Configure process environment
|
||||
argv = r_str_argv (cmd, NULL);
|
||||
execvp (argv[0], argv);
|
||||
r_str_argv_free (argv);
|
||||
|
||||
// TODO: USE TM IF POSSIBLE TO ATTACH IT FROM ANOTHER CONSOLE!!!
|
||||
// TODO:
|
||||
//debug_environment();
|
||||
{
|
||||
char *buf;
|
||||
char *argv[2];
|
||||
char *ptr;
|
||||
|
||||
// TODO: use: argv = r_str_argv ("hello \"world is bar\"", &argc);
|
||||
buf = strdup (cmd);
|
||||
ptr = strchr (buf, ' ');
|
||||
if (ptr)
|
||||
*ptr='\0';
|
||||
|
||||
argv[0] = r_file_path (cmd);
|
||||
argv[1] = NULL;
|
||||
//execv(cmd, argv); //ps.argv[0], ps.argv);
|
||||
execvp (argv[0], argv);
|
||||
}
|
||||
perror ("fork_and_attach: execv");
|
||||
//printf(stderr, "[%d] %s execv failed.\n", getpid(), ps.filename);
|
||||
exit (MAGIC_EXIT); /* error */
|
||||
return 0; // invalid pid // if exit is overriden.. :)
|
||||
break;
|
||||
default:
|
||||
/* XXX: clean this dirty code */
|
||||
#if __APPLE__
|
||||
wait (&status);
|
||||
if (WIFSTOPPED (status))
|
||||
eprintf ("Process with PID %d started...\n", (int)pid);
|
||||
#else
|
||||
__waitpid (pid);
|
||||
kill (pid, SIGSTOP);
|
||||
#endif
|
||||
// XXX
|
||||
//kill (pid, SIGSTOP);
|
||||
break;
|
||||
}
|
||||
printf ("PID = %d\n", pid);
|
||||
|
@ -13,18 +13,15 @@
|
||||
static int ewf_fd = -1;
|
||||
static LIBEWF_HANDLE *ewf_h = NULL;
|
||||
|
||||
static int ewf__write(struct r_io_t *io, int fd, const ut8 *buf, int count)
|
||||
{
|
||||
static int ewf__write(struct r_io_t *io, int fd, const ut8 *buf, int count) {
|
||||
return libewf_write_buffer(ewf_h, buf, count);
|
||||
}
|
||||
|
||||
static int ewf__read(struct r_io_t *io, int fd, ut8 *buf, int count)
|
||||
{
|
||||
static int ewf__read(struct r_io_t *io, int fd, ut8 *buf, int count) {
|
||||
return libewf_read_buffer(ewf_h, buf, count);
|
||||
}
|
||||
|
||||
static int ewf__close(struct r_io_t *io, int fd)
|
||||
{
|
||||
static int ewf__close(struct r_io_t *io, int fd) {
|
||||
if (fd == ewf_fd) {
|
||||
libewf_close(ewf_h);
|
||||
ewf_fd = -1;
|
||||
@ -32,8 +29,7 @@ static int ewf__close(struct r_io_t *io, int fd)
|
||||
}
|
||||
}
|
||||
|
||||
static ut64 ewf__lseek(struct r_io_t *io, int fildes, ut64 offset, int whence)
|
||||
{
|
||||
static ut64 ewf__lseek(struct r_io_t *io, int fildes, ut64 offset, int whence) {
|
||||
size64_t media_size;
|
||||
|
||||
if (fildes == ewf_fd) {
|
||||
@ -56,8 +52,7 @@ static ut64 ewf__lseek(struct r_io_t *io, int fildes, ut64 offset, int whence)
|
||||
return lseek(fildes, offset, whence);
|
||||
}
|
||||
|
||||
static int ewf__handle_fd(struct r_io_t *io, int fd)
|
||||
{
|
||||
static int ewf__handle_fd(struct r_io_t *io, int fd) {
|
||||
return fd == ewf_fd;
|
||||
}
|
||||
|
||||
@ -69,8 +64,7 @@ static int ewf__handle_open(struct r_io_t *io, const char *pathname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ewf__open(struct r_io_t *io, const char *pathname, int flags, int mode)
|
||||
{
|
||||
static int ewf__open(struct r_io_t *io, const char *pathname, int flags, int mode) {
|
||||
// XXX filename list should be dynamic. 1024 limit is ugly
|
||||
const char *filenames[1024];
|
||||
char *ptr,*optr;
|
||||
@ -165,8 +159,7 @@ static int ewf__open(struct r_io_t *io, const char *pathname, int flags, int mod
|
||||
return ewf_fd;
|
||||
}
|
||||
|
||||
static int ewf__init(struct r_io_t *io)
|
||||
{
|
||||
static int ewf__init(struct r_io_t *io) {
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ static int __system(struct r_io_t *io, int fd, const char *cmd)
|
||||
|
||||
struct r_io_handle_t r_io_plugin_malloc = {
|
||||
//void *handle;
|
||||
.name = "io_malloc",
|
||||
.name = "malloc",
|
||||
.desc = "memory allocation ( malloc://size-in-bytes )",
|
||||
.open = __open,
|
||||
.close = __close,
|
||||
|
@ -89,7 +89,7 @@ static int shm__init(struct r_io_t *io)
|
||||
|
||||
struct r_io_handle_t r_io_plugin_shm = {
|
||||
//void *handle;
|
||||
.name = "io_shm",
|
||||
.name = "shm",
|
||||
.desc = "shared memory resources (shm://key)",
|
||||
.open = shm__open,
|
||||
.close = shm__close,
|
||||
|
433
libr/util/str.c
433
libr/util/str.c
@ -11,11 +11,10 @@ static const char *nullstr = "";
|
||||
static const char *nullstr_c = "(null)";
|
||||
|
||||
/* int c; ret = hex2int(&c, 'c'); */
|
||||
static int hex2int (unsigned char *val, unsigned char c)
|
||||
{
|
||||
if ('0' <= c && c <= '9') *val = (unsigned char)(*val) * 16 + ( c - '0');
|
||||
else if (c >= 'A' && c <= 'F') *val = (unsigned char)(*val) * 16 + ( c - 'A' + 10);
|
||||
else if (c >= 'a' && c <= 'f') *val = (unsigned char)(*val) * 16 + ( c - 'a' + 10);
|
||||
static int hex2int (ut8 *val, ut8 c) {
|
||||
if ('0' <= c && c <= '9') *val = (ut8)(*val) * 16 + ( c - '0');
|
||||
else if (c >= 'A' && c <= 'F') *val = (ut8)(*val) * 16 + ( c - 'A' + 10);
|
||||
else if (c >= 'a' && c <= 'f') *val = (ut8)(*val) * 16 + ( c - 'a' + 10);
|
||||
else return 1;
|
||||
return 0;
|
||||
}
|
||||
@ -49,40 +48,38 @@ R_API char *r_str_home(const char *str)
|
||||
return dst;
|
||||
}
|
||||
|
||||
R_API int r_str_hash(const char *str)
|
||||
{
|
||||
R_API int r_str_hash(const char *str) {
|
||||
int i = 1;
|
||||
int a = 0x31;
|
||||
int b = 0x337;
|
||||
int h = str[0];
|
||||
for(; str[i]; i++) {
|
||||
h+=str[i]*i*a;
|
||||
a*=b;
|
||||
for (; str[i]; i++) {
|
||||
h += str[i]*i*a;
|
||||
a *= b;
|
||||
}
|
||||
return h&0x7fffffff;
|
||||
}
|
||||
|
||||
R_API int r_str_delta(char *p, char a, char b)
|
||||
{
|
||||
char *_a = strchr(p, a);
|
||||
char *_b = strchr(p, b);
|
||||
if (!_a||!_b) return 0;
|
||||
return (_a-_b);
|
||||
R_API int r_str_delta(char *p, char a, char b) {
|
||||
char *_a = strchr (p, a);
|
||||
char *_b = strchr (p, b);
|
||||
return (!_a||!_b)?0:(_a-_b);
|
||||
}
|
||||
|
||||
R_API int r_str_word_set0(char *str)
|
||||
{
|
||||
int i;
|
||||
R_API int r_str_word_set0(char *str) { int i;
|
||||
char *p;
|
||||
if (str[0]=='\0')
|
||||
return 0;
|
||||
/* TODO: sync with r1 code */
|
||||
for(i=1,p=str;p[0];p=p+1)if(*p==' '){i++;*p='\0';} // s/ /\0/g
|
||||
for (i=1,p=str; p[0]; p++)
|
||||
if (*p==' ') {
|
||||
i++;
|
||||
*p='\0';
|
||||
} // s/ /\0/g
|
||||
return i;
|
||||
}
|
||||
|
||||
R_API char *r_str_word_get0(char *str, int idx)
|
||||
{
|
||||
R_API char *r_str_word_get0(char *str, int idx) {
|
||||
int i;
|
||||
char *ptr = str;
|
||||
if (ptr == NULL)
|
||||
@ -92,107 +89,90 @@ R_API char *r_str_word_get0(char *str, int idx)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
R_API int r_str_char_count(const char *string, char ch)
|
||||
{
|
||||
int i, count=0;
|
||||
for(i=0;string[i];i++)
|
||||
R_API int r_str_char_count(const char *string, char ch) {
|
||||
int i, count = 0;
|
||||
for (i=0; string[i]; i++)
|
||||
if (string[i]==ch)
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
R_API int r_str_word_count(const char *string)
|
||||
{
|
||||
R_API int r_str_word_count(const char *string) {
|
||||
const char *text, *tmp;
|
||||
int word = 0;
|
||||
int word;
|
||||
|
||||
for(text=tmp=string;(*text)&&(isseparator(*text));text++);
|
||||
|
||||
for(word = 0; *text; word++) {
|
||||
for(;*text && !isseparator(*text);text = text +1);
|
||||
tmp = text;
|
||||
for(;*text &&isseparator(*text);text = text +1);
|
||||
if (tmp == text)
|
||||
word-=1;
|
||||
for (text = tmp = string; *text && isseparator (*text); text++);
|
||||
for (word = 0; *text; word++) {
|
||||
for (;*text && !isseparator (*text); text++);
|
||||
for (tmp = text; *text && isseparator (*text); text++);
|
||||
if (tmp == text) word--;
|
||||
}
|
||||
|
||||
return word-1;
|
||||
}
|
||||
|
||||
R_API char *r_str_ichr(char *str, char chr)
|
||||
{
|
||||
while(*str==chr) {
|
||||
R_API char *r_str_ichr(char *str, char chr) {
|
||||
while (*str==chr)
|
||||
str = str+1;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
R_API char *r_str_lchr(char *str, char chr)
|
||||
{
|
||||
R_API char *r_str_lchr(char *str, char chr) {
|
||||
int len = strlen(str)+1;
|
||||
for(;len>=0;len--)
|
||||
for (;len>=0;len--)
|
||||
if (str[len]==chr)
|
||||
return str+len;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API int r_str_nchr(const char *str, char chr)
|
||||
{
|
||||
int n = 0;
|
||||
while(str[0]) {
|
||||
if (str[0]==chr)
|
||||
R_API int r_str_nchr(const char *str, char chr) {
|
||||
int n;
|
||||
for (n = 0; *str; str++)
|
||||
if (*str==chr)
|
||||
n++;
|
||||
str = str+1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
R_API int r_str_nstr(char *from, char *to, int size)
|
||||
{
|
||||
R_API int r_str_nstr(char *from, char *to, int size) {
|
||||
int i;
|
||||
for(i=0;i<size;i++)
|
||||
if (from==NULL||to==NULL||from[i]!=to[i])
|
||||
for (i=0; i<size; i++)
|
||||
if (from==NULL || to==NULL || from[i]!=to[i])
|
||||
break;
|
||||
return (size!=i);
|
||||
}
|
||||
|
||||
R_API const char *r_str_chop_ro(const char *str)
|
||||
{
|
||||
R_API const char *r_str_chop_ro(const char *str) {
|
||||
if (str)
|
||||
while(str[0]&&iswhitechar(str[0]))
|
||||
str = str + 1;
|
||||
while (*str && iswhitechar (*str))
|
||||
str++;
|
||||
return str;
|
||||
}
|
||||
|
||||
R_API char *r_str_new(char *str)
|
||||
{
|
||||
return strdup(str);
|
||||
R_API char *r_str_new(char *str) {
|
||||
return strdup (str);
|
||||
}
|
||||
|
||||
R_API char *r_str_chop(char *str)
|
||||
{
|
||||
R_API char *r_str_chop(char *str) {
|
||||
int len;
|
||||
char *ptr;
|
||||
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
|
||||
while(str[0]&&iswhitechar(str[0]))
|
||||
while (*str && iswhitechar (*str))
|
||||
str = str + 1;
|
||||
|
||||
len = strlen(str);
|
||||
|
||||
if (len>0)
|
||||
for(ptr = str+len-1;ptr!=str;ptr = ptr - 1) {
|
||||
if (iswhitechar(ptr[0]))
|
||||
ptr[0]='\0';
|
||||
else break;
|
||||
for (ptr = str+len-1;ptr!=str;ptr = ptr - 1) {
|
||||
if (iswhitechar (ptr[0]))
|
||||
*ptr = '\0';
|
||||
else break;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
R_API char *r_str_trim_head(char *str)
|
||||
{
|
||||
R_API char *r_str_trim_head(char *str) {
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
while (*str && iswhitechar(*str))
|
||||
@ -200,8 +180,7 @@ R_API char *r_str_trim_head(char *str)
|
||||
return str;
|
||||
}
|
||||
|
||||
R_API char *r_str_trim_tail(char *str)
|
||||
{
|
||||
R_API char *r_str_trim_tail(char *str) {
|
||||
char *ptr = str;
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
@ -213,37 +192,33 @@ R_API char *r_str_trim_tail(char *str)
|
||||
return str;
|
||||
}
|
||||
|
||||
R_API char *r_str_trim_head_tail(char *str)
|
||||
{
|
||||
R_API char *r_str_trim_head_tail(char *str) {
|
||||
return r_str_trim_tail(r_str_trim_head(str));
|
||||
}
|
||||
|
||||
R_API char *r_str_trim(char *str)
|
||||
{
|
||||
R_API char *r_str_trim(char *str) {
|
||||
int i;
|
||||
char *ptr;
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
for(ptr=str, i=0;str[i];i++)
|
||||
if (!iswhitechar(str[i]))
|
||||
*ptr++=str[i];
|
||||
for (ptr=str, i=0;str[i];i++)
|
||||
if (!iswhitechar (str[i]))
|
||||
*ptr++ = str[i];
|
||||
*ptr='\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
/* memccmp("foo.bar", "foo.cow, '.') == 0 */
|
||||
R_API int r_str_ccmp(const char *dst, const char *src, int ch)
|
||||
{
|
||||
R_API int r_str_ccmp(const char *dst, const char *src, int ch) {
|
||||
int i;
|
||||
for(i=0;src[i] && src[i] != ch; i++)
|
||||
for (i=0;src[i] && src[i] != ch; i++)
|
||||
if (dst[i] != src[i])
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
R_API int r_str_cmp(const char *a, const char *b, int len)
|
||||
{
|
||||
for(;len--;) {
|
||||
R_API int r_str_cmp(const char *a, const char *b, int len) {
|
||||
for (;len--;) {
|
||||
if (*a=='\0'||*b=='\0'||*a!=*b)
|
||||
return 1;
|
||||
a=a+1;
|
||||
@ -252,8 +227,7 @@ R_API int r_str_cmp(const char *a, const char *b, int len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
R_API int r_str_ccpy(char *dst, char *src, int ch)
|
||||
{
|
||||
R_API int r_str_ccpy(char *dst, char *src, int ch) {
|
||||
int i;
|
||||
for(i=0;src[i] && src[i] != ch; i++)
|
||||
dst[i] = src[i];
|
||||
@ -261,47 +235,39 @@ R_API int r_str_ccpy(char *dst, char *src, int ch)
|
||||
return i;
|
||||
}
|
||||
|
||||
R_API char *r_str_word_get_first(const char *string)
|
||||
{
|
||||
char *text = (char *)string;
|
||||
char *start = NULL;
|
||||
char *ret = NULL;
|
||||
int len = 0;
|
||||
R_API char *r_str_word_get_first(const char *text) {
|
||||
char *ret;
|
||||
int len = 0;
|
||||
|
||||
for(;*text &&isseparator(*text);text = text + 1);
|
||||
start = text;
|
||||
for(;*text &&!isseparator(*text);text = text + 1) len++;
|
||||
for (;*text && isseparator (*text); text++);
|
||||
|
||||
/* strdup */
|
||||
ret = (char *)malloc(len+1);
|
||||
if (ret == 0) {
|
||||
fprintf(stderr, "Cannot allocate %d bytes.\n", len+1);
|
||||
ret = (char *)malloc (len+1);
|
||||
if (ret == NULL) {
|
||||
eprintf ("Cannot allocate %d bytes.\n", len+1);
|
||||
exit(1);
|
||||
}
|
||||
strncpy(ret, start, len);
|
||||
strncpy (ret, text, len);
|
||||
ret[len]='\0';
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
R_API const char *r_str_get(const char *str)
|
||||
{
|
||||
R_API const char *r_str_get(const char *str) {
|
||||
if (str == NULL)
|
||||
return nullstr_c;
|
||||
return str;
|
||||
}
|
||||
|
||||
R_API char *r_str_dup(char *ptr, const char *string)
|
||||
{
|
||||
R_API char *r_str_dup(char *ptr, const char *string) {
|
||||
if (ptr)
|
||||
free(ptr);
|
||||
ptr = strdup(string);
|
||||
free (ptr);
|
||||
ptr = strdup (string);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// TODO: rename to r_str_dupfmt
|
||||
R_API char *r_str_dup_printf(const char *fmt, ...)
|
||||
{
|
||||
R_API char *r_str_dup_printf(const char *fmt, ...) {
|
||||
char *ret;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
@ -315,49 +281,44 @@ R_API char *r_str_dup_printf(const char *fmt, ...)
|
||||
/*
|
||||
* return: the pointer ptr resized to string size.
|
||||
*/
|
||||
R_API char *r_str_concat(char *ptr, const char *string)
|
||||
{
|
||||
R_API char *r_str_concat(char *ptr, const char *string) {
|
||||
if (!ptr)
|
||||
return strdup(string);
|
||||
ptr = realloc(ptr, strlen(string)+strlen(ptr)+1);
|
||||
return strdup (string);
|
||||
ptr = realloc (ptr, strlen (string)+strlen (ptr)+1);
|
||||
if (ptr == NULL)
|
||||
return NULL;
|
||||
strcat(ptr, string);
|
||||
strcat (ptr, string);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
R_API char *r_str_concatf(char *ptr, const char *fmt, ...)
|
||||
{
|
||||
R_API char *r_str_concatf(char *ptr, const char *fmt, ...) {
|
||||
char string[1024];
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(string, 1023, fmt, ap);
|
||||
ptr = r_str_concat(ptr, string);
|
||||
va_end(ap);
|
||||
va_start (ap, fmt);
|
||||
vsnprintf (string, 1023, fmt, ap);
|
||||
ptr = r_str_concat (ptr, string);
|
||||
va_end (ap);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
R_API void r_str_concatch(char *x, char y)
|
||||
{
|
||||
R_API void r_str_concatch(char *x, char y) {
|
||||
char b[2]={y,0};
|
||||
strcat(x,b);
|
||||
strcat (x,b);
|
||||
}
|
||||
|
||||
R_API void *r_str_free(void *ptr)
|
||||
{
|
||||
R_API void *r_str_free(void *ptr) {
|
||||
free (ptr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API int r_str_inject(char *begin, char *end, char *str, int maxlen)
|
||||
{
|
||||
R_API int r_str_inject(char *begin, char *end, char *str, int maxlen) {
|
||||
int len = strlen(end)+1;
|
||||
char *tmp = alloca(len);
|
||||
if (maxlen > 0 && ((strlen(begin)-(end-begin)+strlen(str)) > maxlen))
|
||||
if (maxlen > 0 && ((strlen (begin)-(end-begin)+strlen(str)) > maxlen))
|
||||
return 0;
|
||||
memcpy (tmp, end, len);
|
||||
strcpy (begin, str);
|
||||
strcat(begin, tmp);
|
||||
strcpy (begin, str);
|
||||
strcat (begin, tmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -376,21 +337,18 @@ R_API int r_str_inject(char *begin, char *end, char *str, int maxlen)
|
||||
replace all occurrences, otherwise replace only the first.
|
||||
This returns a new string; the caller should free it. */
|
||||
|
||||
static int strsub_memcmp (char *string, char *pat, int len)
|
||||
{
|
||||
int res = 0;
|
||||
while(len--) {
|
||||
static int strsub_memcmp (char *string, char *pat, int len) {
|
||||
int res;
|
||||
for (res = 0; len-->0; pat++) {
|
||||
if (*pat!='?')
|
||||
res += *string - *pat;
|
||||
string = string+1;
|
||||
pat = pat+1;
|
||||
string++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// TODO: rename r_str_replace
|
||||
R_API char *r_str_sub(char *string, char *pat, char *rep, int global)
|
||||
{
|
||||
R_API char *r_str_sub(char *string, char *pat, char *rep, int global) {
|
||||
int patlen, templen, tempsize, repl, i;
|
||||
char *temp, *r;
|
||||
|
||||
@ -414,71 +372,64 @@ R_API char *r_str_sub(char *string, char *pat, char *rep, int global)
|
||||
return (temp);
|
||||
}
|
||||
|
||||
R_API char *r_str_clean(char *str)
|
||||
{
|
||||
R_API char *r_str_clean(char *str) {
|
||||
int len;
|
||||
char *ptr;
|
||||
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
|
||||
while (str[0] && iswhitechar (str[0]))
|
||||
str = str + 1;
|
||||
|
||||
len = strlen(str);
|
||||
|
||||
if (len>0)
|
||||
for (ptr = str+len-1;ptr!=str;ptr = ptr - 1) {
|
||||
if (iswhitechar (ptr[0]))
|
||||
ptr[0]='\0';
|
||||
else break;
|
||||
if (str != NULL) {
|
||||
while (str[0] && iswhitechar (str[0]))
|
||||
str = str + 1;
|
||||
if ((len = strlen(str))>0)
|
||||
for (ptr = str+len-1;ptr!=str;ptr = ptr - 1) {
|
||||
if (iswhitechar (ptr[0]))
|
||||
ptr[0]='\0';
|
||||
else break;
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
R_API int r_str_escape(char *buf)
|
||||
{
|
||||
R_API int r_str_escape(char *buf) {
|
||||
unsigned char ch = 0, ch2 = 0;
|
||||
int err = 0;
|
||||
int i;
|
||||
|
||||
for(i=0;buf[i];i++) {
|
||||
if (buf[i]=='\\') {
|
||||
if (buf[i+1]=='e') {
|
||||
buf[i] = 0x1b;
|
||||
strcpy(buf+i+1, buf+i+2);
|
||||
} else if (buf[i+1]=='r') {
|
||||
buf[i] = 0x0d;
|
||||
strcpy(buf+i+1, buf+i+2);
|
||||
} else if (buf[i+1]=='n') {
|
||||
buf[i] = 0x0a;
|
||||
strcpy(buf+i+1, buf+i+2);
|
||||
} else if (buf[i+1]=='x') {
|
||||
err = ch2 = ch = 0;
|
||||
if (!buf[i+2] || !buf[i+3]) {
|
||||
printf("Unexpected end of string.\n");
|
||||
return 0;
|
||||
}
|
||||
err |= hex2int(&ch, buf[i+2]);
|
||||
err |= hex2int(&ch2, buf[i+3]);
|
||||
if (err) {
|
||||
printf("Incorrect hexadecimal characters for conversion.\n");
|
||||
return 0;
|
||||
}
|
||||
buf[i] = (ch<<4)+ch2;
|
||||
strcpy(buf+i+1, buf+i+4);
|
||||
} else {
|
||||
printf("'\\x' expected.\n");
|
||||
for (i=0; buf[i]; i++) {
|
||||
// only parse scaped characters //
|
||||
if (buf[i]!='\\')
|
||||
continue;
|
||||
if (buf[i+1]=='e') {
|
||||
buf[i] = 0x1b;
|
||||
strcpy (buf+i+1, buf+i+2);
|
||||
} else if (buf[i+1]=='r') {
|
||||
buf[i] = 0x0d;
|
||||
strcpy (buf+i+1, buf+i+2);
|
||||
} else if (buf[i+1]=='n') {
|
||||
buf[i] = 0x0a;
|
||||
strcpy (buf+i+1, buf+i+2);
|
||||
} else if (buf[i+1]=='x') {
|
||||
err = ch2 = ch = 0;
|
||||
if (!buf[i+2] || !buf[i+3]) {
|
||||
eprintf ("Unexpected end of string.\n");
|
||||
return 0;
|
||||
}
|
||||
err |= hex2int (&ch, buf[i+2]);
|
||||
err |= hex2int (&ch2, buf[i+3]);
|
||||
if (err) {
|
||||
eprintf ("Incorrect hexadecimal characters for conversion.\n");
|
||||
return 0;
|
||||
}
|
||||
buf[i] = (ch<<4)+ch2;
|
||||
strcpy (buf+i+1, buf+i+4);
|
||||
} else {
|
||||
eprintf ("'\\x' expected.\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/* ansi helpers */
|
||||
R_API int r_str_ansi_len(const char *str)
|
||||
{
|
||||
R_API int r_str_ansi_len(const char *str) {
|
||||
int i=0, len = 0;
|
||||
while (str[i]) {
|
||||
if (str[i]==0x1b && str[i+1]=='[')
|
||||
@ -489,20 +440,78 @@ R_API int r_str_ansi_len(const char *str)
|
||||
return len;
|
||||
}
|
||||
|
||||
R_API const char *r_str_ansi_chrn(const char *str, int n)
|
||||
{
|
||||
int i=0, len = 0;
|
||||
while(str[i]) {
|
||||
if (n == len)
|
||||
break;
|
||||
R_API const char *r_str_ansi_chrn(const char *str, int n) {
|
||||
int len, i;
|
||||
for (i=len=0; str[i] && (n!=len); i++) {
|
||||
if (str[i]==0x1b && str[i+1]=='[')
|
||||
for(++i;str[i]&&str[i]!='J'&&str[i]!='m'&&str[i]!='H';i++);
|
||||
for (++i;str[i]&&str[i]!='J'&&str[i]!='m'&&str[i]!='H';i++);
|
||||
else len++;
|
||||
i++;
|
||||
}
|
||||
return str+i;
|
||||
}
|
||||
|
||||
#define MAXARG 128
|
||||
R_API char **r_str_argv(const char *_str, int *_argc) {
|
||||
int argc = 0;
|
||||
int escape = 0;
|
||||
int quote = 0;
|
||||
char *optr, *ptr, *str = strdup (_str);
|
||||
char **argv = (char **)malloc (MAXARG*sizeof(char*));
|
||||
|
||||
optr = ptr = r_str_chop_ro (str);
|
||||
for (; *ptr && argc<MAXARG; ptr++) {
|
||||
switch (*ptr) {
|
||||
case '\'':
|
||||
case '"':
|
||||
if (escape) {
|
||||
escape = 0;
|
||||
strcpy (ptr, ptr+1);
|
||||
} else {
|
||||
if (quote) {
|
||||
*ptr = '\0';
|
||||
argv[argc++] = optr;
|
||||
optr = ptr+1;
|
||||
quote = 0;
|
||||
} else {
|
||||
quote = *ptr;
|
||||
optr = ptr+1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '\\':
|
||||
escape = 1;
|
||||
break;
|
||||
case ' ':
|
||||
if (!escape && !quote) {
|
||||
*ptr = '\0';
|
||||
if (*optr) {
|
||||
argv[argc++] = optr;
|
||||
optr = ptr+1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
escape = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*optr) {
|
||||
argv[argc++] = optr;
|
||||
optr = ptr+1;
|
||||
}
|
||||
argv[argc] = NULL;
|
||||
if (_argc)
|
||||
*_argc = argc;
|
||||
return argv;
|
||||
}
|
||||
|
||||
R_API void r_str_argv_free(char **argv) {
|
||||
// TODO: free the internal food or just the first element
|
||||
// free (argv[0]); // MEMORY LEAK
|
||||
free (argv);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* XXX this is necessary ??? */
|
||||
// TODO: make it dynamic
|
||||
@ -531,39 +540,3 @@ R_API char *r_bprintf_get()
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
int r_str_argv_parse(const char *str, int argc, char **argv)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
int i = 0;
|
||||
char *tmp, *tmp2;
|
||||
free(ps.args);
|
||||
ps.args = strdup(ps.filename);
|
||||
tmp2 = ps.args;
|
||||
// parse argv
|
||||
//eprintf("commandline=\"%s\"\n", ps.args);
|
||||
for(tmp=ps.args;tmp[0];tmp=tmp+1) {
|
||||
if (tmp[0]==' '&&tmp!=ps.args) { if ((tmp[-1]=='\\') || (tmp[-1]=='/'))
|
||||
continue;
|
||||
tmp[0]='\0';
|
||||
ps.argv[i] = tmp2;
|
||||
tmp2 = tmp+1;
|
||||
if (++i>254) {
|
||||
printf("Too many arguments. truncated\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ps.argv[i] = tmp2;
|
||||
ps.argv[i+1] = 0;
|
||||
|
||||
tmp = strchr(config.file, ' ');
|
||||
if (tmp) *tmp = '\0';
|
||||
//config.file = strdup("/bin/ls"); //ps.argv[0];
|
||||
//eprintf("ppa:A0(%s)\n", ps.argv[0]);
|
||||
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
@ -4,7 +4,7 @@ ifeq ($(WITHPIC),1)
|
||||
# OSX
|
||||
FLAGS=-I../../include -L.. -lr_util -g -DVERSION=\"${VERSION}\"
|
||||
#FLAGS=-I../../include -Wl,-R.. -L.. -lr_util -g -DVERSION=\"${VERSION}\"
|
||||
EFLAGS=
|
||||
EFLAGS=-L.. -lr_util
|
||||
else
|
||||
FLAGS=-I../../include -g -DVERSION=\"${VERSION}\"
|
||||
EFLAGS=../libr_util.a
|
||||
@ -15,6 +15,7 @@ BINS+=rax2${EXT_EXE}
|
||||
BINS+=ralloc${EXT_EXE}
|
||||
BINS+=array${EXT_EXE}
|
||||
BINS+=pool${EXT_EXE}
|
||||
BINS+=argv${EXT_EXE}
|
||||
BINS+=test_sys${EXT_EXE}
|
||||
BINS+=test_str${EXT_EXE}
|
||||
BINS+=test_file_slurp_hexpairs${EXT_EXE}
|
||||
@ -28,6 +29,9 @@ ralloc${EXT_EXE}:
|
||||
test${EXT_EXE}:
|
||||
${CC} ${FLAGS} test.c ${EFLAGS} -o test${EXT_EXE}
|
||||
|
||||
argv${EXT_EXE}:
|
||||
${CC} ${FLAGS} argv.c ${EFLAGS} -o argv${EXT_EXE}
|
||||
|
||||
test_sys${EXT_EXE}: test_sys.c
|
||||
${CC} ${FLAGS} test_sys.c ${EFLAGS} -o test_sys${EXT_EXE}
|
||||
|
||||
|
19
libr/util/t/argv.c
Normal file
19
libr/util/t/argv.c
Normal file
@ -0,0 +1,19 @@
|
||||
#include <r_util.h>
|
||||
|
||||
static void test(const char *str) {
|
||||
int i, argc;
|
||||
char **argv = r_str_argv (str, &argc);
|
||||
printf ("[%s]\n", str);
|
||||
for(i=0; i<argc; i++)
|
||||
printf (" - %s\n", argv[i]);
|
||||
r_str_argv_free (argv);
|
||||
}
|
||||
|
||||
main () {
|
||||
test (" hello world ");
|
||||
test ("hello world");
|
||||
test ("hello \"world\"");
|
||||
test ("'hello world'");
|
||||
test ("/bin/ls -l 'food is pure bar' \"barra cow is low\"");
|
||||
test ("'hello' \"world\"");
|
||||
}
|
@ -20,7 +20,7 @@ while(<STDIN>) {
|
||||
s/:/\n\t/;
|
||||
/(.*):/;
|
||||
$file = $1;
|
||||
print "$path/$_" if ($file ne $ofile)
|
||||
print "$path/$_" if ($file ne $ofile);
|
||||
$ofile = $file;
|
||||
}
|
||||
#{ print "$path/".$line; }
|
||||
|
Loading…
Reference in New Issue
Block a user