R_API void r_core_visual_seek_animation (RCore *core, ut64 addr) { if (r_config_get_i (core->config, "scr.feedback")<1) return; #if 0 int i, ns = 90000; const char *scmd = (addr > core->offset)? "so": "s-4"; for (i=0;i<5;i++) { r_core_cmd0 (core, scmd); r_core_visual_refresh (core); r_cons_flush(); r_sys_usleep (ns); ns -= 1000; } r_core_seek (core, addr, 1); #else if (core->offset == addr) return; r_cons_gotoxy (1, 2); if (addr>core->offset) { r_cons_printf (".----.\n"); r_cons_printf ("| \\/ |\n"); r_cons_printf ("'----'\n"); } else { r_cons_printf (".----.\n"); r_cons_printf ("| /\\ |\n"); r_cons_printf ("'----'\n"); } r_cons_flush(); r_sys_usleep (90000); #endif r_core_seek (core, addr, 1); }
R_API bool r_socket_spawn(RSocket *s, const char *cmd, unsigned int timeout) { // XXX TODO: dont use sockets, we can achieve the same with pipes const int port = 2000 + r_num_rand (2000); int childPid = r_sys_fork (); if (childPid == 0) { char *a = r_str_replace (strdup (cmd), "\\", "\\\\", true); int res = r_sys_cmdf ("rarun2 system=\"%s\" listen=%d", a, port); free (a); #if 0 // TODO: use the api char *profile = r_str_newf ( "system=%s\n" "listen=%d\n", cmd, port); RRunProfile *rp = r_run_new (profile); r_run_start (rp); r_run_free (rp); free (profile); #endif if (res != 0) { eprintf ("r_socket_spawn: rarun2 failed\n"); exit (1); } eprintf ("r_socket_spawn: %s is dead\n", cmd); exit (0); } r_sys_sleep (1); r_sys_usleep (timeout); char aport[32]; sprintf (aport, "%d", port); // redirect stdin/stdout/stderr bool sock = r_socket_connect (s, "127.0.0.1", aport, R_SOCKET_PROTO_TCP, 2000); if (!sock) { return false; } #if __UNIX__ r_sys_sleep (4); r_sys_usleep (timeout); int status = 0; int ret = waitpid (childPid, &status, WNOHANG); if (ret != 0) { r_socket_close (s); return false; } #endif return true; }
/* Read/Write functions */ R_API int r_socket_write(RSocket *s, void *buf, int len) { int ret, delta = 0; #if __UNIX__ signal (SIGPIPE, SIG_IGN); #endif for (;;) { int b = 1500; //65536; // Use MTU 1500? if (b>len) b = len; #if HAVE_LIB_SSL if (s->is_ssl) { if (s->bio) ret = BIO_write (s->bio, buf+delta, b); else ret = SSL_write (s->sfd, buf+delta, b); } else #endif { ret = send (s->fd, buf+delta, b, 0); } //if (ret == 0) return -1; if (ret<1) break; if (ret == len) return len; r_sys_usleep (100); // take breath, wtf delta += ret; len -= ret; } if (ret == -1) return -1; return delta; }
int test1() { int ctr = 0; struct r_th_t *th; th = r_th_new (&looper, &ctr, 0); th = r_th_new (&looper, &ctr, 0); //th = r_th_new (&looper, &ctr, 0); #if __i386__ || __x86_64__ asm ("int3"); #endif //r_th_start (th, true); while (r_th_wait_async (th)) { printf ("\nwaiting...\n"); fflush (stdout); r_sys_usleep (400); // r_th_break(th); } printf ("\nfinished\n"); #if 0 r_th_start(th, true); sleep(1); #endif /* wait and free */ r_th_wait (th); r_th_free (th); printf ("\nresult %d\n", ctr); return 0; }
R_API int r_socket_spawn (RSocket *s, const char *cmd, unsigned int timeout) { // XXX TODO: dont use sockets, we can achieve the same with pipes const int port = 2000 + r_num_rand (2000); int childPid = r_sys_fork(); if (childPid == 0) { char *a = r_str_replace (strdup (cmd), "\\", "\\\\", true); r_sys_cmdf ("rarun2 system=\"%s\" listen=%d", a, port); free (a); #if 0 // TODO: use the api char *profile = r_str_newf ( "system=%s\n" "listen=%d\n", cmd, port); RRunProfile *rp = r_run_new (profile); r_run_start (rp); r_run_free (rp); free (profile); #endif eprintf ("r_socket_spawn: %s is dead\n", cmd); exit (0); } r_sys_sleep (1); r_sys_usleep (timeout); char aport[32]; sprintf (aport, "%d", port); // redirect stdin/stdout/stderr return r_socket_connect (s, "127.0.0.1", aport, R_SOCKET_PROTO_TCP, 2000); }
// TODO: support len for binary data? R_API char *r_core_rtr_cmds_query (RCore *core, const char *host, const char *port, const char *cmd) { int retries = 6; unsigned char buf[1024]; char *rbuf = NULL; const int timeout = 0; RSocket *s = r_socket_new (0); for (;retries>0; r_sys_usleep (10*1000)) { if (r_socket_connect (s, host, port, R_SOCKET_PROTO_TCP, timeout)) break; retries--; } if (retries>0) { rbuf = strdup (""); r_socket_write (s, (void*)cmd, strlen (cmd)); //r_socket_write (s, "px\n", 3); for (;;) { int ret = r_socket_read (s, buf, sizeof (buf)); if (ret<1) break; buf[ret] = 0; rbuf = r_str_concat (rbuf, (const char *)buf); } } else { eprintf ("Cannot connect\n"); } r_socket_free (s); return rbuf; }
static RThreadFunctionRet loading_thread(RThread *th) { const char *tok = "\\|/-"; int i = 0; if (th) { while (!th->breaked) { eprintf ("%c] Loading..%c \r[", tok[i%4], "."[i%2]); r_sys_usleep (100000); i++; } } return R_TH_STOP; }
R_API void r_cons_flush() { const char *tee = I.teefile; if (I.noflush) { return; } if (I.null) { r_cons_reset (); return; } r_cons_filter (); if (I.is_interactive && I.fdout == 1) { /* Use a pager if the output doesn't fit on the terminal window. */ if (I.pager && *I.pager && I.buffer_len > 0 && r_str_char_count (I.buffer, '\n') >= I.rows) { I.buffer[I.buffer_len-1] = 0; r_sys_cmd_str_full (I.pager, I.buffer, NULL, NULL, NULL); r_cons_reset (); } else if (I.buffer_len > CONS_MAX_USER) { #if COUNT_LINES int i, lines = 0; for (i = 0; I.buffer[i]; i++) { if (I.buffer[i] == '\n') { lines ++; } } if (lines > 0 && !r_cons_yesno ('n',"Do you want to print %d lines? (y/N)", lines)) { r_cons_reset (); return; } #else char buf[64]; char *buflen = r_num_units (buf, I.buffer_len); if (buflen && !r_cons_yesno ('n',"Do you want to print %s chars? (y/N)", buflen)) { r_cons_reset (); return; } #endif // fix | more | less problem r_cons_set_raw (1); } } if (tee && *tee) { FILE *d = r_sandbox_fopen (tee, "a+"); if (d) { if (I.buffer_len != fwrite (I.buffer, 1, I.buffer_len, d)) { eprintf ("r_cons_flush: fwrite: error (%s)\n", tee); } fclose (d); } else { eprintf ("Cannot write on '%s'\n", tee); } } r_cons_highlight (I.highlight); // is_html must be a filter, not a write endpoint if (I.is_html) { r_cons_html_print (I.buffer); } else { if (I.is_interactive && !r_sandbox_enable (false)) { if (I.linesleep > 0 && I.linesleep < 1000) { int i = 0; int pagesize = R_MAX (1, I.pagesize); char *ptr = I.buffer; char *nl = strchr (ptr, '\n'); int len = I.buffer_len; I.buffer[I.buffer_len] = 0; r_cons_break_push (NULL, NULL); while (nl && !r_cons_is_breaked ()) { r_cons_write (ptr, nl - ptr + 1); if (!(i % pagesize)) { r_sys_usleep (I.linesleep * 1000); } ptr = nl + 1; nl = strchr (ptr, '\n'); i++; } r_cons_write (ptr, I.buffer + len - ptr); r_cons_break_pop (); } else { r_cons_write (I.buffer, I.buffer_len); } } else { r_cons_write (I.buffer, I.buffer_len); } } r_cons_reset (); if (I.newline) { eprintf ("\n"); I.newline = false; } }
- follow symlinks #endif R_API int r_core_rtr_http(RCore *core, int launch, const char *path) { RSocketHTTPRequest *rs; int oldsandbox = -1; int timeout = r_config_get_i (core->config, "http.timeout"); int x = r_config_get_i (core->config, "scr.html"); int y = r_config_get_i (core->config, "scr.color"); int z = r_config_get_i (core->config, "asm.bytes"); int u = r_config_get_i (core->config, "scr.interactive"); int v = r_config_get_i (core->config, "asm.cmtright"); const char *port = r_config_get (core->config, "http.port"); if (r_sandbox_enable (0)) { eprintf ("sandbox: connect disabled\n"); return 1; } s = r_socket_new (R_FALSE); s->local = !r_config_get_i (core->config, "http.public"); if (!r_socket_listen (s, port, NULL)) { eprintf ("Cannot listen on http.port\n"); return 1; } if (launch) { char cmd[128]; const char *browser = r_config_get (core->config, "http.browser"); snprintf (cmd, sizeof (cmd)-1, "%s http://localhost:%d/%s", browser, atoi (port), path?path:""); r_sys_cmd (cmd); } r_config_set (core->config, "asm.cmtright", "false"); r_config_set (core->config, "scr.html", "true"); r_config_set (core->config, "scr.color", "false"); r_config_set (core->config, "asm.bytes", "false"); r_config_set (core->config, "scr.interactive", "false"); if (r_config_get_i (core->config, "http.sandbox")) { oldsandbox = r_config_get_i (core->config, "cfg.sandbox"); r_config_set (core->config, "cfg.sandbox", "true"); } eprintf ("Starting http server...\n"); eprintf ("http://localhost:%d/\n", atoi (port)); while (!r_cons_singleton ()->breaked) { r_cons_break (http_break, core); rs = r_socket_http_accept (s, timeout); if (!rs) { if (!s) break; r_sys_usleep (200); continue; } if (!rs->method || !rs->path) { r_socket_http_close (rs); continue; } if (!strcmp (rs->method, "GET")) { if (!memcmp (rs->path, "/up", 3)) { if (r_config_get_i (core->config, "http.upget")) { const char *uproot = r_config_get (core->config, "http.uproot"); if (!rs->path[3] || (rs->path[3]=='/'&&!rs->path[4])) { char *ptr = strdup ("<html><body>\n"); const char *file; RListIter *iter; // list files RList *files = r_sys_dir (uproot); eprintf ("Listing directory %s\n", uproot); r_list_foreach (files, iter, file) { if (file[0] == '.') continue; ptr = r_str_concatf (ptr, "<a href=\"/up/%s\">%s</a><br />\n", file, file); } r_list_free (files); ptr = r_str_concat (ptr, "<html><body>\n"); r_socket_http_response (rs, 200, ptr, 0, NULL); } else { char *path = r_file_root (uproot, rs->path + 4); if (r_file_exists (path)) { int sz = 0; char *f = r_file_slurp (path, &sz); if (f) { r_socket_http_response (rs, 200, f, sz, NULL); free (f); } else { r_socket_http_response (rs, 403, "Permission denied", 0, NULL); eprintf ("http: Cannot open '%s'\n", path); } } else { eprintf ("File '%s' not found\n", path); r_socket_http_response (rs, 404, "File not found\n", 0, NULL); } free (path); } } else { r_socket_http_response (rs, 403, "Permission denied\n", 0, NULL); } } else if (!memcmp (rs->path, "/cmd/", 5)) {
R_API int r_core_rtr_http(RCore *core, int launch, const char *path) { char buf[32]; RSocketHTTPRequest *rs; int iport, oldsandbox = -1; int timeout = r_config_get_i (core->config, "http.timeout"); int x = r_config_get_i (core->config, "scr.html"); int y = r_config_get_i (core->config, "scr.color"); int z = r_config_get_i (core->config, "asm.bytes"); int u = r_config_get_i (core->config, "scr.interactive"); int v = r_config_get_i (core->config, "asm.cmtright"); const char *port = r_config_get (core->config, "http.port"); char *allow = (char *)r_config_get (core->config, "http.allow"); if (core->http_up) { eprintf ("http server is already running\n"); return 1; } if (r_sandbox_enable (0)) { eprintf ("sandbox: connect disabled\n"); return 1; } if (path && atoi (path)) { port = path; path = NULL; } if (!strcmp (port, "0")) { r_num_irand (); iport = 1024+r_num_rand (45256); snprintf (buf, sizeof (buf), "%d", iport); port = buf; } s = r_socket_new (R_FALSE); s->local = !r_config_get_i (core->config, "http.public"); if (!r_socket_listen (s, port, NULL)) { eprintf ("Cannot listen on http.port\n"); return 1; } if (launch) { char cmd[128]; const char *browser = r_config_get (core->config, "http.browser"); snprintf (cmd, sizeof (cmd)-1, "%s http://localhost:%d/%s &", browser, atoi (port), path?path:""); r_sys_cmd (cmd); } r_config_set (core->config, "asm.cmtright", "false"); r_config_set (core->config, "scr.html", "true"); r_config_set (core->config, "scr.color", "false"); r_config_set (core->config, "asm.bytes", "false"); r_config_set (core->config, "scr.interactive", "false"); if (r_config_get_i (core->config, "http.sandbox")) { oldsandbox = r_config_get_i (core->config, "cfg.sandbox"); r_config_set (core->config, "cfg.sandbox", "true"); } eprintf ("Starting http server...\n"); eprintf ("http://localhost:%d/\n", atoi (port)); core->http_up = R_TRUE; while (!r_cons_singleton ()->breaked) { r_cons_break ((RConsBreak)http_break, core); rs = r_socket_http_accept (s, timeout); if (!rs) { if (!s) break; r_sys_usleep (100); continue; } if (allow && *allow) { int accepted = R_FALSE; const char *host; char *p, *peer = r_socket_to_string (rs->s); char *allows = strdup (allow); //eprintf ("Firewall (%s)\n", allows); int i, count = r_str_split (allows, ','); p = strchr (peer, ':'); if (p) *p = 0; for (i=0; i<count; i++) { host = r_str_word_get0 (allows, i); //eprintf ("--- (%s) (%s)\n", host, peer); if (!strcmp (host, peer)) { accepted = R_TRUE; break; } } free (peer); free (allows); if (!accepted) { r_socket_http_close (rs); continue; } } if (!rs->method || !rs->path) { eprintf ("Invalid http headers received from client\n"); r_socket_http_close (rs); continue; } char *dir = NULL; if (r_config_get_i (core->config, "http.dirlist")) if (r_file_is_directory (rs->path)) dir = strdup (rs->path); if (!strcmp (rs->method, "GET")) { if (!memcmp (rs->path, "/up", 3)) { if (r_config_get_i (core->config, "http.upget")) { const char *uproot = r_config_get (core->config, "http.uproot"); if (!rs->path[3] || (rs->path[3]=='/'&&!rs->path[4])) { char *ptr = rtr_dir_files (uproot); r_socket_http_response (rs, 200, ptr, 0, NULL); free (ptr); } else { char *path = r_file_root (uproot, rs->path + 4); if (r_file_exists (path)) { int sz = 0; char *f = r_file_slurp (path, &sz); if (f) { r_socket_http_response (rs, 200, f, sz, NULL); free (f); } else { r_socket_http_response (rs, 403, "Permission denied", 0, NULL); eprintf ("http: Cannot open '%s'\n", path); } } else { if (dir) { char *resp = rtr_dir_files (dir); r_socket_http_response (rs, 404, resp, 0, NULL); free (resp); } else { eprintf ("File '%s' not found\n", path); r_socket_http_response (rs, 404, "File not found\n", 0, NULL); } } free (path); } } else { r_socket_http_response (rs, 403, "Permission denied\n", 0, NULL); } } else if (!memcmp (rs->path, "/cmd/", 5)) { char *cmd = rs->path +5; char foo[32]; const char *httpcmd = r_config_get (core->config, "http.uri"); while (*cmd=='/') cmd++; if (httpcmd && *httpcmd) { int len; char *res; // do remote http query and proxy response snprintf (foo, sizeof (foo), "%s/%s", httpcmd, cmd); res = r_socket_http_get (foo, NULL, &len); if (res) { res[len]=0; r_cons_printf ("%s\n", res); } } else { char *out, *cmd = rs->path+5; r_str_uri_decode (cmd); // eprintf ("CMD (%s)\n", cmd); out = r_core_cmd_str_pipe (core, cmd); // eprintf ("\nOUT LEN = %d\n", strlen (out)); if (out) { char *res = r_str_uri_encode (out); r_socket_http_response (rs, 200, out, 0, "Content-Type: text/plain\n"); free (out); free (res); } else r_socket_http_response (rs, 200, "", 0, NULL); } } else { const char *root = r_config_get (core->config, "http.root"); char *path = r_file_root (root, rs->path); // FD IS OK HERE if (rs->path [strlen (rs->path)-1] == '/') { path = r_str_concat (path, "index.html"); //rs->path = r_str_concat (rs->path, "index.html"); } else { //snprintf (path, sizeof (path), "%s/%s", root, rs->path); if (r_file_is_directory (path)) { char res[128]; snprintf (res, sizeof (res), "Location: %s/\n", rs->path); r_socket_http_response (rs, 302, NULL, 0, res); r_socket_http_close (rs); free (path); free (dir); dir = NULL; continue; } } if (r_file_exists (path)) { int sz = 0; char *f = r_file_slurp (path, &sz); if (f) { const char *contenttype = NULL; if (strstr (path, ".js")) contenttype = "Content-Type: application/javascript\n"; if (strstr (path, ".css")) contenttype = "Content-Type: text/css\n"; if (strstr (path, ".html")) contenttype = "Content-Type: text/html\n"; r_socket_http_response (rs, 200, f, sz, contenttype); free (f); } else { r_socket_http_response (rs, 403, "Permission denied", 0, NULL); eprintf ("http: Cannot open '%s'\n", path); } } else { if (dir) { char *resp = rtr_dir_files (dir); eprintf ("Dirlisting %s\n", dir); r_socket_http_response (rs, 404, resp, 0, NULL); free (resp); } else { eprintf ("File '%s' not found\n", path); r_socket_http_response (rs, 404, "File not found\n", 0, NULL); } } free (path); } } else if (!strcmp (rs->method, "POST")) { ut8 *ret; int retlen; char buf[128]; if (r_config_get_i (core->config, "http.upload")) { ret = r_socket_http_handle_upload ( rs->data, rs->data_length, &retlen); if (ret) { ut64 size = r_config_get_i (core->config, "http.maxsize"); if (size && retlen > size) { r_socket_http_response (rs, 403, "403 File too big\n", 0, NULL); } else { char *filename = r_file_root ( r_config_get (core->config, "http.uproot"), rs->path + 4); eprintf ("UPLOADED '%s'\n", filename); r_file_dump (filename, ret, retlen); free (filename); snprintf (buf, sizeof (buf), "<html><body><h2>uploaded %d bytes. Thanks</h2>\n", retlen); r_socket_http_response (rs, 200, buf, 0, NULL); } free (ret); } } else { r_socket_http_response (rs, 403, "403 Forbidden\n", 0, NULL); } } else { r_socket_http_response (rs, 404, "Invalid protocol", 0, NULL); } r_socket_http_close (rs); free (dir); } core->http_up = R_FALSE; r_socket_free (s); r_cons_break_end (); r_config_set_i (core->config, "scr.html", x); r_config_set_i (core->config, "scr.color", y); r_config_set_i (core->config, "asm.bytes", z); r_config_set_i (core->config, "scr.interactive", u); r_config_set_i (core->config, "asm.cmtright", v); if (oldsandbox != -1) r_config_set_i (core->config, "cfg.sandbox", oldsandbox); return 0; }