diff --git a/libr/core/cmd.c b/libr/core/cmd.c index 973ea55dfa..1e7793da35 100644 --- a/libr/core/cmd.c +++ b/libr/core/cmd.c @@ -236,6 +236,8 @@ static const RCoreHelpMessage help_msg_equal = { "!=!", "", "enable remote cmd mode", "\nservers:", "", "", // ".:", "9000", "start the tcp server (echo x|nc ::1 9090 or curl ::1:9090/cmd/x)", + "=l", "", "listen daemon", + "=L", "", "List daemon sessions", "=t", "port", "start the tcp server (echo x|nc ::1 9090 or curl ::1:9090/cmd/x)", "=r", "port", "start the rap server (o rap://9999)", "=g", "[?]", "start the gdbserver", @@ -1059,6 +1061,64 @@ static void cmd_tcp_server(RCore *core, const char *input) { } } +#define MINPORT 2000 +#define MAXPORT 3000 + +static void session_listen(RCore *core) { + if (core->http_up) { + R_LOG_ERROR ("Daemon already running"); + return; + } + int port = MINPORT + r_num_rand (MAXPORT - MINPORT); + r_strf_var (sport, 80, "%d", port); + r_config_set (core->config, "http.port", sport); + r_config_set_b (core->config, "http.sandbox", false); + int pid = r_sys_getpid (); + char *tmpdir = r_file_tmpdir (); + char *tmpdir_r2 = r_str_newf ("%s/r2", tmpdir); + r_sys_mkdir (tmpdir_r2); + char *fn = r_str_newf ("%s/%d.pid", tmpdir_r2, pid); + char *s = r_str_newf ("r2web://127.0.0.1:%d/cmd", port); + if (r_file_dump (fn, (const ut8*)s, strlen (s), false)) { + r_core_cmd0 (core, "=h&"); + } else { + R_LOG_ERROR ("Cannot create socket file %s", s); + } + free (s); + free (tmpdir_r2); + free (tmpdir); + // set random port +} + +static void session_list(RCore *core) { + char *tmpdir = r_file_tmpdir (); + char *tmpdir_r2 = r_str_newf ("%s/r2", tmpdir); + char *file; + RListIter *iter; + RList *files = r_sys_dir (tmpdir_r2); + r_list_foreach (files, iter, file) { + if (r_str_endswith (file, ".pid")) { + char *ffn = r_str_newf ("%s/%s", tmpdir_r2, file); + // TODO: curl to get filename or session name via "/cmd/k%20name" + char *data = r_file_slurp (ffn, NULL); + int fpid = atoi (file); + if (data) { +#if R2__UNIX__ && !__wasi__ + if (0 == kill (fpid, 0)) { + r_cons_printf ("r2 %s # pid %d\n", data, fpid); + } else { + r_file_rm (ffn); + } +#else + r_cons_printf ("r2 %s # pid %d\n", data, fpid); +#endif + } + free (ffn); + } + } + r_list_free (files); +} + static int cmd_rap(void *data, const char *input) { RCore *core = (RCore *)data; switch (*input) { @@ -1074,6 +1134,16 @@ static int cmd_rap(void *data, const char *input) { case 'R': // "=R" cmd_remote (core, r_str_trim_head_ro (input + 1), true); break; + case 'l': // "=l" + if (input[1] == ' ') { + // set session name here + r_core_cmdf (core, "k name=%s", r_str_trim_head_ro (input + 2)); + } + session_listen (core); + break; + case 'L': // "=L" + session_list (core); + break; case 'j': // "=j" R_LOG_ERROR ("TODO: list connections in json"); break; diff --git a/libr/core/rtr.c b/libr/core/rtr.c index 3604f18300..3076c88e90 100644 --- a/libr/core/rtr.c +++ b/libr/core/rtr.c @@ -48,6 +48,11 @@ typedef struct { R_API void r_core_wait(RCore *core) { r_cons_context ()->breaked = true; +#if R2__UNIX__ + if (core->http_up) { + r_core_rtr_http_stop (core); + } +#endif r_th_kill (httpthread, true); r_th_kill (rapthread, true); r_th_wait (httpthread); @@ -176,18 +181,19 @@ beach: R_API int r_core_rtr_http_stop(RCore *u) { RCore *core = (RCore*)u; const int timeout = 1; // 1 second - const char *port; - RSocket* sock; #if R2__WINDOWS__ r_socket_http_server_set_breaked (&r_cons_context ()->breaked); #endif + core->http_up = false; if (((size_t)u) > 0xff) { - port = listenport? listenport: r_config_get ( - core->config, "http.port"); - sock = r_socket_new (0); - (void)r_socket_connect (sock, "localhost", - port, R_SOCKET_PROTO_TCP, timeout); + const char *port = listenport? listenport: r_config_get (core->config, "http.port"); + char *sport = r_str_startswith (port, "0x") + ? r_str_newf ("%d", (int)r_num_get (NULL, port)) + : strdup (port); + RSocket* sock = r_socket_new (0); + (void)r_socket_connect (sock, "127.0.0.1", sport, R_SOCKET_PROTO_TCP, timeout); + free (sport); r_socket_free (sock); } r_socket_free (s); diff --git a/libr/core/rtr_http.inc.c b/libr/core/rtr_http.inc.c index cb43f9a308..8436822506 100644 --- a/libr/core/rtr_http.inc.c +++ b/libr/core/rtr_http.inc.c @@ -95,7 +95,7 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char * } s = r_socket_new (false); { - if (host && *host) { + if (R_STR_ISNOTEMPTY (host)) { if (!strcmp (host, "::1")) { s->local = true; } else if (!strcmp (host, "localhost")) { @@ -138,9 +138,7 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char * R_LOG_ERROR ("No user list set for HTTP Authentication"); return 1; } - pfile = r_file_slurp (httpauthfile, NULL); - if (pfile) { so.authtokens = r_str_split_list (pfile, "\n", 0); } else { @@ -148,7 +146,6 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char * R_LOG_ERROR ("Empty list of HTTP users"); return 1; } - so.timeout = r_config_get_i (core->config, "http.timeout"); so.accept_timeout = 1; } @@ -172,8 +169,9 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char * restoreSandbox = true; } eprintf ("Starting http server...\n"); - eprintf ("open http://%s:%d/\n", host, atoi (port)); - eprintf ("r2 -C http://%s:%d/cmd/\n", host, atoi (port)); + eprintf ("open http://%s:%s/\n", host, port); + eprintf ("r2 -C http://%s:%s/cmd/\n", host, port); + eprintf ("r2 r2web://%s:%s/cmd/\n", host, port); core->http_up = true; ut64 newoff, origoff = core->offset; @@ -192,7 +190,7 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char * core->block = newblk; // TODO: handle mutex lock/unlock here r_cons_break_push ((RConsBreak)r_core_rtr_http_stop, core); - while (!r_cons_is_breaked ()) { + while (!r_cons_is_breaked () && core->http_up) { /* restore environment */ core->config = origcfg; #if WEBCONFIG @@ -200,7 +198,6 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char * r_config_set_i (origcfg, "scr.color", r_config_get_i (origcfg, "scr.color")); r_config_set_b (origcfg, "scr.interactive", r_config_get_b (origcfg, "scr.interactive")); #endif - core->http_up = 0; // DAT IS NOT TRUE AT ALL.. but its the way to enable visual newoff = core->offset; newblk = core->block; @@ -216,6 +213,10 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char * void *bed = r_cons_sleep_begin (); rs = r_socket_http_accept (s, &so); + if (!core->http_up) { + eprintf ("^C\n"); + break; + } r_cons_sleep_end (bed); if (!rs) { bed = r_cons_sleep_begin (); @@ -591,6 +592,7 @@ static RThreadFunctionRet r_core_rtr_http_thread(RThread *th) { R_LOG_WARN ("Background webserver requires http.sandbox=false to run properly"); int ret = r_core_rtr_http_run (ht->core, ht->launch, ht->browse, ht->path); R_FREE (ht->path); +#if 0 if (ret) { int p = r_config_get_i (ht->core->config, "http.port"); r_config_set_i (ht->core->config, "http.port", p + 1); @@ -598,6 +600,7 @@ static RThreadFunctionRet r_core_rtr_http_thread(RThread *th) { return R_TH_STOP; } } +#endif return ret ? R_TH_REPEAT : R_TH_STOP; } #endif diff --git a/libr/socket/socket.c b/libr/socket/socket.c index c30c25a815..dfc8195110 100644 --- a/libr/socket/socket.c +++ b/libr/socket/socket.c @@ -421,7 +421,7 @@ R_API bool r_socket_connect(RSocket *s, const char *host, const char *port, int } freeaddrinfo (res); if (!rp) { - R_LOG_ERROR ("Could not resolve address '%s' or failed to connect", host); + // R_LOG_ERROR ("Could not resolve address '%s' or failed to connect", host); return false; } } diff --git a/libr/util/sys.c b/libr/util/sys.c index 71fdd6ead8..3c34baf7dd 100644 --- a/libr/util/sys.c +++ b/libr/util/sys.c @@ -724,7 +724,7 @@ R_API int r_sys_cmd_str_full(const char *cmd, const char *input, int ilen, char } close (sh_err[1]); close (sh_in[0]); - if (!inputptr || !*inputptr) { + if (R_STR_ISEMPTY (inputptr)) { close (sh_in[1]); } // we should handle broken pipes somehow better