// TODO: integrate in '/' command with search.inblock ? static void visual_search (RCore *core) { const ut8 *p; int len, d = cursor; char str[128], buf[258]; r_line_set_prompt ("search byte/string in block: "); r_cons_fgets (str, sizeof (str), 0, NULL); len = r_hex_str2bin (str, (ut8*)buf); if (*str=='"') { char *e = strncpy (buf, str+1, sizeof (buf)-1); if (e) { --e; if (*e=='"') *e=0; } len = strlen (buf); } else if (len<1) { strncpy (buf, str, sizeof (buf)-1); len = strlen (str); } p = r_mem_mem (core->block+d, core->blocksize-d, (const ut8*)buf, len); if (p) { cursor = (int)(size_t)(p-core->block); if (len>1) { ocursor = cursor+len-1; } else ocursor = -1; showcursor (core, R_TRUE); eprintf ("FOUND IN %d\n", cursor); r_cons_any_key (); } else { eprintf ("Cannot find bytes\n"); r_cons_any_key (); r_cons_clear00 (); } }
R_API char *r_cons_editor (const char *file, const char *str) { const char *line; _n = 0; if (I->editor) { return I->editor (I->user, file, str); } free (path); if (file) { path = strdup (file); bytes = 0; lines = r_file_slurp (file, &bytes); nlines = r_str_split (lines, '\n'); eprintf ("Loaded %d lines on %d bytes\n", (nlines?(nlines-1):0), bytes); } else path = NULL; I->line->hist_up = up; I->line->hist_down = down; I->line->contents = I->line->buffer.data; for (;;) { setnewline (_n); snprintf (prompt, sizeof (prompt), "%d: ", _n); r_line_set_prompt (prompt); line = r_line_readline (); saveline (_n, line); _n++; if (!line) break; } filesave (); I->line->hist_up = I->line->hist_down = NULL; I->line->contents = NULL; return lines; }
static int textlog_chat (RCore *core) { char prompt[64]; char buf[1024]; int lastmsg = 0; const char *me = r_config_get (core->config, "cfg.user"); char msg[1024]; eprintf ("Type '/help' for commands:\n"); snprintf (prompt, sizeof (prompt)-1, "[%s]> ", me); r_line_set_prompt (prompt); for (;;) { r_core_log_list (core, lastmsg, 0, 0); lastmsg = core->log->last; if (r_cons_fgets (buf, sizeof (buf)-1, 0, NULL)<0) return 1; if (!*buf) continue; if (!strcmp (buf, "/help")) { eprintf ("/quit quit the chat (same as ^D)\n"); eprintf ("/name <nick> set cfg.user name\n"); eprintf ("/log show full log\n"); eprintf ("/clear clear text log messages\n"); } else if (!strncmp (buf, "/name ", 6)) { snprintf (msg, sizeof (msg)-1, "* '%s' is now known as '%s'", me, buf+6); r_core_log_add (core, msg); r_config_set (core->config, "cfg.user", buf+6); me = r_config_get (core->config, "cfg.user"); snprintf (prompt, sizeof (prompt)-1, "[%s]> ", me); r_line_set_prompt (prompt); return 0; } else if (!strcmp (buf, "/log")) { r_core_log_list (core, 0, 0, 0); return 0; } else if (!strcmp (buf, "/clear")) { //r_core_log_del (core, 0); r_core_cmd0 (core, "T-"); return 0; } else if (!strcmp (buf, "/quit")) { return 0; } else if (*buf=='/') { eprintf ("Unknown command: %s\n", buf); } else { snprintf (msg, sizeof (msg)-1, "[%s] %s", me, buf); r_core_log_add (core, msg); } } return 1; }
static void setnewline(int old) { snprintf (prompt, sizeof (prompt), "%d: ", _n); r_line_set_prompt (prompt); strcpy (I->line->buffer.data, r_str_word_get0 (lines, _n)); I->line->buffer.index = I->line->buffer.length = strlen (I->line->buffer.data); I->line->contents = I->line->buffer.data; }
R_API void r_core_visual_prompt (RCore *core) { char buf[1024]; ut64 oseek = core->offset; #if __UNIX__ r_line_set_prompt (Color_RESET":> "); #else r_line_set_prompt (":> "); #endif showcursor (core, R_TRUE); r_cons_fgets (buf, sizeof (buf), 0, NULL); r_line_hist_add (buf); r_core_cmd (core, buf, 0); r_cons_any_key (); r_cons_clear00 (); showcursor (core, R_FALSE); if (curset) r_core_seek (core, oseek, 1); }
R_API char *r_cons_input(const char *msg) { char *oprompt = r_line_get_prompt (); if (!oprompt) { return NULL; } char buf[1024]; if (msg) { r_line_set_prompt (msg); } else { r_line_set_prompt (""); } buf[0] = 0; r_cons_fgets (buf, sizeof (buf), 0, NULL); r_line_set_prompt (oprompt); free (oprompt); return strdup (buf); }
static void visual_offset (RCore *core) { char buf[256]; r_line_set_prompt ("[offset]> "); strcpy (buf, "s "); if (r_cons_fgets (buf+2, sizeof (buf)-3, 0, NULL) >0) { if (buf[2]=='.')buf[1]='.'; r_core_cmd0 (core, buf); } }
static void prompt_read (const char *p, char *buf, int buflen) { r_line_set_prompt (p); showcursor (NULL, true); r_cons_fgets (buf, buflen, 0, NULL); showcursor (NULL, false); }
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;
R_API int r_cons_less_str(const char *str, const char *exitkeys) { static int in_help = false; static const char *r_cons_less_help = \ " u/space - page up/down\n" " jk - line down/up\n" " gG - begin/end buffer\n" " / - search in buffer\n" " _ - enter the hud mode\n" " n/p - next/prev search result\n" " q - quit\n" " ? - show this help\n" "\n"; int lines_count = 0; RRegex *rx = NULL; int w, h, ch, to, ui = 1, from = 0, i; const char *sreg; RList **mla; if (!str || !*str) { return 0; } // rcons kills str after flushing the buffer, so we must keep a copy char *ostr = strdup (str); if (!ostr) { return 0; } char *p = strdup (str); if (!p) { free (ostr); return 0; } int *lines = pager_splitlines (p, &lines_count); if (lines_count < 1) { mla = NULL; } else { mla = calloc (lines_count, sizeof (RList *)); if (!mla) { free (p); free (ostr); free (lines); return 0; } } for (i = 0; i < lines_count; i++) { mla[i] = r_list_new (); } r_cons_set_raw (true); r_cons_show_cursor (false); r_cons_reset (); h = 0; while (ui) { w = r_cons_get_size (&h); to = R_MIN (lines_count, from + h); if (from + 3 > lines_count) { from = lines_count - 3; } if (from < 0) { from = 0; } pager_printpage (p, lines, mla, from, to, w); ch = r_cons_readchar (); if (exitkeys && strchr (exitkeys, ch)) { for (i = 0; i < lines_count; i++) { r_list_free (mla[i]); } free (p); free (mla); free (ostr); free (lines); return ch; } ch = r_cons_arrow_to_hjkl (ch); switch (ch) { case '_': r_cons_hud_string (ostr); break; case '?': if (!in_help) { in_help = true; r_cons_less_str (r_cons_less_help, NULL); in_help = false; } break; case 'u': from -= h; if (from < 0) { from = 0; } break; case ' ': from += h; break; case 'g': from = 0; break; case 'G': from = lines_count-h; break; case -1: // EOF case '\x03': // ^C case 'q': ui = 0; break; case '\r': case '\n': case 'j': from++; break; case 'J': from+=h; break; case 'k': if (from > 0) { from--; } break; case 'K': from = (from>=h)? from-h: 0; break; case '/': /* search */ r_cons_reset_colors (); r_line_set_prompt ("/"); sreg = r_line_readline (); from = R_MIN (lines_count - 1, from); /* repeat last search if empty string is provided */ if (sreg[0]) { /* prepare for a new search */ if (rx) { r_regex_free (rx); } rx = r_regex_new (sreg, ""); } else { /* we got an empty string */ from = pager_next_match (from, mla, lines_count); break; } if (!rx) { break; } /* find all occurences */ if (pager_all_matches (p, rx, mla, lines, lines_count)) { from = pager_next_match (from, mla, lines_count); } break; case 'n': /* next match */ /* search already performed */ if (rx) { from = pager_next_match (from, mla, lines_count); } break; case 'N': case 'p': /* previous match */ if (rx) { from = pager_prev_match (from, mla); } break; } } for (i = 0; i < lines_count; i++) { r_list_free (mla[i]); } free (mla); r_regex_free (rx); free (lines); free (p); r_cons_reset_colors (); r_cons_set_raw (false); r_cons_show_cursor (true); free (ostr); return 0; }
static void prompt_read (const char *p, char *buf, int buflen) { r_line_set_prompt (p); r_cons_show_cursor (R_TRUE); r_cons_fgets (buf, buflen, 0, NULL); r_cons_show_cursor (R_FALSE); }
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;
R_API void r_cons_less_str(const char *str) { int lines_count; RRegex *rx = NULL; int w, h, ch, to, ui = 1, from = 0, i; const char *sreg; if(str == NULL || str[0] == '\0') return; char *p = strdup (str); int *lines = splitlines (p, &lines_count); RRegexMatch **ms = malloc(lines_count * sizeof(void *)); for(i = 0; i < lines_count; i++) ms[i] = calloc(NMATCHES, sizeof(RRegexMatch)); r_cons_set_raw (R_TRUE); r_cons_show_cursor (R_FALSE); r_cons_reset (); w = h = 0; while (ui) { w = r_cons_get_size (&h); to = R_MIN (lines_count, from+h); if (from+3>lines_count) from = lines_count-3; if (from<0) from = 0; printpage (p, lines, ms, from, to, w); ch = r_cons_readchar (); ch = r_cons_arrow_to_hjkl (ch); switch (ch) { case ' ': from += h; break; case 'g': from = 0; break; case 'G': from = lines_count-1-h; break; case -1: // EOF case 'q': ui = 0; break; case '\r': case '\n': case 'j': from++; break; case 'J': from+=h; break; case 'k': if (from>0) from--; break; case 'K': from = (from>=h)? from-h: 0; break; case '/': /* search */ r_cons_reset_colors(); r_line_set_prompt("/"); sreg = r_line_readline(); from = R_MIN(lines_count - 1, from); /* repeat last search if empty string is provided */ if(sreg[0]){ /* prepare for a new search */ if(rx) r_regex_free(rx); rx = r_regex_new(sreg, ""); } else { /* we got an empty string */ from = next_match(from, ms, lines_count); break; } if(!rx) break; /* find all occurences */ if(all_matches(p, rx, ms, lines, lines_count)) from = next_match(from, ms, lines_count); break; case 'n': /* next match */ /* search already performed */ if(rx) from = next_match(from, ms, lines_count); break; case 'p': /* previous match */ if(rx) from = prev_match(from, ms); break; } } for(i = 0; i < lines_count; i++) free(ms[i]); free(ms); if(rx) r_regex_free(rx); free (lines); free (p); r_cons_reset_colors(); r_cons_set_raw (R_FALSE); r_cons_show_cursor (R_TRUE); }
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); }