mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-19 12:22:43 +00:00
Add CS
command to manage meta-spaces
This commit is contained in:
parent
e58c46c0cc
commit
8d0b8c6b78
@ -23,7 +23,7 @@ Move around the bytes with h,j,k,l! Arrow keys are neither portable nor efficien
|
||||
Seek at relative offsets with 's +<offset>' or 's -<offset>'
|
||||
Invert the block bytes using the 'I' key in visual mode
|
||||
Switch between print modes using the 'p' and 'P' keys in visual mode
|
||||
Add comments using the ';' key in visual mode or the 'C' command from the radare2 shell
|
||||
Add comments using the ';' key in visual mode or the 'CC' command from the radare2 shell
|
||||
Assemble opcodes with the 'a' and 'A' keys in visual mode, which are bindings to the 'wa' and 'wA' commands
|
||||
Find expanded AES keys in memory with '/Ca'
|
||||
Find wide-char strings with the '/w <string>' command
|
||||
|
@ -57,6 +57,20 @@ R_API void r_anal_unset_limits(RAnal *anal) {
|
||||
anal->limit = NULL;
|
||||
}
|
||||
|
||||
static void meta_unset_for(void *user, int idx) {
|
||||
RSpaces *s = (RSpaces*)user;
|
||||
RAnal *anal = (RAnal*)s->user;
|
||||
r_meta_space_unset_for (anal, idx);
|
||||
}
|
||||
|
||||
static int meta_count_for(void *user, int idx) {
|
||||
int ret;
|
||||
RSpaces *s = (RSpaces*)user;
|
||||
RAnal *anal = (RAnal*)s->user;
|
||||
ret = r_meta_space_count_for (anal, idx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
R_API RAnal *r_anal_new() {
|
||||
int i;
|
||||
RAnalPlugin *static_plugin;
|
||||
@ -70,6 +84,8 @@ R_API RAnal *r_anal_new() {
|
||||
anal->sdb = sdb_new0 ();
|
||||
anal->sdb_fcns = sdb_ns (anal->sdb, "fcns", 1);
|
||||
anal->sdb_meta = sdb_ns (anal->sdb, "meta", 1);
|
||||
r_space_init (&anal->meta_spaces,
|
||||
meta_unset_for, meta_count_for, anal);
|
||||
anal->sdb_hints = sdb_ns (anal->sdb, "hints", 1);
|
||||
anal->sdb_xrefs = sdb_ns (anal->sdb, "xrefs", 1);
|
||||
//anal->sdb_vars = sdb_ns (anal->sdb, "vars", 1); // its inside fcns right now
|
||||
@ -126,6 +142,7 @@ R_API RAnal *r_anal_free(RAnal *a) {
|
||||
r_list_free (a->fcns);
|
||||
// might provoke double frees since this is used in r_anal_fcn_insert()
|
||||
//r_listrange_free (a->fcnstore);
|
||||
r_space_fini (&a->meta_spaces);
|
||||
r_list_free (a->refs);
|
||||
r_list_free (a->types);
|
||||
r_reg_free (a->reg);
|
||||
|
144
libr/anal/meta.c
144
libr/anal/meta.c
@ -101,6 +101,7 @@ R_API int r_meta_set_string(RAnal *a, int type, ut64 addr, const char *s) {
|
||||
char key[100], val[2048], *e_str;
|
||||
int ret;
|
||||
ut64 size;
|
||||
int space_idx = a->meta_spaces.space_idx;
|
||||
meta_type_add (a, type, addr);
|
||||
|
||||
snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, type, addr);
|
||||
@ -111,7 +112,7 @@ R_API int r_meta_set_string(RAnal *a, int type, ut64 addr, const char *s) {
|
||||
ret = R_TRUE;
|
||||
} else ret = R_FALSE;
|
||||
e_str = sdb_encode ((const void*)s, -1);
|
||||
snprintf (val, sizeof (val)-1, "%d,%s", (int)size, e_str);
|
||||
snprintf (val, sizeof (val)-1, "%d,%d,%s", (int)size, space_idx, e_str);
|
||||
sdb_set (DB, key, val, 0);
|
||||
free ((void*)e_str);
|
||||
return ret;
|
||||
@ -193,8 +194,9 @@ R_API RAnalMetaItem *r_meta_item_new(int type) {
|
||||
}
|
||||
|
||||
R_API int r_meta_add(RAnal *a, int type, ut64 from, ut64 to, const char *str) {
|
||||
int exists;
|
||||
int space_idx = a->meta_spaces.space_idx;
|
||||
char *e_str, key[100], val[2048];
|
||||
int exists;
|
||||
if (from>to)
|
||||
return R_FALSE;
|
||||
if (from == to)
|
||||
@ -205,8 +207,9 @@ R_API int r_meta_add(RAnal *a, int type, ut64 from, ut64 to, const char *str) {
|
||||
/* set entry */
|
||||
e_str = sdb_encode ((const void*)str, -1);
|
||||
snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, type, from);
|
||||
snprintf (val, sizeof (val)-1, "%d,%s", (int)(to-from), e_str);
|
||||
snprintf (val, sizeof (val)-1, "%d,%d,%s", (int)(to-from), space_idx, e_str);
|
||||
exists = sdb_exists (DB, key);
|
||||
|
||||
sdb_set (DB, key, val, 0);
|
||||
free (e_str);
|
||||
|
||||
@ -250,7 +253,7 @@ R_API RAnalMetaItem *r_meta_find(RAnal *a, ut64 off, int type, int where) {
|
||||
|
||||
R_API const char *r_meta_type_to_string(int type) {
|
||||
// XXX: use type as '%c'
|
||||
switch(type) {
|
||||
switch (type) {
|
||||
case R_META_TYPE_HIDE: return "Ch";
|
||||
case R_META_TYPE_CODE: return "Cc";
|
||||
case R_META_TYPE_DATA: return "Cd";
|
||||
@ -263,15 +266,22 @@ R_API const char *r_meta_type_to_string(int type) {
|
||||
}
|
||||
|
||||
static void printmetaitem(RAnal *a, RAnalMetaItem *d, int rad) {
|
||||
char *pstr, *str = r_str_escape (d->str);
|
||||
char *pstr, *str;
|
||||
//eprintf ("%d %d\n", d->space, a->meta_spaces.space_idx);
|
||||
if (a->meta_spaces.space_idx != -1) {
|
||||
if (a->meta_spaces.space_idx != d->space) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
str = r_str_escape (d->str);
|
||||
if (str || d->type == 'd') {
|
||||
if (d->type=='s' && !*str) {
|
||||
free (str);
|
||||
return;
|
||||
}
|
||||
if (!str)
|
||||
if (!str) {
|
||||
pstr = "";
|
||||
else if (d->type != 'C') {
|
||||
} else if (d->type != 'C') {
|
||||
r_name_filter (str, 0);
|
||||
pstr = str;
|
||||
} else pstr = d->str;
|
||||
@ -369,6 +379,8 @@ static void printmetaitem(RAnal *a, RAnalMetaItem *d, int rad) {
|
||||
}
|
||||
|
||||
static int meta_print_item(void *user, const char *k, const char *v) {
|
||||
// const char *v; // size
|
||||
const char *v2; // space_idx
|
||||
RAnalMetaUserItem *ui = user;
|
||||
RAnalMetaItem it;
|
||||
if (strlen (k)<8)
|
||||
@ -378,17 +390,22 @@ static int meta_print_item(void *user, const char *k, const char *v) {
|
||||
it.type = k[5];
|
||||
it.size = sdb_atoi (v);
|
||||
it.from = sdb_atoi (k+7);
|
||||
|
||||
v2 = strchr (v, ',');
|
||||
if (!v2) goto beach;
|
||||
it.space = atoi (v2+1);
|
||||
it.to = it.from + it.size;
|
||||
it.str = strchr (v, ',');
|
||||
it.str = strchr (v2+1, ',');
|
||||
if (it.str)
|
||||
it.str = (char *)sdb_decode ((const char*)it.str+1, 0);
|
||||
printmetaitem (ui->anal, &it, ui->rad);
|
||||
beach:
|
||||
free (it.str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
R_API int r_meta_list_cb(RAnal *a, int type, int rad, SdbForeachCallback cb, void *user) {
|
||||
RAnalMetaUserItem ui = { a, type, rad, cb, user };
|
||||
RAnalMetaUserItem ui = { a, type, rad, cb, user, 0 };
|
||||
if (rad=='j') a->printf ("[");
|
||||
if (cb) {
|
||||
sdb_foreach (DB, cb, &ui);
|
||||
@ -396,13 +413,120 @@ R_API int r_meta_list_cb(RAnal *a, int type, int rad, SdbForeachCallback cb, voi
|
||||
sdb_foreach (DB, meta_print_item, &ui);
|
||||
}
|
||||
if (rad=='j') a->printf ("]\n");
|
||||
return 0;
|
||||
return ui.count;
|
||||
}
|
||||
|
||||
R_API int r_meta_list(RAnal *a, int type, int rad) {
|
||||
return r_meta_list_cb (a, type, rad, NULL, NULL);
|
||||
}
|
||||
|
||||
static int meta_enumerate_cb(void *user, const char *k, const char *v) {
|
||||
const char *v2;
|
||||
RAnalMetaUserItem *ui = user;
|
||||
RList *list = ui->user;
|
||||
//RAnal *a = ui->anal;
|
||||
RAnalMetaItem *it;
|
||||
if (strlen (k)<8)
|
||||
return 1;
|
||||
if (memcmp (k+6, ".0x", 3))
|
||||
return 1;
|
||||
it = R_NEW0 (RAnalMetaItem);
|
||||
it->type = k[5];
|
||||
it->size = sdb_atoi (v);
|
||||
it->from = sdb_atoi (k+7);
|
||||
it->to = it->from + it->size;
|
||||
v2 = strchr (v, ',');
|
||||
if (!v2) goto beach;
|
||||
it->space = atoi (v2+1);
|
||||
it->str = strchr (v2+1, ',');
|
||||
|
||||
if (it->str)
|
||||
it->str = (char *)sdb_decode ((const char*)it->str+1, 0);
|
||||
//printmetaitem (ui->anal, &it, ui->rad);
|
||||
r_list_append (list, it);
|
||||
beach:
|
||||
return 1;
|
||||
}
|
||||
|
||||
R_API RList *r_meta_enumerate(RAnal *a, int type) {
|
||||
RList *list = r_list_new ();
|
||||
r_meta_list_cb (a, type, 0, meta_enumerate_cb, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
static int deserialize(RAnalMetaItem *it, const char *k, const char *v) {
|
||||
const char *v2;
|
||||
if (strlen (k)<8)
|
||||
return 1;
|
||||
if (memcmp (k+6, ".0x", 3))
|
||||
return 1;
|
||||
it->type = k[5];
|
||||
it->size = sdb_atoi (v);
|
||||
it->from = sdb_atoi (k+7);
|
||||
it->to = it->from + it->size;
|
||||
v2 = strchr (v, ',');
|
||||
if (!v2) goto beach;
|
||||
it->space = atoi (v2+1);
|
||||
it->str = strchr (v2+1, ',');
|
||||
//printmetaitem (ui->anal, &it, ui->rad);
|
||||
beach:
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void serialize(RAnalMetaItem *it, char *k, char *v) {
|
||||
sprintf (k, "meta.%c.0x%"PFMT64x, it->type, it->from);
|
||||
snprintf (v, 4095, "%d,%d,%s", (int)it->size, it->space, it->str);
|
||||
}
|
||||
|
||||
static int meta_unset_cb(void *user, const char *k, const char *v) {
|
||||
char nk[128], nv[4096];
|
||||
RAnalMetaUserItem *ui = user;
|
||||
RAnal *a = ui->anal;
|
||||
RAnalMetaItem it;
|
||||
if (!strstr(k, ".0x"))
|
||||
return 1;
|
||||
deserialize (&it, k, v);
|
||||
if (it.space != -1) {
|
||||
it.space = -1;
|
||||
serialize (&it, nk, nv);
|
||||
sdb_set (DB, nk, nv, 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
R_API void r_meta_space_unset_for(RAnal *a, int type) {
|
||||
r_meta_list_cb (a, type, 0, meta_unset_cb, NULL);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
int index;
|
||||
int ctx;
|
||||
} myMetaUser;
|
||||
|
||||
static int meta_count_cb(void *user, const char *k, const char *v) {
|
||||
RAnalMetaUserItem *ui = user;
|
||||
myMetaUser *mu = ui->user;
|
||||
RAnalMetaItem it;
|
||||
if (!strstr(k, ".0x"))
|
||||
return 1;
|
||||
deserialize (&it, k, v);
|
||||
if (mu) {
|
||||
if (it.space == mu->ctx) {
|
||||
mu->count++;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
R_API int r_meta_space_count_for(RAnal *a, int ctx) {
|
||||
myMetaUser mu = {0};
|
||||
mu.ctx = ctx;
|
||||
int type = a->meta_spaces.space_idx;
|
||||
r_meta_list_cb (a, type, 0, meta_count_cb, &mu);
|
||||
return mu.count;
|
||||
}
|
||||
|
||||
#if 0
|
||||
R_API char *r_anal_meta_bar (RAnal *anal, ut64 from, ut64 to, int blocks) {
|
||||
int i, n, blocksize;
|
||||
|
@ -1014,7 +1014,7 @@ static int bin_symbols (RCore *r, int mode, ut64 baddr, ut64 laddr, int va, ut64
|
||||
int i = 0;
|
||||
|
||||
symbols = r_bin_get_symbols (r->bin);
|
||||
|
||||
r_space_set (&r->anal->meta_spaces, "bin");
|
||||
if (mode & R_CORE_BIN_JSON) {
|
||||
r_cons_printf ("[");
|
||||
r_list_foreach (symbols, iter, symbol) {
|
||||
@ -1091,7 +1091,6 @@ static int bin_symbols (RCore *r, int mode, ut64 baddr, ut64 laddr, int va, ut64
|
||||
// set the new sym.[cname].[name] with comment
|
||||
snprintf (str, R_FLAG_NAME_SIZE, "sym.%s.%s", cname, name);
|
||||
fi = r_flag_set (r->flags, str, addr, symbol->size, 0);
|
||||
|
||||
if (comment) {
|
||||
r_flag_item_set_comment (fi, comment);
|
||||
free (comment);
|
||||
@ -1196,6 +1195,7 @@ static int bin_symbols (RCore *r, int mode, ut64 baddr, ut64 laddr, int va, ut64
|
||||
}
|
||||
if (!at && !mode) r_cons_printf ("\n%i symbols\n", i);
|
||||
}
|
||||
r_space_set (&r->anal->meta_spaces, NULL);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
|
@ -548,6 +548,7 @@ static int cmd_meta(void *data, const char *input) {
|
||||
"C*", "", "list meta info in r2 commands",
|
||||
"C-", " [len] [[@]addr]", "delete metadata at given address range",
|
||||
"CL", "[-][*] [file:line] [addr]", "show or add 'code line' information (bininfo)",
|
||||
"CS", "[-][space]", "manage meta-spaces to filter comments, etc..",
|
||||
"CC", "[-] [comment-text] [@addr]", "add/remove comment",
|
||||
"CC!", " [@addr]", "edit comment with $EDITOR",
|
||||
"CCa", "[-at]|[at] [text] [@addr]", "add/remove comment at given address",
|
||||
@ -567,6 +568,80 @@ static int cmd_meta(void *data, const char *input) {
|
||||
if (f) r_anal_str_to_fcn (core->anal, f, input+2);
|
||||
else eprintf ("Cannot find function here\n");
|
||||
break;
|
||||
case 'S':
|
||||
{
|
||||
RSpaces *ms = &core->anal->meta_spaces;
|
||||
/** copypasta from `fs`.. this must be refactorized to be shared */
|
||||
switch (input[1]) {
|
||||
case '?':
|
||||
{
|
||||
const char *help_msg[] = {
|
||||
"Usage: CS","[*] [+-][metaspace|addr]", " # Manage metaspaces",
|
||||
"CS","","display metaspaces",
|
||||
"CS"," *","select all metaspaces",
|
||||
"CS"," metaspace","select metaspace or create if it doesn't exist",
|
||||
"CS","-metaspace","remove metaspace",
|
||||
"CS","-*","remove all metaspaces",
|
||||
"CS","+foo","push previous metaspace and set",
|
||||
"CS","-","pop to the previous metaspace",
|
||||
// "CSm"," [addr]","move metas at given address to the current metaspace",
|
||||
"CSr"," newname","rename selected metaspace",
|
||||
NULL};
|
||||
r_core_cmd_help (core, help_msg);
|
||||
}
|
||||
break;
|
||||
case '+':
|
||||
r_space_push (ms, input+2);
|
||||
break;
|
||||
case 'r':
|
||||
if (input[2]==' ')
|
||||
r_space_rename (ms, NULL, input+2);
|
||||
else eprintf ("Usage: CSr [newname]\n");
|
||||
break;
|
||||
case '-':
|
||||
if (input[2]) {
|
||||
if (input[2]=='*') {
|
||||
r_space_unset (ms, NULL);
|
||||
} else {
|
||||
r_space_unset (ms, input+2);
|
||||
}
|
||||
} else {
|
||||
r_space_pop (ms);
|
||||
}
|
||||
break;
|
||||
case 'j':
|
||||
case '\0':
|
||||
case '*':
|
||||
r_space_list (ms, input[1]);
|
||||
break;
|
||||
case ' ':
|
||||
r_space_set (ms, input+2);
|
||||
break;
|
||||
#if 0
|
||||
case 'm':
|
||||
{ RFlagItem *f;
|
||||
ut64 off = core->offset;
|
||||
if (input[2] == ' ')
|
||||
off = r_num_math (core->num, input+2);
|
||||
f = r_flag_get_i (core->flags, off);
|
||||
if (f) {
|
||||
f->space = core->flags->space_idx;
|
||||
} else eprintf ("Cannot find any flag at 0x%"PFMT64x".\n", off);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default: {
|
||||
int i, j = 0;
|
||||
for (i=0; i<R_FLAG_SPACES_MAX; i++) {
|
||||
if (ms->spaces[i])
|
||||
r_cons_printf ("%02d %c %s\n", j++,
|
||||
(i==ms->space_idx)?'*':' ',
|
||||
ms->spaces[i]);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return R_TRUE;
|
||||
}
|
||||
|
@ -872,6 +872,7 @@ R_API int r_core_init(RCore *core) {
|
||||
core->assembler->num = core->num;
|
||||
r_asm_set_user_ptr (core->assembler, core);
|
||||
core->anal = r_anal_new ();
|
||||
core->anal->meta_spaces.printf = r_cons_printf;
|
||||
core->anal->cb.on_fcn_new = on_fcn_new;
|
||||
core->anal->cb.on_fcn_delete = on_fcn_delete;
|
||||
core->anal->cb.on_fcn_rename = on_fcn_rename;
|
||||
|
@ -14,7 +14,7 @@ R_API int r_flag_space_get(RFlag *f, const char *name) {
|
||||
}
|
||||
|
||||
R_API const char *r_flag_space_get_i (RFlag *f, int idx) {
|
||||
if (idx==-1 || idx>255 || !f || !f->spaces[idx] || !*f->spaces[idx])
|
||||
if (idx==-1 || idx>=R_FLAG_SPACES_MAX || !f || !f->spaces[idx] || !*f->spaces[idx])
|
||||
return "";
|
||||
return f->spaces[idx];
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ typedef struct r_anal_meta_item_t {
|
||||
ut64 size;
|
||||
int type;
|
||||
char *str;
|
||||
int space;
|
||||
} RAnalMetaItem;
|
||||
|
||||
typedef struct {
|
||||
@ -57,6 +58,7 @@ typedef struct {
|
||||
int rad;
|
||||
SdbForeachCallback cb;
|
||||
void *user;
|
||||
int count;
|
||||
} RAnalMetaUserItem;
|
||||
|
||||
typedef struct r_anal_range_t {
|
||||
@ -597,6 +599,7 @@ typedef struct r_anal_t {
|
||||
Sdb *sdb_xrefs;
|
||||
Sdb *sdb_types;
|
||||
Sdb *sdb_meta; // TODO: Future r_meta api
|
||||
RSpaces meta_spaces;
|
||||
PrintfCallback printf;
|
||||
//moved from RAnalFcn
|
||||
Sdb *sdb; // root
|
||||
@ -1346,6 +1349,9 @@ R_API void r_anal_data_free (RAnalData *d);
|
||||
R_API char *r_anal_data_to_string (RAnalData *d);
|
||||
|
||||
R_API void r_meta_free(RAnal *m);
|
||||
R_API void r_meta_space_unset_for(RAnal *a, int type);
|
||||
R_API int r_meta_space_count_for(RAnal *a, int ctx);
|
||||
R_API RList *r_meta_enumerate(RAnal *a, int type);
|
||||
R_API int r_meta_count(RAnal *m, int type, ut64 from, ut64 to);
|
||||
R_API char *r_meta_get_string(RAnal *m, int type, ut64 addr);
|
||||
R_API int r_meta_set_string(RAnal *m, int type, ut64 addr, const char *s);
|
||||
@ -1354,6 +1360,7 @@ R_API int r_meta_add(RAnal *m, int type, ut64 from, ut64 size, const char *str);
|
||||
R_API RAnalMetaItem *r_meta_find(RAnal *m, ut64 off, int type, int where);
|
||||
R_API int r_meta_cleanup(RAnal *m, ut64 from, ut64 to);
|
||||
R_API const char *r_meta_type_to_string(int type);
|
||||
R_API RList *r_meta_enumerate(RAnal *a, int type);
|
||||
R_API int r_meta_list(RAnal *m, int type, int rad);
|
||||
R_API int r_meta_list_cb(RAnal *m, int type, int rad, SdbForeachCallback cb, void *user);
|
||||
R_API void r_meta_item_free(void *_item);
|
||||
|
@ -53,6 +53,18 @@ R_REFCTR_REF (foo)
|
||||
R_REFCTR_UNREF (foo)
|
||||
#endif
|
||||
|
||||
#define R_SPACES_MAX 512
|
||||
|
||||
typedef struct r_space_t {
|
||||
int space_idx;
|
||||
int space_idx2;
|
||||
char *spaces[R_SPACES_MAX];
|
||||
RList *spacestack; // metaspaces
|
||||
PrintfCallback printf;
|
||||
void (*unset_for)(void *user, int idx);
|
||||
int (*count_for)(void *user, int idx);
|
||||
void *user;
|
||||
} RSpaces;
|
||||
|
||||
/* empty classes */
|
||||
typedef struct { } RSystem;
|
||||
@ -763,6 +775,19 @@ R_API char **r_sys_get_environ (void);
|
||||
R_API void r_sys_set_environ (char **e);
|
||||
|
||||
|
||||
/* spaces */
|
||||
|
||||
R_API void r_space_init(RSpaces *f, void (*unset_for)(void*, int), int (*count_for)(void *,int), void *user);
|
||||
R_API void r_space_fini(RSpaces *f);
|
||||
R_API int r_space_get(RSpaces *f, const char *name);
|
||||
R_API const char *r_space_get_i (RSpaces *f, int idx);
|
||||
R_API int r_space_push(RSpaces *f, const char *name);
|
||||
R_API int r_space_pop(RSpaces *f);
|
||||
R_API int r_space_set(RSpaces *f, const char *name);
|
||||
R_API int r_space_unset (RSpaces *f, const char *fs);
|
||||
R_API int r_space_list(RSpaces *f, int mode);
|
||||
R_API int r_space_rename (RSpaces *f, const char *oname, const char *nname);
|
||||
|
||||
/* Some "secured" functions, to do basic operation (mul, sub, add...) on integers */
|
||||
static inline int UT64_ADD(ut64 *r, ut64 a, ut64 b) {
|
||||
if(UT64_MAX - a < b)
|
||||
|
@ -10,7 +10,7 @@ OBJS+=regex/regcomp.o regex/regerror.o regex/regexec.o uleb128.o
|
||||
OBJS+=sandbox.o calc.o thread.o thread_lock.o thread_msg.o
|
||||
OBJS+=strpool.o bitmap.o strht.o p_date.o p_format.o print.o
|
||||
OBJS+=p_seven.o slist.o randomart.o log.o zip.o debruijn.o
|
||||
OBJS+=utf8.o strbuf.o lib.o name.o
|
||||
OBJS+=utf8.o strbuf.o lib.o name.o spaces.o
|
||||
OBJS+=diff.o bdiff.o stack.o queue.o tree.o
|
||||
|
||||
# DO NOT BUILD r_big api (not yet used and its buggy)
|
||||
|
181
libr/util/spaces.c
Normal file
181
libr/util/spaces.c
Normal file
@ -0,0 +1,181 @@
|
||||
/* radare - LGPL - Copyright 2015 - pancake */
|
||||
|
||||
#include <r_anal.h>
|
||||
|
||||
R_API int r_space_get(RSpaces *f, const char *name) {
|
||||
int i;
|
||||
for (i=0; i<R_SPACES_MAX; i++) {
|
||||
if (f->spaces[i] != NULL)
|
||||
if (!strcmp (name, f->spaces[i]))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
R_API const char *r_space_get_i (RSpaces *f, int idx) {
|
||||
if (idx==-1 || idx>=R_SPACES_MAX|| !f || !f->spaces[idx] || !*f->spaces[idx])
|
||||
return "";
|
||||
return f->spaces[idx];
|
||||
}
|
||||
|
||||
R_API void r_space_init(RSpaces *f, void (*unset_for)(void*,int), int (*count_for)(void*,int), void *user) {
|
||||
int i;
|
||||
f->space_idx = -1;
|
||||
f->space_idx2 = -1;
|
||||
f->spacestack = r_list_new ();
|
||||
f->printf = (PrintfCallback)printf;
|
||||
f->unset_for = unset_for;
|
||||
f->count_for = count_for;
|
||||
f->user = user;
|
||||
for (i=0;i<R_SPACES_MAX;i++)
|
||||
f->spaces[i] = NULL;
|
||||
}
|
||||
|
||||
R_API void r_space_fini(RSpaces *f) {
|
||||
int i;
|
||||
for (i=0;i<R_SPACES_MAX;i++) {
|
||||
free (f->spaces[i]);
|
||||
f->spaces[i] = NULL;
|
||||
}
|
||||
r_list_free (f->spacestack);
|
||||
}
|
||||
|
||||
R_API int r_space_push(RSpaces *f, const char *name) {
|
||||
int ret = R_FALSE;
|
||||
if (name && *name) {
|
||||
if (f->space_idx != -1 && f->spaces[f->space_idx]) {
|
||||
r_list_push (f->spacestack, f->spaces[f->space_idx]);
|
||||
} else {
|
||||
r_list_push (f->spacestack, "*");
|
||||
}
|
||||
r_space_set (f, name);
|
||||
ret = R_TRUE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
R_API int r_space_pop(RSpaces *f) {
|
||||
char *p = r_list_pop (f->spacestack);
|
||||
if (p) {
|
||||
if (*p) {
|
||||
r_space_set (f, p);
|
||||
}
|
||||
return R_TRUE;
|
||||
}
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
R_API int r_space_set(RSpaces *f, const char *name) {
|
||||
int i;
|
||||
if (name == NULL || *name == '*') {
|
||||
f->space_idx = -1;
|
||||
return f->space_idx;
|
||||
}
|
||||
|
||||
for (i=0; i<R_SPACES_MAX; i++) {
|
||||
if (f->spaces[i] != NULL)
|
||||
if (!strcmp (name, f->spaces[i])) {
|
||||
f->space_idx = i;
|
||||
return f->space_idx;
|
||||
}
|
||||
}
|
||||
/* not found */
|
||||
for (i=0; i<R_SPACES_MAX; i++) {
|
||||
if (f->spaces[i] == NULL) {
|
||||
f->spaces[i] = strdup (name);
|
||||
f->space_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return f->space_idx;
|
||||
}
|
||||
|
||||
R_API int r_space_unset (RSpaces *f, const char *fs) {
|
||||
int i, count = 0;
|
||||
if (!fs) {
|
||||
return r_space_set (f, NULL);
|
||||
}
|
||||
for (i=0; i<R_SPACES_MAX; i++) {
|
||||
if (!f->spaces[i]) continue;
|
||||
if (!fs || !strcmp (fs, f->spaces[i])) {
|
||||
if (f->space_idx == i) {
|
||||
f->space_idx = -1;
|
||||
}
|
||||
if (f->space_idx2 == i) {
|
||||
f->space_idx2 = -1;
|
||||
}
|
||||
R_FREE (f->spaces[i]);
|
||||
if (f->unset_for) {
|
||||
f->unset_for (f, i);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static int r_space_count (RSpaces *f, int n) {
|
||||
if (f->count_for) {
|
||||
return f->count_for (f, n);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
R_API int r_space_list(RSpaces *f, int mode) {
|
||||
const char *defspace = NULL;
|
||||
int count, len, i, j = 0;
|
||||
if (mode == 'j')
|
||||
f->printf ("[");
|
||||
for (i=0; i<R_SPACES_MAX; i++) {
|
||||
if (!f->spaces[i]) continue;
|
||||
count = r_space_count (f, i);
|
||||
if (mode=='j') {
|
||||
f->printf ("%s{\"name\":\"%s\"%s,\"count\":%d}",
|
||||
j? ",":"", f->spaces[i],
|
||||
(i==f->space_idx)? ",\"selected\":true":"",
|
||||
count);
|
||||
} else if (mode=='*') {
|
||||
f->printf ("fs %s\n", f->spaces[i]);
|
||||
if (i==f->space_idx) defspace = f->spaces[i];
|
||||
} else {
|
||||
#define INDENT 5
|
||||
char num0[64], num1[64], spaces[32];
|
||||
snprintf (num0, sizeof (num0), "%d", i);
|
||||
snprintf (num1, sizeof (num1), "%d", count);
|
||||
memset (spaces, ' ', sizeof (spaces));
|
||||
len = strlen (num0) + strlen (num1);
|
||||
if (len<INDENT) {
|
||||
spaces[INDENT-len] = 0;
|
||||
} else spaces[0] = 0;
|
||||
f->printf ("%s%s %s %c %s\n", num0, spaces, num1,
|
||||
(i==f->space_idx)?'*':'.',
|
||||
f->spaces[i]);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (defspace)
|
||||
f->printf ("fs %s # current\n", defspace);
|
||||
if (mode == 'j')
|
||||
f->printf ("]\n");
|
||||
return j;
|
||||
}
|
||||
|
||||
R_API int r_space_rename (RSpaces *f, const char *oname, const char *nname) {
|
||||
int i;
|
||||
if (!oname) {
|
||||
if (f->space_idx == -1)
|
||||
return R_FALSE;
|
||||
oname = f->spaces[f->space_idx];
|
||||
}
|
||||
if (!nname) return R_FALSE;
|
||||
while (*oname==' ') oname++;
|
||||
while (*nname==' ') nname++;
|
||||
for (i=0; i<R_SPACES_MAX; i++) {
|
||||
if (f->spaces[i] && !strcmp (oname, f->spaces[i])) {
|
||||
free (f->spaces[i]);
|
||||
f->spaces[i] = strdup (nname);
|
||||
return R_TRUE;
|
||||
}
|
||||
}
|
||||
return R_FALSE;
|
||||
}
|
@ -488,12 +488,14 @@ R_API char *r_sys_cmd_str(const char *cmd, const char *input, int *len) {
|
||||
R_API int r_sys_rmkdir(const char *dir) {
|
||||
int ret = R_TRUE;
|
||||
const char slash = R_SYS_DIR[0];
|
||||
char *path = strdup (dir), *ptr = path, *p;
|
||||
char *path = strdup (dir), *ptr = path;
|
||||
if (*ptr==slash) ptr++;
|
||||
#if __WINDOWS__
|
||||
p = strstr (ptr, ":\\");
|
||||
if (p) {
|
||||
ptr = p + 2;
|
||||
{
|
||||
char *p = strstr (ptr, ":\\");
|
||||
if (p) {
|
||||
ptr = p + 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
while ((ptr = strchr (ptr, slash))) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user