Пример #1
0
R_API void r_cons_grep_parsecmd(char *cmd, const char *quotestr) {
	char *ptr;

	if (!cmd) {
		return;
	}

	ptr = preprocess_filter_expr (cmd, quotestr);

	if (ptr) {
		r_str_chop (cmd);
		parse_grep_expression (ptr);
		free (ptr);
	}
}
Пример #2
0
static RNumCalcValue prim(RNum *num, RNumCalc *nc, int get) {
	RNumCalcValue v = {0};
	if (get) get_token (num, nc);
	switch (nc->curr_tok) {
	case RNCNUMBER:
		v = nc->number_value;
		get_token (num, nc);
		return v;
	case RNCNAME:
		//fprintf (stderr, "error: unknown keyword (%s)\n", nc->string_value);
		//double& v = table[nc->string_value];
		r_str_chop (nc->string_value);
		v = Nset (r_num_get (num, nc->string_value));
		get_token (num, nc);
		if (nc->curr_tok  == RNCASSIGN) {
			v = expr (num, nc, 1);
		}
		if (nc->curr_tok == RNCINC) Naddi (v, 1);
		if (nc->curr_tok == RNCDEC) Nsubi (v, 1);
		return v;
	case RNCNEG:
		v = nc->number_value;
		get_token (num, nc);
		return Nneg (nc->number_value); //prim (num, nc, 1), 1);
	case RNCINC: return Naddi (prim (num, nc, 1), 1);
	case RNCDEC: return Naddi (prim (num, nc, 1), -1);
	case RNCORR: return Norr (v, prim (num, nc, 1));
	case RNCMINUS: return Nsub (v, prim (num, nc, 1));
	case RNCLEFTP:
		v = expr (num, nc, 1);
		if (nc->curr_tok == RNCRIGHTP) {
			get_token (num, nc);
		} else error (num, nc, " ')' expected");
	case RNCEND:
	case RNCXOR:
	case RNCAND:
	case RNCPLUS:
	case RNCMOD:
	case RNCMUL:
	case RNCDIV:
	case RNCPRINT:
	case RNCASSIGN:
	case RNCRIGHTP:
		return v;
	//default: error (num, nc, "primary expected");
	}
	return v;
}
Пример #3
0
static bool cmd_wf(RCore *core, const char *input) {
	ut8 *buf;
	int size;
	const char *arg = input + ((input[1] == ' ') ? 2 : 1);
	int wseek = r_config_get_i (core->config, "cfg.wseek");
	char *p, *a = r_str_chop (strdup (arg));
	// XXX: file names cannot contain spaces
	p = strchr (a, ' ');
	if (p) *p++ = 0;

	if (*arg =='?' || !*arg) {
		eprintf ("Usage: wf [file] ([size] ([offset]))\n");
	}
	if (!strcmp (arg, "-")) {
		char *out = r_core_editor (core, NULL, NULL);
		if (out) {
			r_io_write_at (core->io, core->offset,
				(ut8*)out, strlen (out));
			r_core_block_read (core);
			free (out);
		}
	}
	if ((buf = (ut8*) r_file_slurp (a, &size))) {
		int u_size = size;
		int u_offset = 0;
		u_size = r_num_math (core->num, p);
		if (u_size < 1) u_size = size;
		if (p) {
			*p++ = 0;
			u_offset = r_num_math (core->num, p);
			if (u_offset > size) {
				eprintf ("Invalid offset\n");
				free (buf);
				return false;
			}
		}
		r_io_use_desc (core->io, core->file->desc);
		r_io_write_at (core->io, core->offset, buf + u_offset, u_size);
		WSEEK (core, size);
		free (buf);
		r_core_block_read (core);
	} else {
		eprintf ("Cannot open file '%s'\n", arg);
	}
	return true;
}
Пример #4
0
static NumValue prim(int get) {
	NumValue v = {0};
	if (get) get_token ();
	switch (curr_tok) {
	case NUMBER:
		v = number_value;
		get_token ();
		return v;
	case NAME:
		//fprintf (stderr, "error: unknown keyword (%s)\n", string_value);
		//double& v = table[string_value];
		r_str_chop (string_value);
		v = Nset (r_num_get (calc_num, string_value));
		get_token ();
		if (curr_tok  == ASSIGN) 
			v = expr (1);
		if (curr_tok == INC) Naddi (v, 1);
		if (curr_tok == DEC) Nsubi (v, 1);
		return v;
	case INC: return Naddi (prim (1), 1);
	case DEC: return Naddi (prim (1), -1);
	case MINUS: return Nsub (v, prim (1));
	case LEFTP:
		v = expr (1);
		if (curr_tok == RIGHTP)
			get_token ();
		else error (" ')' expected");
	case END:
	case PLUS:
	case MUL:
	case DIV:
	case PRINT:
	case ASSIGN:
	case RIGHTP:
		return v;
	//default: error ("primary expected");
	}
	return v;
}
Пример #5
0
static char *swift_demangle_cmd(const char *s) {
	/* XXX: command injection issue here */
	static char *swift_demangle = NULL;
	if (have_swift_demangle == -1) {
		if (!swift_demangle) {
			have_swift_demangle = 0;
			swift_demangle = r_file_path ("swift-demangle");
			if (!swift_demangle || !strcmp (swift_demangle, "swift-demangle")) {
				char *xcrun = r_file_path ("xcrun");
				if (xcrun) {
					if (strcmp (xcrun, "xcrun")) {
						free (swift_demangle);
						swift_demangle = r_str_newf ("%s swift-demangle", xcrun);
						have_swift_demangle = 1;
					}
					free (xcrun);
				}
			}
		}
	}
	if (swift_demangle) {
		if (strstr (s, "'") || strstr (s, "\\")) {
			/* nice try */
			return NULL;
		}
		//char *res = r_sys_cmd_strf ("%s -compact -simplified '%s'",
		char *res = r_sys_cmd_strf ("%s -compact '%s'",
			swift_demangle, s);
		if (res && !*res) {
			free (res);
			res = NULL;
		}
		return r_str_chop (res);
	}
	return NULL;
}
Пример #6
0
static int parse(RParse *p, const char *data, char *str) {
	int i, n;
	char w0[32];
	char w1[32];
	char w2[32];
	char w3[32];
	char *buf, *ptr, *optr, *num;

	// malloc can be slow here :?
	buf = strdup (data);
	r_str_trim_head (buf);

	ptr = strchr (buf, '#');
	if (ptr) {
		*ptr = 0;
		r_str_chop (buf);
	}
	if (*buf == '.' || buf[strlen(buf)-1] == ':') {
		free (buf);
		strcpy (str, data);
		return R_TRUE;
	}
	r_str_replace_char (buf, '$', 0);
	r_str_replace_char (buf, '%', 0);
	r_str_replace_char (buf, '\t', ' ');
	r_str_replace_char (buf, '(', '[');
	r_str_replace_char (buf, ')', ']');
	ptr = strchr (buf, '[');
	if (ptr) {
		*ptr = 0;
		num = (char*)r_str_lchr (buf, ' ');
		if (!num)
			num = (char*)r_str_lchr (buf, ',');
		if (num) {
			n = atoi (num+1);
			*ptr = '[';
			memmove (num+1, ptr, strlen (ptr)+1);
			ptr = (char*)r_str_lchr (buf, ']');
			if (n && ptr) {
				char *rest = strdup (ptr+1);
				if(n>0) sprintf (ptr, "+%d]%s", n, rest);
				else sprintf (ptr, "%d]%s", n, rest);
				free (rest);
			}
		} else *ptr = '[';
	}

	if (*buf) {
		*w0 = *w1 = *w2 = *w3 = 0;
		ptr = strchr (buf, ' ');
		if (ptr == NULL)
			ptr = strchr (buf, '\t');
		if (ptr) {
			*ptr = '\0';
			for (++ptr; *ptr==' '; ptr++);
			strncpy (w0, buf, sizeof(w0) - 1);
			strncpy (w1, ptr, sizeof(w1) - 1);

			optr = ptr;
			ptr = strchr (ptr, ',');
			if (ptr) {
				*ptr = '\0';
				for (++ptr; *ptr==' '; ptr++);
				strncpy (w1, optr, sizeof(w1)-1);
				strncpy (w2, ptr, sizeof(w2)-1);
				ptr = strchr (ptr, ',');
				if (ptr) {
					*ptr = '\0';
					for (++ptr; *ptr==' '; ptr++);
					strncpy (w2, optr, sizeof(w2)-1);
					strncpy (w3, ptr, sizeof(w3)-1);
				}
			}
		}
		{
			const char *wa[] = { w0, w1, w2, w3 };
			int nw = 0;
			for (i=0; i<4; i++) {
				if (wa[i][0] != '\0')
				nw++;
			}
			replace (nw, wa, str);
		}
	}
	free (buf);
	return R_TRUE;
}
Пример #7
0
R_API int r_core_visual_cmd(RCore *core, int ch) {
    RAsmOp op;
    ut64 offset = core->offset;
    char buf[4096];
    int i, ret, offscreen, cols = core->print->cols, delta = 0;
    ch = r_cons_arrow_to_hjkl (ch);
    ch = visual_nkey (core, ch);
    if (ch<2) return 1;

    // do we need hotkeys for data references? not only calls?
    if (ch>='0'&& ch<='9') {
        ut64 off = core->asmqjmps[ch-'0'];
        if (off != UT64_MAX) {
            int delta = R_ABS ((st64)off-(st64)offset);
            r_io_sundo_push (core->io, offset);
            if (curset && delta<100) {
                cursor = delta;
            } else {
                r_core_visual_seek_animation (core, off);
                //r_core_seek (core, off, 1);
            }
            r_core_block_read (core, 1);
        }
    } else
        switch (ch) {
        case 0x0d:
        {
            r_cons_enable_mouse (R_TRUE);
            RAnalOp *op = r_core_anal_op (core, core->offset+cursor);
            if (op) {
                if (op->type == R_ANAL_OP_TYPE_JMP	||
                        op->type == R_ANAL_OP_TYPE_CJMP ||
                        op->type == R_ANAL_OP_TYPE_CALL) {
                    r_io_sundo_push (core->io, offset);
                    r_core_visual_seek_animation(core, op->jump);
                }
            }
            r_anal_op_free (op);
        }
        break;
        case 90: // shift+tab
            if (!strcmp (printfmt[0], "x"))
                printfmt[0] = "pxa";
            else printfmt[0] = "x";
            break;
        case 9: // tab
        {   // XXX: unify diff mode detection
            ut64 f = r_config_get_i (core->config, "diff.from");
            ut64 t = r_config_get_i (core->config, "diff.to");
            if (f == t && f == 0) {
                core->print->col = core->print->col==1? 2: 1;
            } else {
                ut64 delta = offset - f;
                r_core_seek (core, t+delta, 1);
                r_config_set_i (core->config, "diff.from", t);
                r_config_set_i (core->config, "diff.to", f);
            }
        }
        break;
        case 'a':
            if (core->file && !(core->file->rwx & 2)) {
                r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n");
                r_cons_any_key ();
                return R_TRUE;
            }
            r_cons_printf ("Enter assembler opcodes separated with ';':\n");
            showcursor (core, R_TRUE);
            r_cons_flush ();
            r_cons_set_raw (R_FALSE);
            strcpy (buf, "wa ");
            r_line_set_prompt (":> ");
            if (r_cons_fgets (buf+3, 1000, 0, NULL) <0) buf[0]='\0';
            if (*buf) {
                if (curset) r_core_seek (core, core->offset + cursor, 0);
                r_core_cmd (core, buf, R_TRUE);
                if (curset) r_core_seek (core, core->offset - cursor, 1);
            }
            showcursor (core, R_FALSE);
            r_cons_set_raw (R_TRUE);
            break;
        case '!':
            r_cons_2048();
            break;
        case 'o':
            visual_offset (core);
            break;
        case 'A':
        {   int oc = curset;
            ut64 off = curset? core->offset+cursor : core->offset;
            curset = 0;
            r_core_visual_asm (core, off);
            curset = oc;
        }
        break;
        case 'c':
            setcursor (core, curset?0:1);
            break;
        case 'C':
            color = color? 0: 1;
            r_config_set_i (core->config, "scr.color", color);
            break;
        case 'd':
            r_core_visual_define (core);
            break;
        case 'D':
            setdiff (core);
            break;
        case 'f':
        {
            int range, min, max;
            char name[256], *n;
            r_line_set_prompt ("flag name: ");
            showcursor (core, R_TRUE);
            if (r_cons_fgets (name, sizeof (name), 0, NULL) >=0 && *name) {
                n = r_str_chop (name);
                if (*name=='-') {
                    if (*n) r_flag_unset (core->flags, n+1, NULL);
                } else {
                    if (ocursor != -1) {
                        min = R_MIN (cursor, ocursor);
                        max = R_MAX (cursor, ocursor);
                    } else {
                        min = max = cursor;
                    }
                    range = max-min+1;
                    if (range<1) range = 1;
                    if (*n) r_flag_set (core->flags, n,
                                            core->offset + min, range, 1);
                }
            }
        }
        showcursor (core, R_FALSE);
        break;
        case 'F':
            r_flag_unset_i (core->flags, core->offset + cursor, NULL);
            break;
        case 'n':
            r_core_seek_next (core, r_config_get (core->config, "scr.nkey"));
            break;
        case 'N':
            r_core_seek_previous (core, r_config_get (core->config, "scr.nkey"));
            break;
        case 'i':
        case 'I':
            if (core->file && !(core->file->rwx & 2)) {
                r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n");
                r_cons_any_key ();
                return R_TRUE;
            }
            showcursor (core, R_TRUE);
            r_cons_flush ();
            r_cons_set_raw (0);
            if (ch=='I') {
                strcpy (buf, "wow ");
                r_line_set_prompt ("insert hexpair block: ");
                if (r_cons_fgets (buf+4, sizeof (buf)-5, 0, NULL) <0)
                    buf[0]='\0';
                char *p = strdup (buf);
                int cur = core->print->cur;
                if (cur>=core->blocksize)
                    cur = core->print->cur-1;
                snprintf (buf, sizeof (buf), "%s @ $$0!%i", p,
                          core->blocksize-cursor);
                r_core_cmd (core, buf, 0);
                free (p);
                break;
            }
            delta = (ocursor!=-1)? R_MIN (cursor, ocursor): cursor;
            if (core->print->col==2) {
                strcpy (buf, "\"w ");
                r_line_set_prompt ("insert string: ");
                if (r_cons_fgets (buf+3, sizeof (buf)-4, 0, NULL) <0)
                    buf[0]='\0';
                strcat (buf, "\"");
            } else {
                r_line_set_prompt ("insert hex: ");
                if (ocursor != -1) {
                    int bs = R_ABS (cursor-ocursor)+1;
                    core->blocksize = bs;
                    strcpy (buf, "wow ");
                } else {
                    strcpy (buf, "wx ");
                }
                if (r_cons_fgets (buf+strlen (buf), sizeof (buf)-strlen (buf), 0, NULL) <0)
                    buf[0]='\0';
            }
            if (curset) r_core_seek (core, core->offset + delta, 0);
            r_core_cmd (core, buf, 1);
            if (curset) r_core_seek (core, offset, 1);
            r_cons_set_raw (1);
            showcursor (core, R_FALSE);
            break;
        case 'R':
            r_core_cmd0 (core, "ecr");
            break;
        case 'e':
            r_core_visual_config (core);
            break;
        case 'E':
            r_core_visual_colors (core);
            break;
        case 'M':
            r_core_visual_mounts (core);
            break;
        case 't':
            r_core_visual_trackflags (core);
            break;
        case 'x':
        {
            int count = 0;
            RList *xrefs = NULL;
            RAnalRef *refi;
            RListIter *iter;
            RAnalFunction *fun;

            if ((xrefs = r_anal_xref_get (core->anal, core->offset))) {
                r_cons_gotoxy (1, 1);
                r_cons_printf ("[GOTO XREF]> \n");
                if (r_list_empty (xrefs)) {
                    r_cons_printf ("\tNo XREF found at 0x%"PFMT64x"\n", core->offset);
                    r_cons_any_key ();
                    r_cons_clear00 ();
                } else {
                    r_list_foreach (xrefs, iter, refi) {
                        fun = r_anal_fcn_find (core->anal, refi->addr, R_ANAL_FCN_TYPE_NULL);
                        r_cons_printf (" [%i] 0x%08"PFMT64x" %s XREF 0x%08"PFMT64x" (%s)                      \n", count,
                                       refi->at,
                                       refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)":
                                       refi->type==R_ANAL_REF_TYPE_CALL?"CODE (CALL)":"DATA", refi->addr,
                                       fun?fun->name:"unk");
                        if (++count > 9) break;
                    }
                }
            } else xrefs = NULL;
Пример #8
0
static int parse(RParse *p, const char *data, char *str) {
	int i, len = strlen (data);
	char *buf, *ptr, *optr, *ptr2;
	char w0[64];
	char w1[64];
	char w2[64];
	char w3[64];
	char w4[64];

	// malloc can be slow here :?
	if ((buf = malloc (len+1)) == NULL)
		return R_FALSE;
	memcpy (buf, data, len+1);

	if (!strcmp (data, "invalid")
	||  !strcmp (data, "nop")
	||  !strcmp (data, "DEPRECATED")) {
		str[0] = 0;
		return R_TRUE;
	}
	
	r_str_chop (buf);

	if (*buf) {
		w0[0]='\0';
		w1[0]='\0';
		w2[0]='\0';
		w3[0]='\0';
		w4[0]='\0';
		ptr = strchr (buf, ' ');
		if (ptr == NULL)
			ptr = strchr (buf, '\t');
		if (ptr) {
			*ptr = '\0';
			for (++ptr; *ptr==' '; ptr++);
			strcpy (w0, buf);
			strcpy (w1, ptr);

			optr=ptr;
			ptr2 = strchr (ptr, '}');
			if (ptr2) ptr = ptr2+1;
			ptr = strchr (ptr, ',');
			if (ptr) {
				*ptr = '\0';
				for (++ptr; *ptr==' '; ptr++);
				strcpy (w1, optr);
				strcpy (w2, ptr);
				optr=ptr;
				ptr = strchr (ptr, ',');
				if (ptr) {
					*ptr = '\0';
					for (++ptr; *ptr==' '; ptr++);
					strcpy (w2, optr);
					strcpy (w3, ptr);
					optr=ptr;
// bonus
					ptr = strchr (ptr, ',');
					if (ptr) {
						*ptr = '\0';
						for (++ptr; *ptr==' '; ptr++);
						strcpy (w3, optr);
						strcpy (w4, ptr);
					}
				}
			}
		}
		{
			const char *wa[] = { w0, w1, w2, w3, w4 };
			int nw = 0;
			for (i=0; i<4; i++) {
				if (wa[i][0] != '\0')
				nw++;
			}
			replace (nw, wa, str);
{
	char *p = strdup (str);
	p = r_str_replace (p, "+ -", "- ", 0);
#if EXPERIMENTAL_ZERO
	p = r_str_replace (p, "zero", "0", 0);
	if (!memcmp (p, "0 = ", 4)) *p = 0; // nop
#endif
	if (!strcmp (w1, w2)) {
		char a[32], b[32];
#define REPLACE(x,y) \
		sprintf (a, x, w1, w1); \
		sprintf (b, y, w1); \
		p = r_str_replace (p, a, b, 0);

// TODO: optimize
		REPLACE ("%s = %s +", "%s +=");
		REPLACE ("%s = %s -", "%s -=");
		REPLACE ("%s = %s &", "%s &=");
		REPLACE ("%s = %s |", "%s |=");
		REPLACE ("%s = %s ^", "%s ^=");
		REPLACE ("%s = %s >>", "%s >>=");
		REPLACE ("%s = %s <<", "%s <<=");
	}
	strcpy (str, p);
	free (p);
}
		}
	}
	free (buf);
	return R_TRUE;
}
Пример #9
0
char *r_bin_demangle_swift(const char *s) {
#define STRCAT_BOUNDS(x) if ((x+2+strlen (out))>sizeof (out)) break;
	static char *swift_demangle = NULL;
	char out[8192];
	int i, len, is_generic = 0;;
	int is_first = 1;
	int is_last = 0;
	int retmode = 0;
	if (!strncmp (s, "__", 2)) s = s + 2;
	if (!strncmp (s, "imp.", 4)) s = s + 4;
	if (!strncmp (s, "reloc.", 6)) s = s + 6;
#if 0
	const char *element[] = {
		"module", "class", "method", NULL
	};
#endif
	const char *attr = NULL;
	const char *attr2 = NULL;
	const char *q, *p = s;
	if (strncmp (s, "_T", 2)) {
		return NULL;
	}
	if (strchr (s, '\'') || strchr (s, ' '))
		return NULL;

	if (!swift_demangle) {
		swift_demangle = r_file_path ("swift-demangle");
		if (!swift_demangle || !strcmp (swift_demangle, "swift-demangle")) {
			char *xcrun = r_file_path ("xcrun");
			if (xcrun) {
				free (swift_demangle);
				swift_demangle = r_str_newf ("%s swift-demangle", xcrun);
				free (xcrun);
			}
		}
	}
	if (swift_demangle) {
		char *res = r_sys_cmd_strf ("%s -compact -simplified '%s'",
			swift_demangle, s);
		if (res && !*res) {
			free (res);
			res = NULL;
		}
		return r_str_chop (res);
	}
	out[0] = 0;
	p += 2;
	if (*p == 'F' || *p == 'W') {
		q = numpos (p);
		//printf ("(%s)\n", getstring (p, (q-p)));
		for (i=0, len = 1; len; q += len, i++) {
			if (*q=='P') {
		//		printf ("PUBLIC: ");
				q++;
			}
			q = getnum (q, &len);
			if (!len)
				break;
#if 0
			printf ("%s %d %s\n", element[i],
				len, getstring (q, len));
#endif
			// push string
			if (*out)
				strcat (out, ".");
			STRCAT_BOUNDS (len);
			strcat (out, getstring (q, len));
		}
		p = resolve (flags, q, &attr);
		if (!p && *q=='U') {
			p = resolve (metas, q, &attr);
			if (attr) {
				//printf ("Template (%s)\n", attr);
			} else {
				//printf ("Findus (%s)\n", q);
			}
//			return 0;
		}
		if (attr) {
			int len;
			const char *name;
			/* get field name and then type */
			resolve (types, q, &attr);
			//printf ("Accessor: %s\n", attr);
			q = getnum (q+1, &len);
			name = getstring (q, len);
#if 0
			if (name && *name) {
				printf ("Field Name: %s\n", name);
			}
#endif
			resolve (types, q+len, &attr2);
//			printf ("Field Type: %s\n", attr2);

			do {
				if (name && *name) {
					strcat (out, ".");
					STRCAT_BOUNDS (strlen (name));
					strcat (out, name);
				}
				if (attr && *attr) {
					strcat (out, ".");
					STRCAT_BOUNDS (strlen (attr));
					strcat (out, attr);
				}
				if (attr2 && *attr2) {
					strcat (out, "__");
					STRCAT_BOUNDS (strlen (attr2));
					strcat (out, attr2);
				}
			} while (0);
		} else {
			/* parse function parameters here */
			// type len value
			for (i=0; q; i++) {
				switch (*q) {
				case 'B':
				case 'T':
				case 'I':
				case 'F':
					p = resolve (types, q+3, &attr); // type
					break;
				case 'G':
					q+=2;
					//printf ("GENERIC\n");
					if (!strncmp (q, "_V", 2)) {
						q+=2;
					}
					p = resolve (types, q, &attr); // type
					break;
				case 'V':
				//	printf ("VECTOR\n");
					p = resolve (types, q+1, &attr); // type
					break;
				case '_':

					// it's return value time!
					p = resolve (types, q+1, &attr); // type
					//printf ("RETURN TYPE %s\n", attr);
					break;
				default:
					p = resolve (types, q, &attr); // type
				}
				if (p) {
					q = p;
					q = getnum (p, &len);
					if (!strcmp (attr, "generic"))
						is_generic = 1;
					//printf ("TYPE: %s LEN %d VALUE %s\n",
					//	attr, len, getstring (q, len));
					if (!len) {
						if (retmode) {
							p = resolve (types, q+1, &attr); // type
							//printf ("RETURN TYPE %s\n", attr);
		//					printf ("RET %s\n", attr);
							strcat (out, " -> ");
							STRCAT_BOUNDS (strlen (attr));
							strcat (out, attr);
							break;
						}
						retmode = 1;
						len++;
					}
					if (q[len]) {
						const char *s = getstring (q, len);
						if (s && *s) {
							if (is_first) {	
								strcat (out, is_generic?"<":"(");
								is_first = 0;
							}
							//printf ("ISLAST (%s)\n", q+len);
							is_last = q[len];
							STRCAT_BOUNDS (strlen (attr));
							strcat (out, attr);
							strcat (out, " ");
							STRCAT_BOUNDS (strlen (s));
							strcat (out, s);
							if (is_last) {
								strcat (out, is_generic?">":")");
								is_first = 1;
							} else {
								strcat (out, ", ");
							}
						} else {
							strcat (out, " -> ");
							STRCAT_BOUNDS (strlen (attr));
							strcat (out, attr);

						}
					} else {
					}
					q += len;
				} else {
					//printf ("void\n");
					q++;
					break;
				}
			}
		}
	} else {
		//printf ("Unsupported type: %c\n", *p);
	}
	if (*out) {
		char *p, *outstr = strdup (out);
		p = outstr;
		for (;;) {
			p = strstr (p, ")(");
			if (p) {
				p[0] = '_';
				p[1] = '_';
				p+=2;
			} else break;
		}
		return outstr;
	}
	return NULL;
}
Пример #10
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;
		}
Пример #11
0
static int parse(RParse *p, const char *data, char *str) {
    int i, len = strlen (data);
    char w0[WSZ];
    char w1[WSZ];
    char w2[WSZ];
    char w3[WSZ];
    char w4[WSZ];
    char *buf, *ptr, *optr;

    if (!strcmp (data, "jr ra")) {
        strcpy (str, "ret");
        return true;
    }

    // malloc can be slow here :?
    if (!(buf = malloc (len+1)))
        return false;
    memcpy (buf, data, len+1);

    r_str_replace_char (buf, '(', ',');
    r_str_replace_char (buf, ')', ' ');
    r_str_chop (buf);

    if (*buf) {
        w0[0]='\0';
        w1[0]='\0';
        w2[0]='\0';
        w3[0]='\0';
        w4[0]='\0';
        ptr = strchr (buf, ' ');
        if (!ptr)
            ptr = strchr (buf, '\t');
        if (ptr) {
            *ptr = '\0';
            for (++ptr; *ptr==' '; ptr++);
            strncpy (w0, buf, WSZ - 1);
            strncpy (w1, ptr, WSZ - 1);

            optr=ptr;
            ptr = strchr (ptr, ',');
            if (ptr) {
                *ptr = '\0';
                for (++ptr; *ptr==' '; ptr++);
                strncpy (w1, optr, WSZ - 1);
                strncpy (w2, ptr, WSZ - 1);
                optr=ptr;
                ptr = strchr (ptr, ',');
                if (ptr) {
                    *ptr = '\0';
                    for (++ptr; *ptr==' '; ptr++);
                    strncpy (w2, optr, WSZ - 1);
                    strncpy (w3, ptr, WSZ - 1);
                    optr=ptr;
// bonus
                    ptr = strchr (ptr, ',');
                    if (ptr) {
                        *ptr = '\0';
                        for (++ptr; *ptr==' '; ptr++);
                        strncpy (w3, optr, WSZ - 1);
                        strncpy (w4, ptr, WSZ - 1);
                    }
                }
            }
        }
        {
            const char *wa[] = { w0, w1, w2, w3, w4 };
            int nw = 0;
            for (i=0; i<4; i++) {
                if (wa[i][0] != '\0')
                    nw++;
            }
            replace (nw, wa, str);
            {
                char *p = strdup (str);
                p = r_str_replace (p, "+ -", "- ", 0);
                p = r_str_replace(p, " + ]", " + 0]", 0);
#if EXPERIMENTAL_ZERO
                p = r_str_replace (p, "zero", "0", 0);
                if (!memcmp (p, "0 = ", 4)) *p = 0; // nop
#endif
                if (!strcmp (w1, w2)) {
                    char a[32], b[32];
#define REPLACE(x,y) \
		sprintf (a, x, w1, w1); \
		sprintf (b, y, w1); \
		p = r_str_replace (p, a, b, 0);

// TODO: optimize
                    REPLACE ("%s = %s +", "%s +=");
                    REPLACE ("%s = %s -", "%s -=");
                    REPLACE ("%s = %s &", "%s &=");
                    REPLACE ("%s = %s |", "%s |=");
                    REPLACE ("%s = %s ^", "%s ^=");
                    REPLACE ("%s = %s >>", "%s >>=");
                    REPLACE ("%s = %s <<", "%s <<=");
                }
                p = r_str_replace (p, ":", "0000", 0);
                strcpy (str, p);
                free (p);
            }
        }
    }
    free (buf);
    return true;
}
Пример #12
0
static int parse(RParse *p, const char *data, char *str) {
	int i, len = strlen (data);
	char w0[WSZ];
	char w1[WSZ];
	char w2[WSZ];
	char w3[WSZ];
	char w4[WSZ];
	char *buf, *ptr, *optr, *par;

	// malloc can be slow here :?
	if (!(buf = malloc (len + 1))) {
		return false;
	}
	memcpy (buf, data, len + 1);

	r_str_chop (buf);
	if (*buf) {
		w0[0] = '\0';
		w1[0] = '\0';
		w2[0] = '\0';
		w3[0] = '\0';
		w4[0] = '\0';
		ptr = strchr (buf, ' ');
		if (!ptr) {
			ptr = strchr (buf, '\t');
		}
		if (ptr) {
			*ptr = '\0';
			for (++ptr; *ptr == ' '; ptr++) {
				//nothing to see here
			}
			strncpy (w0, buf, WSZ - 1);
			strncpy (w1, ptr, WSZ - 1);

			optr = ptr;
			ptr = strchr (ptr, ',');
			if (ptr) {
				*ptr = '\0';
				for (++ptr; *ptr == ' '; ptr++) {
					//nothing to see here
				}
				strncpy (w1, optr, WSZ - 1);
				strncpy (w2, ptr, WSZ - 1);
				optr = ptr;
				ptr = strchr (ptr, ',');
				if (ptr) {
					*ptr = '\0';
					for (++ptr; *ptr == ' '; ptr++) {
						//nothing to see here
					}
					strncpy (w2, optr, WSZ - 1);
					strncpy (w3, ptr, WSZ - 1);
					optr = ptr;
					// bonus
					ptr = strchr (ptr, ',');
					if (ptr) {
						*ptr = '\0';
						for (++ptr; *ptr == ' '; ptr++) {
							//nothing to see here
						}
						strncpy (w3, optr, WSZ - 1);
						strncpy (w4, ptr, WSZ - 1);
					}
				}
			}
		} else {
			strncpy (w0, buf, WSZ - 1);
		}
		{
			const char *wa[] = { w0, w1, w2, w3, w4 };
			int nw = 0;
			for (i = 0; i < 5; i++) {
				if (wa[i][0] != '\0') {
					nw++;
				}
			}
			replace (nw, wa, str);
		}
	}
	free (buf);
	return true;
}
Пример #13
0
R_API int r_core_visual_cmd(RCore *core, int ch) {
	RAsmOp op;
	char buf[4096];
	int i, ret, offscreen, cols = core->print->cols;
	ch = r_cons_arrow_to_hjkl (ch);
	ch = visual_nkey (core, ch);
	if (ch<2) return 1;

	// do we need hotkeys for data references? not only calls?
	if (ch>='0'&& ch<='9') {
		r_io_sundo_push (core->io, core->offset);
		r_core_seek (core, core->asmqjmps[ch-'0'], 1);
		r_core_block_read (core, 1);
	} else
	switch (ch) {
	case 9: // tab
		{ // XXX: unify diff mode detection
		ut64 f = r_config_get_i (core->config, "diff.from");
		ut64 t = r_config_get_i (core->config, "diff.to");
		if (f == t && f == 0) {
			core->print->col = core->print->col==1? 2: 1;
		} else {
			ut64 delta = core->offset - f;
			r_core_seek (core, t+delta, 1);
			r_config_set_i (core->config, "diff.from", t);
			r_config_set_i (core->config, "diff.to", f);
		}
		}
		break;
	case 'c':
		// XXX dupped flag imho
		setcursor (core, curset ^ 1);
		break;
	case 'd':
		r_core_visual_define (core);
		break;
	case 'D':
		setdiff (core);
		break;
	case 'C':
		color ^= 1;
		if (color) flags |= R_PRINT_FLAGS_COLOR;
		else flags &= ~(flags&R_PRINT_FLAGS_COLOR);
		r_config_set_i (core->config, "scr.color", color);
		r_print_set_flags (core->print, flags);
		break;
	case 'f':
		{
		int range;
		char name[256], *n;
		r_line_set_prompt ("flag name: ");
		if (r_cons_fgets (name, sizeof (name), 0, NULL) >=0 && *name) {
			n = r_str_chop (name);
			if (*name=='-') {
				if (*n) r_flag_unset (core->flags, n+1, NULL);
			} else {
				range = curset? (R_ABS (cursor-ocursor)+1): 1;
				if (range<1) range = 1;
				if (*n) r_flag_set (core->flags, n,
					core->offset + cursor, range, 1);
			}
		} }
		break;
	case 'F':
		r_flag_unset_i (core->flags, core->offset + cursor, NULL);
		break;
	case 'n':
		r_core_seek_next (core, r_config_get (core->config, "scr.nkey"));
		break;
	case 'N':
		r_core_seek_previous (core, r_config_get (core->config, "scr.nkey"));
		break;
	case 'A':
		{ int oc = curset;
		ut64 off = curset? core->offset+cursor : core->offset;
		curset = 0;
		r_core_visual_asm (core, off);
		curset = oc;
		}
		break;
	case 'a':
		if (core->file && !(core->file->rwx & 2)) {
			r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n");
			r_cons_any_key ();
			return R_TRUE;
		}
		r_cons_printf ("Enter assembler opcodes separated with ';':\n");
		r_cons_show_cursor (R_TRUE);
		r_cons_flush ();
		r_cons_set_raw (R_FALSE);
		strcpy (buf, "wa ");
		r_line_set_prompt (":> ");
		if (r_cons_fgets (buf+3, 1000, 0, NULL) <0) buf[0]='\0';
		if (*buf) {
			if (curset) r_core_seek (core, core->offset + cursor, 0);
			r_core_cmd (core, buf, R_TRUE);
			if (curset) r_core_seek (core, core->offset - cursor, 1);
		}
		r_cons_show_cursor (R_FALSE);
		r_cons_set_raw (R_TRUE);
		break;
	case 'i':
	case 'I':
		if (core->file && !(core->file->rwx & 2)) {
			r_cons_printf ("\nFile has been opened in read-only mode. Use -w flag\n");
			r_cons_any_key ();
			return R_TRUE;
		}
		r_cons_show_cursor (R_TRUE);
		r_cons_flush ();
		r_cons_set_raw (0);
		if (ch=='I') {
			strcpy (buf, "wow ");
			r_line_set_prompt ("insert hexpair block: ");
			if (r_cons_fgets (buf+4, sizeof (buf)-3, 0, NULL) <0)
				buf[0]='\0';
			char *p = strdup (buf);
			int cur = core->print->cur;
			if (cur>=core->blocksize)
				cur = core->print->cur-1;
			snprintf (buf, sizeof (buf), "%s @ $$0!%i", p,
				core->blocksize-cursor);
			r_core_cmd (core, buf, 0);
			free (p);
			break;
		}
		if (core->print->col==2) {
			strcpy (buf, "w ");
			r_line_set_prompt ("insert string: ");
			if (r_cons_fgets (buf+2, sizeof (buf)-3, 0, NULL) <0)
				buf[0]='\0';
		} else {
			strcpy (buf, "wx ");
			r_line_set_prompt ("insert hex: ");
			if (r_cons_fgets (buf+3, sizeof (buf)-4, 0, NULL) <0)
				buf[0]='\0';
		}
		if (curset) r_core_seek (core, core->offset + cursor, 0);
		r_core_cmd (core, buf, 1);
		if (curset) r_core_seek (core, core->offset - cursor, 1);
		r_cons_set_raw (1);
		r_cons_show_cursor (R_FALSE);
		break;
	case 'e':
		r_core_visual_config (core);
		break;
	case 'M':
		r_core_visual_mounts (core);
		break;
	case 't':
		r_core_visual_trackflags (core);
		break;
	case 'x':
		{
		int count = 0;
		RList *xrefs = NULL;
		RAnalRef *refi;
		RListIter *iter;
		RAnalFunction *fun;

		if ((xrefs = r_anal_xref_get (core->anal, core->offset))) {
			r_cons_printf ("XREFS:\n");
			if (r_list_empty (xrefs)) {
				r_cons_printf ("\tNo XREF found at 0x%"PFMT64x"\n", core->offset);
				r_cons_any_key ();
				r_cons_clear00 ();
			} else {
				r_list_foreach (xrefs, iter, refi) {
					fun = r_anal_fcn_find (core->anal, refi->addr, R_ANAL_FCN_TYPE_NULL);
					r_cons_printf ("\t[%i] %s XREF 0x%08"PFMT64x" (%s)\n", count,
							refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)":
							refi->type==R_ANAL_REF_TYPE_CALL?"CODE (CALL)":"DATA", refi->addr,
							fun?fun->name:"unk");
					if (++count > 9) break;
				}
			}
		} else xrefs = NULL;
Пример #14
0
R_API void r_core_rtr_add(RCore *core, const char *_input) {
	char *port, input[1024], *host = NULL, *file = NULL, *ptr = NULL, buf[1024];
	int proto, i, timeout, ret;
	RSocket *fd;

	timeout = r_config_get_i (core->config, "http.timeout");
	strncpy (input, _input, sizeof (input)-4);
	/* Parse uri */
	if ((ptr = strstr (input, "tcp://"))) {
		proto = RTR_PROT_TCP;
		host = ptr+6;
	} else if ((ptr = strstr(input, "http://"))) {
		proto = RTR_PROT_HTTP;
		host = ptr+7;
	} else if ((ptr = strstr(input, "udp://"))) {
		proto = RTR_PROT_UDP;
		host = ptr+6;
	} else if ((ptr = strstr(input, "rap://"))) {
		proto = RTR_PROT_RAP;
		host = ptr+6;
	} else {
		proto = RTR_PROT_RAP;
		host = input;
	}
	while (*host && iswhitechar (*host))
		host++;

	if (!(ptr = strchr (host, ':'))) {
		ptr = host;
		port = "80";
	} else {
		*ptr++ = '\0';
		port = ptr;
	}

	if (!(file = strchr (ptr, '/'))) {
		eprintf("Error: Missing '/'\n");
		return;
	}
	*file++ = 0;
	port = r_str_chop (port);
	while (*file==' ') file++;
	if (r_sandbox_enable (0)) {
		eprintf ("sandbox: connect disabled\n");
		return;
	}

	fd = r_socket_new (R_FALSE);
	if (!fd) {
		eprintf ("Error: Cannot create new socket\n");
		return;
	}
	switch (proto) {
	case RTR_PROT_HTTP:
		{
			char uri[1024], prompt[64];
			int len;
			char *str, *res;
			if (file[strlen (file)-1]=='/') {
				snprintf (prompt, sizeof (prompt), "[http://%s:%s/%s]> ",
					host, port, file);
				r_line_set_prompt (prompt);
				for (;;) {
					char *ptr, *str = r_line_readline ();
					if (!str || !*str) break;
					if (*str == 'q') break;
					ptr = r_str_uri_encode (str);
					if (ptr) str = ptr;
					snprintf (uri, sizeof (uri), "http://%s:%s/%s%s",
						host, port, file, str);
					if (ptr == str) free (ptr);
					str = r_socket_http_get (uri, NULL, &len);
					if (str) {
						str[len] = 0;
						res = strstr (str, "\n\n");
						if (res) res = strstr (res+1, "\n\n");
						if (res) res += 2; else res = str;
						printf ("%s%s", res, (res[strlen (res)-1]=='\n')?"":"\n");
						r_line_hist_add (str);
						free (str);
					}
				}
				r_socket_free (fd);
				return;
			}
			snprintf (uri, sizeof (uri), "http://%s:%s/%s",
				host, port, file);
			str = r_socket_http_get (uri, NULL, &len);
			if (str) {
				str[len] = 0;
				res = strstr (str, "\n\n");
				if (res) res = strstr (res+1, "\n\n");
				if (res) res += 2; else res = str;
				printf ("%s", res);
				free (str);
			} else eprintf ("HTTP connection has failed\n");
			// do not add connection. wtf
			return;
		}
		break;
	case RTR_PROT_RAP:
		if (!r_socket_connect_tcp (fd, host, port, timeout)) { //TODO: Use rap.ssl
			eprintf ("Error: Cannot connect to '%s' (%s)\n", host, port);
			return;
		}
		eprintf ("Connected to %s at port %s\n", host, port);
		/* send */
		buf[0] = RTR_RAP_OPEN;
		buf[1] = 0;
		buf[2] = (ut8)(strlen (file)+1);
		memcpy (buf+3, file, buf[2]);
		r_socket_write(fd, buf, 3+buf[2]);
		/* read */
		eprintf ("waiting... "); fflush(stdout);
		r_socket_read (fd, (ut8*)buf, 5);
		r_mem_copyendian ((ut8 *)&i, (ut8*)buf+1, 4, core->assembler->big_endian);
		if (buf[0] != (char)(RTR_RAP_OPEN|RTR_RAP_REPLY) || i<= 0) {
			eprintf ("Error: Wrong reply\n");
			return;
		}
		eprintf ("ok\n");
		break;
	case RTR_PROT_TCP:
		if (!r_socket_connect_tcp (fd, host, port, timeout)) { //TODO: Use rap.ssl
			core->num->value = 1;
			eprintf("Error: Cannot connect to '%s' (%s)\n", host, port);
			return;
		}
		core->num->value = 0;
		eprintf ("Connected to: %s at port %s\n", host, port);
		break;
	case RTR_PROT_UDP:
		if (!r_socket_connect_udp (fd, host, port, timeout)) { //TODO: Use rap.ssl
			core->num->value = 1;
			eprintf ("Error: Cannot connect to '%s' (%s)\n", host, port);
			return;
		}
		core->num->value = 0;
		eprintf("Connected to: %s at port %s\n", host, port);
		break;
	}

	ret = core->num->value;
	for (i = 0; i < RTR_MAX_HOSTS; i++)
		if (!rtr_host[i].fd) {
			rtr_host[i].proto = proto;
			memcpy (rtr_host[i].host, host, 512);
			rtr_host[i].port = r_num_get (core->num, port);
			memcpy (rtr_host[i].file, file, 1024);
			rtr_host[i].fd = fd;
			rtr_n = i;
			break;
		}
	core->num->value = ret;
	r_socket_free(fd);
	//r_core_rtr_list (core);
}