Exemple #1
0
void ls_free(list* ls) {
  if (!ls) return;

  if (ls->next) {
    ls_free(ls->next);
  }

  if (ls->type == TYPE_LIST) {
    ls_free(ls->data);
  }

  gc_free(ls);
}
Exemple #2
0
static void tcp_listen_cb(uv_stream_t *handle, int status)
{
    lua_State   *l             = ls_default_state();
    ls_tcp_t    *server        = containerof(handle, ls_tcp_t, handle);
    uv_loop_t   *loop          = uv_default_loop();
    lua_State   *nl;

    if (ls_object_is_waited(&server->wait_object))
    {
        int ref = server->wait_object.mthread_ref;
        server->wait_object.mthread_ref = LUA_NOREF;
        ls_getref(l, ref);
        nl = lua_tothread(l, -1);
        lua_pop(l, 1);

        if (nl)
        {
            ls_clear_waiting(nl);
            if (status != 0)
            {
                ls_last_error_resume(nl, loop);
            }
            else
            {
                ls_tcp_t *client = new_tcp_handle(l);
                if (uv_accept(handle, (uv_stream_t*)&client->handle))
                {
                    ls_free(nl, client);
                    luaL_error(nl, "accept failed");
                }
                if (uv_read_start((uv_stream_t*)&client->handle, tcp_alloc_cb, tcp_read_cb))
                {
                    ls_free(nl, client);
                    luaL_error(nl, "start read failed.");
                }

                if (LUA_YIELD == lua_status(nl))
                {
                    lua_pushboolean(nl, 1);
                    new_tcp_connection_udata(nl, client);
                    ls_resume(nl, 2);
                }
                else
                {
                    ls_free(nl, client);
                }
            }
        }
        ls_unref(l, ref);
    }
}
Exemple #3
0
static void tcp_close_cb(uv_handle_t *handle)
{
    ls_tcp_t    *tcp;
    lua_State   *l, *nl;

    tcp           = containerof(handle, ls_tcp_t, handle);
    l             = ls_default_state();

    if (ls_object_is_waited(&tcp->wait_object))
    {
        int ref = tcp->wait_object.mthread_ref;
        tcp->wait_object.mthread_ref = LUA_NOREF; 
        ls_getref(l, ref);
        nl = lua_tothread(l, -1);
        lua_pop(l, 1);
        if (nl)
        {
            ls_clear_waiting(nl);
            if (LUA_YIELD == lua_status(nl))
                ls_error_resume(nl, LS_ERRCODE_EOF, "tcp closed");
        }
        ls_unref(l, ref);
    }

    ls_free(l, tcp);
}
Exemple #4
0
void btree_free(btree_t *t)
{
    if (!t) return;
    ls_free(&t->list);
    lsPairInt_free(&t->children);
    lsInt_free(&t->parent);
}
Exemple #5
0
R_API char *r_type_link_at (Sdb *TDB, ut64 addr) {
	char* res = NULL;

	if (addr == UT64_MAX) {
		return NULL;
	}
	char* query = sdb_fmt ("link.%08"PFMT64x, addr);
	res = sdb_get (TDB, query, 0);
	if (!res) { // resolve struct memb if possible for given addr
		SdbKv *kv;
		SdbListIter *sdb_iter;
		SdbList *sdb_list = sdb_foreach_list (TDB, true);
		ls_foreach (sdb_list, sdb_iter, kv) {
			if (strncmp (kv->key, "link.", strlen ("link."))) {
				continue;
			}
			const char *linkptr = sdb_fmt ("0x%s", kv->key + strlen ("link."));
			ut64 baseaddr = r_num_math (NULL, linkptr);
			int delta = (addr > baseaddr)? addr - baseaddr: -1;
			res = r_type_get_struct_memb (TDB, kv->value, delta);
			if (res) {
				break;
			}
		}
		ls_free (sdb_list);
	}
Exemple #6
0
void ht_free(SdbHash *ht) {
	if (ht) {
		free (ht->table);
		ls_free (ht->list);
		free (ht);
	}
}
Exemple #7
0
static int tcp_write(lua_State *l)
{
    tcp_udata_t *udata  = connection_udata(l);
    ls_tcp_t    *tcp    = udata->handle;
    uv_stream_t *handle = (uv_stream_t *)&tcp->handle;
    uv_buf_t     bufs[MAX_WRITE_BUF_COUNT];
    int          refs[MAX_WRITE_BUF_COUNT];
    int          datacnt;
    int          i;
    ls_write_t   *write_req;

    if (tcp == NULL)
        return ls_error_return(l, LS_ERRCODE_EOF, "tcp connection closed.");

    datacnt = lua_gettop(l) - 1;

    if (datacnt > arraysize(bufs))
        return ls_error_return(l, LS_ERRCODE_ARGSIZE, "too much data to write.");
    else if (datacnt <= 0)
    {
        lua_pushboolean(l, 1);
        return 1;
    }

    for (i=0; i<datacnt; i++)
    {
        size_t len;
        const char *data = lua_tolstring(l, i+2, &len);
        if (data == NULL)
            return ls_error_return(l, LS_ERRCODE_INVAL, "invalid data to be writen: should be string or number");
        bufs[i] = uv_buf_init((char*)data, len);
    }

    // now, number in the stack has already been converted into string

    write_req = new_write_req(l);

    
    if (uv_write(&write_req->req, handle, bufs, datacnt, tcp_write_cb))
    {
        ls_free(l, write_req);
        return ls_last_error_return(l, handle->loop);
    }

    // make ref to the string
    for (i=0; i<datacnt; i++)
    {
        write_req->data_refs[i] = ls_ref_value(l, i+2);
    }

    write_req->refcnt = datacnt;

    // libuv make sure now tcp_write_cb is not called, even the data
    // has been writen already.
    ls_set_waiting(l, &write_req->wait_object, udata->timeout);

    return lua_yield(l, 0);
}
Exemple #8
0
list_t *  ls_setPt(list_t * il_to, int n, LIST_TYPE * items)
{
  if (!il_to)
    il_to = ls_Nil();
  ls_free(il_to);
  LS_ITEMS(il_to) = items;
  LS_N(il_to) = n;
  il_to->max_list = n;

  return (il_to);
}
Exemple #9
0
list_t *  ls_cpyPt(list_t * il_to, list_t * il_from)
{
  if (!il_to)
    il_to = ls_Nil();
  ls_free(il_to);
  LS_ITEMS(il_to) = LS_ITEMS(il_from);
  LS_N(il_to) = LS_N(il_from);
  il_to->max_list = il_from->max_list;

  return (il_to);
}
Exemple #10
0
SDB_VISIBLE void sdb_free (Sdb* s) {
	if (!s) return;
	cdb_free (&s->db);
	if (s->lock)
		sdb_unlock (sdb_lockfile (s->dir));
	ls_free (s->ns);
	ht_free (s->ht);
	if (s->fd != -1)
		close (s->fd);
	free (s->ndump);
	free (s->dir);
	free (s);
}
Exemple #11
0
R_API RList* r_type_get_by_offset(Sdb *TDB, ut64 offset) {
	RList *offtypes = r_list_new ();
	SdbList *ls = sdb_foreach_list (TDB, true);
	SdbListIter *lsi;
	SdbKv *kv;
	ls_foreach (ls, lsi, kv) {
		// TODO: Add unions support
		if (!strncmp (kv->value, "struct", 6) && strncmp (kv->key, "struct.", 7)) {
			char *res = r_type_get_struct_memb (TDB, kv->key, offset);
			if (res) {
				r_list_append (offtypes, res);
			}
		}
	}
	ls_free (ls);
	return offtypes;
}
int main() {

  List *ls = ls_make();
  S_t *val1 = malloc(sizeof(S_t));
  val1->num = 5;
  
  S_t *val2 = malloc(sizeof(S_t));
  val2->num = 7;
  
  S_t *val3 = malloc(sizeof(S_t));
  val3->num = 9;
  
  S_t *val4 = malloc(sizeof(S_t));
  val4->num = 14;
  
  S_t *val5 = malloc(sizeof(S_t));
  val5->num = 2;
  
  S_t *val6 = malloc(sizeof(S_t));
  val6->num = 12;
  
  S_t *val7 = malloc(sizeof(S_t));
  val7->num = 6;
  
  S_t *val8 = malloc(sizeof(S_t));
  val8->num = 1;

  ls = ls_cons(ls_cons(ls_cons(ls_cons(ls_cons(ls_cons(ls_cons(ls_cons(ls, val6), val7), val8), val5), val4), val3), val2), val1);
  printf("list\n");
  ls_walk(ls, printer);
  printf("sorted C\n");
  ls_sort(ls, comparator);
  ls_walk(ls, printer);
  printf("list reverse\n");
  ls_reverse(ls);
  ls_walk(ls, printer);
  printf("list mapped\n");
  List *cp = ls_map(ls, copy_num);
  ls_walk(cp, printer);

  //clean up
  ls_free(ls, 1);
  ls = NULL;

  return 0;
}
Exemple #13
0
static void tcp_connect_cb(uv_connect_t *connect_req, int status)
{
    ls_tcp_t *client = containerof(connect_req->handle, ls_tcp_t, handle);
    uv_tcp_t *handle = &client->handle;
    lua_State *l = ls_default_state();
    lua_State *nl;
    uv_loop_t *loop = uv_default_loop();

    ls_free(l, connect_req);

    if (ls_object_is_waited(&client->wait_object))
    {
        int ref = client->wait_object.mthread_ref;
        client->wait_object.mthread_ref = LUA_NOREF;
        ls_getref(l, ref);
        nl = lua_tothread(l, -1);
        lua_pop(l, 1);
        if (nl)
        {
            ls_clear_waiting(nl);
            if (status)
            {
                uv_close((uv_handle_t*)handle, tcp_close_cb);
                ls_last_error_resume(nl, loop);
            }
            else
            {
                if (uv_read_start((uv_stream_t*)handle, tcp_alloc_cb, tcp_read_cb))
                {
                    uv_close((uv_handle_t*)handle, tcp_close_cb);
                    ls_last_error_resume(nl, loop);
                }
                else
                {
                    lua_pushboolean(nl, 1);
                    new_tcp_connection_udata(nl, client);
                    ls_resume(nl, 2);
                }
            }
        }
        ls_unref(l, ref);
    }
}
Exemple #14
0
static int tcp_create_client(lua_State *l)
{
    const char    *rip4     = "0.0.0.0";
    int            rport    = 0;
    ls_tcp_t      *client;
    uv_tcp_t      *handle;
    uv_loop_t     *loop    = uv_default_loop();
    uv_connect_t  *connect_req;
    int            connect_timeout;

    if (lua_gettop(l) >= 2)
    {
        rip4 = luaL_checkstring(l, 1);
        rport = luaL_checkint(l, 2);
        luaL_argcheck(l, strnlen(rip4, 256) > 0, 1, "invalid ipv4 address");
        luaL_argcheck(l, rport > 0, 2, "port number should > 0");
    }
    else if (lua_gettop(l) == 1)
    {
        rport = luaL_checkint(l, 1);
        luaL_argcheck(l, rport > 0, 1, "port number should > 0");
    }
    else
        return ls_error_return(l, LS_ERRCODE_INVAL, "server ip and port should be specified.");
    client = new_tcp_handle(l);
    connect_req = (uv_connect_t*)ls_malloc(l, sizeof(uv_connect_t));
    if (uv_tcp_connect(connect_req, &client->handle, uv_ip4_addr(rip4, rport), tcp_connect_cb))
    {
        ls_free(l, connect_req);
        uv_close((uv_handle_t*)client, tcp_close_cb);
        return ls_last_error_return(l, loop);
    }

    lua_getglobal(l, "tcp");
    lua_getfield(l, -1, "connect_timeout");
    connect_timeout = lua_tointeger(l, -1);
    lua_pop(l, 2);

    ls_set_waiting(l, &client->wait_object, connect_timeout);

    return lua_yield(l, 0);
}
Exemple #15
0
static void tcp_write_cb(uv_write_t *req, int status)
{
    ls_write_t *write_req = containerof(req, ls_write_t, req);
    uv_loop_t *loop = uv_default_loop();
    lua_State *l, *nl;
    int i;

    l = ls_default_state();
    for (i=0; i<write_req->refcnt; i++)
    {
        ls_unref(l, write_req->data_refs[i]);
        lua_pop(l, 1);
        write_req->data_refs[i] = LUA_NOREF;
    }
    write_req->refcnt = 0;

    if (ls_object_is_waited(&write_req->wait_object))
    {
        int ref = write_req->wait_object.mthread_ref;
        write_req->wait_object.mthread_ref = LUA_NOREF;
        ls_getref(l, ref);
        nl = lua_tothread(l, -1);
        lua_pop(l, 1);
        if (nl)
        {
            ls_clear_waiting(nl);
            if (status)
            {
                ls_last_error_resume(nl, req->handle->loop);
            }
            else
            {
                ls_ok_resume(nl);
            }
        }

        ls_unref(l, ref);
    }
    ls_free(l, write_req);
}
Exemple #16
0
R_API void r_anal_xrefs_list(RAnal *anal, int rad) {
	switch (rad) {
	case 1:
	case '*':
		sdb_foreach (DB, (SdbForeachCallback)xrefs_list_cb_rad, anal);
		break;
	case 'j':
		{
		anal->cb_printf ("{");
		bool is_first = true;
		SdbListIter *sdb_iter;
		SdbKv *kv;
		SdbList *sdb_list = sdb_foreach_match (DB, "^ref.", false);
		ls_foreach (sdb_list, sdb_iter, kv) {
			is_first = xrefs_list_cb_json (anal, is_first, kv->key, kv->value);
		}
		ls_free (sdb_list);
		anal->cb_printf ("}\n");
		}
		break;
	default:
		sdb_foreach (DB, (SdbForeachCallback)xrefs_list_cb_plain, anal);
		break;
	}
Exemple #17
0
static int cmd_type(void *data, const char *input) {
	RCore *core = (RCore*)data;

	switch (input[0]) {
	// t [typename] - show given type in C syntax
	case 'k':
		if (input[1]==' ') {
			sdb_query (core->anal->sdb_types, input+2);
		} else sdb_query (core->anal->sdb_types, "*");
		break;
	case 's':
	{
		char *q, *p, *o, *e;
		p = o = strdup (input+1);
		for (;;) {
			if (*p == '\0'){
				eprintf ("Usage: ts <k>=<v> Set fields at curseek linked type\n");
				break;
			}
			q = strchr (p, ' ');
			if (q) *q = 0;
			if (!*p) {
				p++;
				continue;
			}
			e = strchr (p, '=');
			if (e) {
				*e = 0;
				r_anal_type_set (core->anal, core->offset,
					p, r_num_math (core->num, e+1));
			} else eprintf ("TODO: implement get\n");
			if (!q) break;
			p = q+1;
		}
		free (o);
	}
		break;
	case 'b':
		{
		int i;
		char *p, *s = (strlen (input) > 1) ? strdup (input+2): NULL;
		const char *isenum;
		p = s ? strchr (s, ' ') : NULL;
		if (p) {
			*p++ = 0;
// dupp in core.c (see getbitfield())
#if 1
			isenum = sdb_const_get (core->anal->sdb_types, s, 0);
			if (isenum && !strcmp (isenum, "enum")) {
				int empty = 1;
				ut32 num = (ut32)r_num_math (core->num, p);
				r_cons_printf ("0x%08"PFMT64x" : ", num);
				for (i=0; i< 32; i++) {
					if (num & (1<<i)) {
						const char *q = sdb_fmt (0, "%s.0x%x", s, (1<<i));
						const char *res = sdb_const_get (core->anal->sdb_types, q, 0);
						if (!empty)
							r_cons_printf (" | ");
						if (res) r_cons_printf ("%s", res);
						else r_cons_printf ("0x%x", (1<<i));
						empty = 0;
					}
				}
			} else {
				eprintf ("This is not an enum\n");
			}
#endif
		} else {
			eprintf ("Missing value\n");
		}
		free (s);
		}
		break;
	case 'e':
		{
		if (!input[1]) {
			char *name = NULL;
			SdbKv *kv;
			SdbListIter *iter;
                        SdbList *l = sdb_foreach_list (core->anal->sdb_types);
			ls_foreach (l, iter, kv) {
				if (!strcmp (kv->value, "enum")) {
					if (!name || strcmp (kv->value, name)) {
						free (name);
						name = strdup (kv->key);
						r_cons_printf ("%s\n", name);
					}
				}
			}
			free (name);
			ls_free (l);
			break;
		}
		char *p, *s = strdup (input+2);
		const char *isenum;
		p = strchr (s, ' ');
		if (p) {
			*p++ = 0;
			isenum = sdb_const_get (core->anal->sdb_types, s, 0);
			if (isenum && !strcmp (isenum, "enum")) {
				const char *q = sdb_fmt (0, "%s.0x%x", s, (ut32)r_num_math (core->num, p));
				const char *res = sdb_const_get (core->anal->sdb_types, q, 0);
				if (res)
					r_cons_printf ("%s\n", res);
			} else {
				eprintf ("This is not an enum\n");
			}
		} else {
			//eprintf ("Missing value\n");
			r_core_cmdf (core, "t~&%s,=0x", s);
		}
		free (s);
		}
		break;
	case ' ':
	{
		const char *isenum = sdb_const_get (core->anal->sdb_types, input+2, 0);
		if (isenum && !strcmp (isenum, "enum")) {
			eprintf ("IS ENUM! \n");
		} else {
			char *fmt = r_anal_type_format (core->anal, input +1);
			if (fmt) {
				r_cons_printf ("pf %s\n", fmt);
				free (fmt);
			} else eprintf ("Cannot find '%s' type\n", input+1);
		}
	}
		break;
	// t* - list all types in 'pf' syntax
	case '*':
		sdb_foreach (core->anal->sdb_types, typelist, core);
		break;
	case 0:
		sdb_foreach (core->anal->sdb_types, sdbforcb, core);
		break;
	case 'o':
		if (input[1] == ' ') {
			const char *filename = input + 2;
			char *homefile = NULL;
			if (*filename == '~') {
				if (filename[1] && filename[2]) {
					homefile = r_str_home (filename + 2);
					filename = homefile;
				}
			}
			if (!strcmp (filename, "-")) {
				char *out, *tmp;
				tmp = r_core_editor (core, NULL, "");
				if (tmp) {
					out = r_parse_c_string (tmp);
					if (out) {
				//		r_cons_strcat (out);
						sdb_query_lines (core->anal->sdb_types, out);
						free (out);
					}
					free (tmp);
				}
			} else {
				char *out = r_parse_c_file (filename);
				if (out) {
				//	r_cons_strcat (out);
					sdb_query_lines (core->anal->sdb_types, out);
					free (out);
				}
				//r_anal_type_loadfile (core->anal, filename);
			}
			free (homefile);
		}
		break;
	// td - parse string with cparse engine and load types from it
	case 'd':
		if (input[1] == '?') {
			const char * help_message[] = {
				"Usage:", "td[...]", "",
				"td", "[string]", "Load types from string",
				NULL
			};
			r_core_cmd_help(core, help_message);
		} else
		if (input[1] == '-') {
			const char *arg = strchr (input+1, ' ');
			if (arg) arg++; else arg = input+2;
			r_anal_type_del (core->anal, arg);
		} else
		if (input[1] == ' ') {
			char tmp[8192];
			snprintf (tmp, sizeof (tmp)-1, "%s;", input+2);
			//const char *string = input + 2;
			//r_anal_str_to_type (core->anal, string);
			char *out = r_parse_c_string (tmp);
			if (out) {
				//r_cons_strcat (out);
				sdb_query_lines (core->anal->sdb_types, out);
				free (out);
			}
		} else {
			eprintf ("Invalid use of td. See td? for help\n");
		}
		break;
	// tl - link a type to an address
	case 'l':
		if (input[1]=='?') {
			const char * help_message[] = {
				"Usage: tl", " [typename|addr] ([addr])@[addr|function]", "",
				NULL
			 };

			r_core_cmd_help(core, help_message);
		} else if (input[1]) {
			ut64 addr = r_num_math (core->num, input+2);
			char *ptr = strchr (input + 2, ' ');
			if (ptr) {
				addr = r_num_math (core->num, ptr + 1);
				*ptr = '\0';
			} else addr = core->offset;
			r_anal_type_link (core->anal, input+2, addr);
		} else {
			r_core_cmd0 (core, "t~^link");
		}
		break;
	case '-':
		if (input[1] == '?') {
			const char * help_message[] = {
				"Usage: t-", " <type>", "Delete type by its name",
				NULL
			 };

			r_core_cmd_help(core, help_message);
		} else
		if (input[1]=='*') {
			eprintf ("TODO\n");
		} else {
			const char *name = input + 1;
			if (*name==' ') name++;
			if (*name) {
				r_anal_type_del (core->anal, name);
			} else eprintf ("Invalid use of t- . See t-? for help.\n");
		}
		break;
	// tv - get/set type value linked to a given address
	case 'f':
		 {
			ut64 addr;
			char *fmt, key[128];
			const char *type;
			if (input[1]) {
				addr = r_num_math (core->num, input+1);
			} else addr = core->offset;
			snprintf (key, sizeof (key), "link.%08"PFMT64x, addr);
			type = sdb_const_get (core->anal->sdb_types, key, 0);
			if (type) {
				fmt = r_anal_type_format (core->anal, type);
				r_cons_printf ("struct %s {\n", type);
				if (fmt) {
					r_core_cmdf (core, "pf %s @ 0x%08"PFMT64x"\n", fmt, addr);
					free (fmt);
				}// else eprintf ("Cannot find '%s' type\n", input+1);
				r_cons_printf ("}\n");
			} //else eprintf ("Cannot find type at 0x%llx\n", addr);
		 }
		break;
	case '?':
		show_help (core);
		break;
	}
Exemple #18
0
static int cmd_type(void *data, const char *input) {
	RCore *core = (RCore *)data;

	switch (input[0]) {
	// t [typename] - show given type in C syntax
	case 'u': // "tu"
		switch (input[1]) {
		case '?': {
			const char *help_message[] = {
				"USAGE tu[...]", "", "",
				"tu", "", "List all loaded unions",
				"tu?", "", "show this help",
				NULL };
			r_core_cmd_help (core, help_message);
		} break;
		case 0:
			sdb_foreach (core->anal->sdb_types, stdprintifunion, core);
			break;
		}
		break;
	case 'k': // "tk"
		if (input[1] == ' ') {
			sdb_query (core->anal->sdb_types, input + 2);
		} else sdb_query (core->anal->sdb_types, "*");
		fflush (stdout);
		break;
	case 's': // "ts"
		switch (input[1]) {
		case '?': {
			const char *help_message[] = {
				"USAGE ts[...]", "", "",
				"ts", "", "List all loaded structs",
				"ts?", "", "show this help",
				NULL };
			r_core_cmd_help (core, help_message);
		} break;
		case 0:
			sdb_foreach (core->anal->sdb_types, stdprintifstruct, core);
			break;
		}
		break;
	case 'b': {
		char *p, *s = (strlen (input) > 1)? strdup (input + 2): NULL;
		const char *isenum;
		p = s? strchr (s, ' '): NULL;
		if (p) {
			*p++ = 0;
			// dupp in core.c (see getbitfield())
			isenum = sdb_const_get (core->anal->sdb_types, s, 0);
			if (isenum && !strcmp (isenum, "enum")) {
				*--p = '.';
				const char *res = sdb_const_get (core->anal->sdb_types, s, 0);
				if (res)
					r_cons_println (res);
				else eprintf ("Invalid enum member\n");
			} else {
				eprintf ("This is not an enum\n");
			}
		} else {
			eprintf ("Missing value\n");
		}
		free (s);
	} break;
	case 'e': {
		if (!input[1]) {
			char *name = NULL;
			SdbKv *kv;
			SdbListIter *iter;
			SdbList *l = sdb_foreach_list (core->anal->sdb_types);
			ls_foreach (l, iter, kv) {
				if (!strcmp (kv->value, "enum")) {
					if (!name || strcmp (kv->value, name)) {
						free (name);
						name = strdup (kv->key);
						r_cons_println (name);
					}
				}
			}
			free (name);
			ls_free (l);
			break;
		}
		if (input[1] == '?') {
			const char *help_message[] = {
				"USAGE te[...]", "", "",
				"te", "", "List all loaded enums",
				"te", " <enum> <value>", "Show name for given enum number",
				"te?", "", "show this help",
				NULL };
			r_core_cmd_help (core, help_message);
			break;
		}
		char *p, *s = strdup (input + 2);
		const char *isenum;
		p = strchr (s, ' ');
		if (p) {
			*p++ = 0;
			isenum = sdb_const_get (core->anal->sdb_types, s, 0);
			if (isenum && !strncmp (isenum, "enum", 4)) {
				const char *q = sdb_fmt (0, "%s.0x%x", s, (ut32)r_num_math (core->num, p));
				const char *res = sdb_const_get (core->anal->sdb_types, q, 0);
				if (res)
					r_cons_println (res);
			} else {
				eprintf ("This is not an enum\n");
			}
		} else {
			//eprintf ("Missing value\n");
			r_core_cmdf (core, "t~&%s,=0x", s);
		}
		free (s);
	} break;
	case ' ': {
		const char *isenum = sdb_const_get (core->anal->sdb_types, input + 1, 0);
		if (isenum && !strcmp (isenum, "enum")) {
			eprintf ("IS ENUM! \n");
		} else {
			char *fmt = r_anal_type_format (core->anal, input + 1);
			if (fmt) {
				r_str_chop (fmt);
				r_cons_printf ("pf %s\n", fmt);
				free (fmt);
			} else eprintf ("Cannot find '%s' type\n", input + 1);
		}
	} break;
	// t* - list all types in 'pf' syntax
	case '*':
		sdb_foreach (core->anal->sdb_types, typelist, core);
		break;
	case 0:
		sdb_foreach (core->anal->sdb_types, sdbforcb, core);
		break;
	case 'o':
		if (!r_sandbox_enable (0)) {
			if (input[1] == ' ') {
				const char *filename = input + 2;
				char *homefile = NULL;
				if (*filename == '~') {
					if (filename[1] && filename[2]) {
						homefile = r_str_home (filename + 2);
						filename = homefile;
					}
				}
				if (!strcmp (filename, "-")) {
					char *out, *tmp;
					tmp = r_core_editor (core, NULL, "");
					if (tmp) {
						out = r_parse_c_string (tmp);
						if (out) {
							//		r_cons_strcat (out);
							save_parsed_type (core, out);
							free (out);
						}
						free (tmp);
					}
				} else {
					char *out = r_parse_c_file (filename);
					if (out) {
						//r_cons_strcat (out);
						save_parsed_type (core, out);
						free (out);
					}
					//r_anal_type_loadfile (core->anal, filename);
				}
				free (homefile);
			} else if (input[1] == 's') {
				const char *dbpath = input + 3;
				if (r_file_exists (dbpath)) {
					Sdb *db_tmp = sdb_new (0, dbpath, 0);
					sdb_merge (core->anal->sdb_types, db_tmp);
					sdb_close (db_tmp);
					sdb_free (db_tmp);
				}
			}
		} else {
			eprintf ("Sandbox: system call disabled\n");
		}
		break;
	// td - parse string with cparse engine and load types from it
	case 'd':
		if (input[1] == '?') {
			const char *help_message[] = {
				"Usage:", "\"td [...]\"", "",
				"td", "[string]", "Load types from string",
				NULL };
			r_core_cmd_help (core, help_message);
			r_cons_printf ("Note: The td command should be put between double quotes\n"
				"Example: \" td struct foo {int bar;int cow};\""
				"\nt");

		} else if (input[1] == ' ') {
			char tmp[8192];
			snprintf (tmp, sizeof (tmp) - 1, "%s;", input + 2);
			//const char *string = input + 2;
			//r_anal_str_to_type (core->anal, string);
			char *out = r_parse_c_string (tmp);
			if (out) {
				//r_cons_strcat (out);
				save_parsed_type (core, out);
				free (out);
			}
		} else {
			eprintf ("Invalid use of td. See td? for help\n");
		}
		break;
	// tl - link a type to an address
	case 'l':
		switch (input[1]) {
		case '?': {
			const char *help_message[] = {
				"Usage:", "", "",
				"tl", "", "list all links in readable format",
				"tl", "[typename]", "link a type to current adress.",
				"tl", "[typename] = [address]", "link type to given address.",
				"tls", "[address]", "show link at given address",
				"tl-*", "", "delete all links.",
				"tl-", "[address]", "delete link at given address.",
				"tl*", "", "list all links in radare2 command format",
				"tl?", "", "print this help.",
				NULL };
			r_core_cmd_help (core, help_message);
			} break;
		case ' ': {
			char *type = strdup (input + 2);
			char *ptr = strchr (type, '=');
			ut64 addr;

			if (ptr) {
				*ptr++ = 0;
				r_str_chop (ptr);
				if (ptr && *ptr) {
					addr = r_num_math (core->num, ptr);
				} else {
					eprintf ("address is unvalid\n");
					free (type);
					break;
				}
			} else {
				addr = core->offset;
			}
			r_str_chop (type);
			char *tmp = sdb_get (core->anal->sdb_types, type, 0);
			if (tmp && *tmp) {
				r_anal_type_link (core->anal, type, addr);
				free (tmp);
			} else {
				eprintf ("unknown type %s\n", type);
			}
			free (type);
			}
			break;
		case 's': {
			int ptr;
			char *addr = strdup (input + 2);
			SdbKv *kv;
			SdbListIter *sdb_iter;
			SdbList *sdb_list = sdb_foreach_list (core->anal->sdb_types);
			r_str_chop (addr);
			ptr = r_num_math (NULL, addr);
			//r_core_cmdf (core, "tl~0x%08"PFMT64x" = ", addr);
			ls_foreach (sdb_list, sdb_iter, kv) {
				char *linkptr;
				if (strncmp (kv->key, "link.", strlen ("link."))) {
					continue;
				}
				linkptr = sdb_fmt (-1,"0x%s", kv->key + strlen ("link."));
				if (ptr == r_num_math (NULL, linkptr)) {
					linklist_readable (core, kv->key, kv->value);
				}
			}
			free (addr);
			ls_free (sdb_list);
			}
			break;
		case '-':
			switch (input[2]) {
			case '*':
				sdb_foreach (core->anal->sdb_types, sdbdeletelink, core);
				break;
			case ' ': {
				const char *ptr = input + 3;
				ut64 addr = r_num_math (core->num, ptr);
				r_anal_type_unlink (core->anal, addr);
				}
				break;
			}
			break;
		case '*':
			sdb_foreach (core->anal->sdb_types, linklist, core);
			break;
		case '\0':
			sdb_foreach (core->anal->sdb_types, linklist_readable, core);
			break;
		}
Exemple #19
0
static int cmd_type(void *data, const char *input) {
	RCore *core = (RCore *)data;

	switch (input[0]) {
	// t [typename] - show given type in C syntax
	case 'k':
		if (input[1] == ' ') {
			sdb_query (core->anal->sdb_types, input + 2);
		} else sdb_query (core->anal->sdb_types, "*");
		break;
	case 's': {
		char *q, *p, *o, *e;
		p = o = strdup (input + 1);
		for (;;) {
			if (*p == '\0') {
				eprintf ("Usage: ts <k>=<v> Set fields at curseek linked type\n");
				break;
			}
			q = strchr (p, ' ');
			if (q) *q = 0;
			if (!*p) {
				p++;
				continue;
			}
			e = strchr (p, '=');
			if (e) {
				*e = 0;
				r_anal_type_set (core->anal, core->offset,
						p, r_num_math (core->num, e + 1));
			} else eprintf ("TODO: implement get\n");
			if (!q) break;
			p = q + 1;
		}
		free (o);
	} break;
	case 'b': {
		char *p, *s = (strlen (input) > 1)? strdup (input + 2): NULL;
		const char *isenum;
		p = s? strchr (s, ' '): NULL;
		if (p) {
			*p++ = 0;
			// dupp in core.c (see getbitfield())
			isenum = sdb_const_get (core->anal->sdb_types, s, 0);
			if (isenum && !strcmp (isenum, "enum")) {
				*--p = '.';
				const char *res = sdb_const_get (core->anal->sdb_types, s, 0);
				if (res)
					r_cons_printf ("%s\n", res);
				else eprintf ("Invalid enum member\n");
			} else {
				eprintf ("This is not an enum\n");
			}
		} else {
			eprintf ("Missing value\n");
		}
		free (s);
	} break;
	case 'e': {
		if (!input[1]) {
			char *name = NULL;
			SdbKv *kv;
			SdbListIter *iter;
			SdbList *l = sdb_foreach_list (core->anal->sdb_types);
			ls_foreach (l, iter, kv) {
				if (!strcmp (kv->value, "enum")) {
					if (!name || strcmp (kv->value, name)) {
						free (name);
						name = strdup (kv->key);
						r_cons_printf ("%s\n", name);
					}
				}
			}
			free (name);
			ls_free (l);
			break;
		}
		char *p, *s = strdup (input + 2);
		const char *isenum;
		p = strchr (s, ' ');
		if (p) {
			*p++ = 0;
			isenum = sdb_const_get (core->anal->sdb_types, s, 0);
			if (isenum && !strcmp (isenum, "enum")) {
				const char *q = sdb_fmt (0, "%s.0x%x", s, (ut32)r_num_math (core->num, p));
				const char *res = sdb_const_get (core->anal->sdb_types, q, 0);
				if (res)
					r_cons_printf ("%s\n", res);
			} else {
				eprintf ("This is not an enum\n");
			}
		} else {
			//eprintf ("Missing value\n");
			r_core_cmdf (core, "t~&%s,=0x", s);
		}
		free (s);
	} break;
	case ' ': {
		const char *isenum = sdb_const_get (core->anal->sdb_types, input + 1, 0);
		if (isenum && !strcmp (isenum, "enum")) {
			eprintf ("IS ENUM! \n");
		} else {
			char *fmt = r_anal_type_format (core->anal, input + 1);
			if (fmt) {
				r_cons_printf ("pf %s\n", fmt);
				free (fmt);
			} else eprintf ("Cannot find '%s' type\n", input + 1);
		}
	} break;
	// t* - list all types in 'pf' syntax
	case '*':
		sdb_foreach (core->anal->sdb_types, typelist, core);
		break;
	case 0:
		sdb_foreach (core->anal->sdb_types, sdbforcb, core);
		break;
	case 'o':
		if (!r_sandbox_enable (0)) {
			if (input[1] == ' ') {
				const char *filename = input + 2;
				char *homefile = NULL;
				if (*filename == '~') {
					if (filename[1] && filename[2]) {
						homefile = r_str_home (filename + 2);
						filename = homefile;
					}
				}
				if (!strcmp (filename, "-")) {
					char *out, *tmp;
					tmp = r_core_editor (core, NULL, "");
					if (tmp) {
						out = r_parse_c_string (tmp);
						if (out) {
							//		r_cons_strcat (out);
							sdb_query_lines (core->anal->sdb_types, out);
							free (out);
						}
						free (tmp);
					}
				} else {
					char *out = r_parse_c_file (filename);
					if (out) {
						//r_cons_strcat (out);
						sdb_query_lines (core->anal->sdb_types, out);
						free (out);
					}
					//r_anal_type_loadfile (core->anal, filename);
				}
				free (homefile);
			}
		} else {
			eprintf ("Sandbox: system call disabled\n");
		}
		break;
	// td - parse string with cparse engine and load types from it
	case 'd':
		if (input[1] == '?') {
			const char *help_message[] = {
				"Usage:", "\"td [...]\"", "",
				"td", "[string]", "Load types from string",
				NULL };
			r_core_cmd_help (core, help_message);
			r_cons_printf ("Note: The td command should be put between double quotes\n"
				"Example: \" td struct foo {int bar;int cow};\""
				"\nt");

		} else if (input[1] == ' ') {
			char tmp[8192];
			snprintf (tmp, sizeof (tmp) - 1, "%s;", input + 2);
			//const char *string = input + 2;
			//r_anal_str_to_type (core->anal, string);
			char *out = r_parse_c_string (tmp);
			if (out) {
				//r_cons_strcat (out);
				sdb_query_lines (core->anal->sdb_types, out);
				free (out);
			}
		} else {
			eprintf ("Invalid use of td. See td? for help\n");
		}
		break;
	// tl - link a type to an address
	case 'l':
		if (input[1] == '?') {
			const char *help_message[] = {
				"Usage: tl", " [typename|addr] ([addr])@[addr|function]", "",
				NULL };

			r_core_cmd_help (core, help_message);
		} else if (input[1]) {
			ut64 addr = r_num_math (core->num, input + 2);
			char *ptr = strchr (input + 2, ' ');
			if (ptr) {
				addr = r_num_math (core->num, ptr + 1);
				*ptr = '\0';
			} else addr = core->offset;
			r_anal_type_link (core->anal, input + 2, addr);
		} else {
			r_core_cmd0 (core, "t~^link");
		}
		break;
	case '-':
		if (input[1] == '?') {
			const char *help_message[] = {
				"Usage: t-", " <type>", "Delete type by its name",
				NULL };

			r_core_cmd_help (core, help_message);
		} else if (input[1] == '*') {
			sdb_foreach (core->anal->sdb_types, sdbdelete, core);
		} else {
			const char *name = input + 1;
			while (IS_WHITESPACE (*name)) name++;
			if (*name) {
				SdbKv *kv;
				SdbListIter *iter;
				int tmp_len = strlen (name);
				char *tmp = malloc (tmp_len + 2);
				r_anal_type_del (core->anal, name);
				if (tmp) {
					snprintf (tmp, tmp_len + 1, "%s.", name);
					SdbList *l = sdb_foreach_list (core->anal->sdb_types);
					ls_foreach (l, iter, kv) {
						if (!strncmp (kv->key, tmp, tmp_len - 1))
							r_anal_type_del (core->anal, kv->key);
					}
					free (tmp);
				}
			} else eprintf ("Invalid use of t- . See t-? for help.\n");
		}