コード例 #1
0
ファイル: io.c プロジェクト: adamharder/radare2
R_API int r_core_dump(RCore *core, const char *file, ut64 addr, ut64 size) {
	ut64 i;
	ut8 *buf;
	int bs = core->blocksize;
	FILE *fd;
	r_sys_truncate (file, 0);
	fd = r_sandbox_fopen (file, "wb");
	if (!fd) {
		eprintf ("Cannot open '%s' for writing\n", file);
		return R_FALSE;
	}
	buf = malloc (bs);
	r_cons_break (NULL, NULL);
	for (i=0; i<size; i+=bs) {
		if (r_cons_singleton ()->breaked)
			break;
		if ((i+bs)>size)
			bs = size-i;
		r_io_read_at (core->io, addr+i, buf, bs);
		if (fwrite (buf, bs, 1, fd) <1) {
			eprintf ("write error\n");
			break;
		}
	}
	eprintf ("dumped 0x%"PFMT64x" bytes\n", i);
	r_cons_break_end ();
	fclose (fd);
	free (buf);
	return R_TRUE;
}
コード例 #2
0
ファイル: visual.c プロジェクト: xuwenbo/radare2
static void visual_repeat(RCore *core) {
	int atport = r_config_get_i (core->config, "scr.atport");
	if (atport) {
#if __UNIX__ && !__APPLE__
		int port = r_config_get_i (core->config, "http.port");
		if (!r_core_rtr_http (core, '&', NULL)) {
			const char *xterm = r_config_get (core->config, "cmd.xterm");
			// TODO: this must be configurable
			r_sys_cmdf ("%s 'r2 -C http://localhost:%d/cmd/V;sleep 1' &", xterm, port);
			//xterm -bg black -fg gray -e 'r2 -C http://localhost:%d/cmd/;sleep 1' &", port);
		} else {
			r_cons_any_key (NULL);
		}
#else
		eprintf ("Unsupported on this platform\n");
		r_cons_any_key (NULL);
#endif
	} else {
		RThread *th = r_th_new (visual_repeat_thread, core, 0);
		r_th_start (th, 1);
		r_cons_break (NULL, NULL);
		r_cons_any_key (NULL);
		eprintf ("^C  \n");
		core->cons->breaked = true;
		r_th_wait (th);
		r_cons_break_end ();
	}
}
コード例 #3
0
ファイル: anal_tp.c プロジェクト: Lukas-Dresel/radare2
R_API void r_anal_type_match(RCore *core, RAnalFunction *fcn) {
	bool esil_var[STATES_SIZE] = {false};
	if (!core ) {
		return;
	}
	if (!r_anal_emul_init (core, esil_var) || !fcn ) {
		r_anal_emul_restore (core, esil_var);
		return;
	}
	const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
	ut64 addr = fcn->addr;
	r_reg_setv (core->dbg->reg, pc, fcn->addr);
	r_debug_reg_sync (core->dbg, -1, true);
	r_cons_break (NULL, NULL);
	while (!r_cons_is_breaked ()) {
		RAnalOp *op = r_core_anal_op (core, addr);
		int loop_count = sdb_num_get ( core->anal->esil->db_trace, sdb_fmt (-1, "0x%"PFMT64x".count", addr), 0);
		if (loop_count > LOOP_MAX) {
			eprintf ("Unfortunately your evilly engineered %s function trapped my most innocent `aftm` in an infinite loop.\n", fcn->name);
			eprintf ("I kept trace log for you to review and find out how bad things were going to happen by yourself.\n");
			eprintf ("You can view this log by `ate`. Meanwhile, I will train on how to behave with such behaviour without bothering you.\n");
			return;
		}
		sdb_num_set (core->anal->esil->db_trace, sdb_fmt (-1, "0x%"PFMT64x".count", addr), loop_count + 1, 0);
		if (!op || op->type == R_ANAL_OP_TYPE_RET) {
			r_anal_emul_restore (core, esil_var);
			return;
		}
		if (op->type == R_ANAL_OP_TYPE_CALL) {
			RAnalFunction *fcn_call = r_anal_get_fcn_in (core->anal, op->jump, -1);
			//eprintf ("in the middle of %s\n", fcn_call->name);
			if (fcn_call) {
				type_match (core, addr, fcn_call->name);
			} else {
				eprintf ("Cannot find function at 0x%08"PFMT64x"\n", op->jump);
			}
			addr += op->size;
			r_anal_op_free (op);
			r_reg_setv (core->dbg->reg, pc, addr);
			r_debug_reg_sync (core->dbg, -1, true);
			r_anal_esil_set_pc (core->anal->esil, addr);
			addr += stack_clean (core, addr, fcn);
			r_reg_setv (core->dbg->reg, pc, addr);
			r_debug_reg_sync (core->dbg, -1, true);
			r_anal_esil_set_pc (core->anal->esil, addr);
			continue;
		} else {
			r_core_esil_step (core, UT64_MAX, NULL);
			r_anal_op_free (op);
		}
		r_core_cmd0 (core, ".ar*");
		addr = r_reg_getv (core->anal->reg, pc);
	}
	r_cons_break_end ();
	r_anal_emul_restore (core, esil_var);

}
コード例 #4
0
ファイル: pipe.c プロジェクト: 13572293130/radare2
DWORD WINAPI ThreadFunction(LPVOID lpParam) {
	RLang * lang = lpParam;
	CHAR buf[PIPE_BUF_SIZE];
	BOOL bSuccess = FALSE;
	int i, res = 0;
	DWORD dwRead, dwWritten;
	r_cons_break (NULL, NULL);
	res = ConnectNamedPipe (hPipeInOut, NULL);
	if (!res) {
		eprintf ("ConnectNamedPipe failed\n");
		return FALSE;
	}
	do {
		if (r_cons_singleton ()->breaked) {
			TerminateProcess(hproc,0);
			break;
		}
		memset (buf, 0, PIPE_BUF_SIZE);
		bSuccess = ReadFile (hPipeInOut, buf, PIPE_BUF_SIZE, &dwRead, NULL);
                if (bStopThread)
			break;
		if (bSuccess && dwRead>0) {
			buf[sizeof (buf)-1] = 0;
			char *res = lang->cmd_str ((RCore*)lang->user, buf);
			if (res) {
				int res_len = strlen (res) + 1;
				for (i = 0; i < res_len; i++) {
					memset (buf, 0, PIPE_BUF_SIZE);
					dwWritten = 0;
					int writelen=res_len - i;
					int rc = WriteFile (hPipeInOut, res + i, writelen>PIPE_BUF_SIZE?PIPE_BUF_SIZE:writelen, &dwWritten, 0);
					if (bStopThread) {
						free (res);
						break;
					}
					if (!rc) {
						eprintf ("WriteFile: failed 0x%x\n", (int)GetLastError());
					}
					if (dwWritten > 0) {
						i += dwWritten - 1;
					} else {
						/* send null termination // chop */
						eprintf ("w32-lang-pipe: 0x%x\n", (ut32)GetLastError ());
						//WriteFile (hPipeInOut, "", 1, &dwWritten, NULL);
						//break;
					}
				}
				free (res);
			} else {
				WriteFile (hPipeInOut, "", 1, &dwWritten, NULL);
			}
		}
	} while(!bStopThread);
	r_cons_break_end ();
	return TRUE;
}
コード例 #5
0
ファイル: bin.c プロジェクト: hidd3ncod3s/radare2
static int bin_dwarf(RCore *core, int mode) {
	RBinDwarfRow *row;
	RListIter *iter;
	RList *list = NULL;
	RBinFile *binfile = r_core_bin_cur (core);
	RBinPlugin * plugin = r_bin_file_cur_plugin (binfile);
	if (!binfile) return false;

	if (plugin && plugin->lines) {
		list = plugin->lines (binfile);
	} else if (core->bin) {
		// TODO: complete and speed-up support for dwarf
		if (r_config_get_i (core->config, "bin.dwarf")) {
			RBinDwarfDebugAbbrev *da = NULL;
			da = r_bin_dwarf_parse_abbrev (core->bin, mode);
			r_bin_dwarf_parse_info (da, core->bin, mode);
			r_bin_dwarf_parse_aranges (core->bin, mode);
			list = r_bin_dwarf_parse_line (core->bin, mode);
			r_bin_dwarf_free_debug_abbrev (da);
			free (da);
		}
	}
	if (!list) return false;
	r_cons_break (NULL, NULL);
        r_list_foreach (list, iter, row) {
		if (r_cons_singleton()->breaked) break;
		if (mode) {
			// TODO: use 'Cl' instead of CC
			const char *path = row->file;
			char *line = r_file_slurp_line (path, row->line-1, 0);
			if (line) {
				r_str_filter (line, strlen (line));
				line = r_str_replace (line, "\"", "\\\"", 1);
				line = r_str_replace (line, "\\\\", "\\", 1);
			}
			// TODO: implement internal : if ((mode & R_CORE_BIN_SET))
			if ((mode & R_CORE_BIN_SET)) {
				char *cmt = r_str_newf ("%s:%d  %s", row->file, row->line, line?line:"");
				r_meta_set_string (core->anal, R_META_TYPE_COMMENT,
						row->address, cmt);
				free (cmt);
			} else {
				r_cons_printf ("\"CC %s:%d  %s\"@0x%"PFMT64x"\n",
					row->file, row->line, line?line:"", row->address);
			}
			free (line);
		} else {
			r_cons_printf ("0x%08"PFMT64x"\t%s\t%d\n", row->address, row->file, row->line);
		}
        }
	r_cons_break_end ();
	r_list_free (list);
	return true;
}
コード例 #6
0
ファイル: rtr.c プロジェクト: dialeth/radare2
R_API int r_core_rtr_cmds (RCore *core, const char *port) {
	unsigned char buf[4097];
	RSocket *ch, *s;
	int i, ret;
	char *str;

	if (!port || port[0]=='?') {
		r_cons_printf ("Usage: .:[tcp-port]    run r2 commands for clients\n");
		return R_FALSE;
	}

	s = r_socket_new (0);
	if (!r_socket_listen (s, port, NULL)) {
		eprintf ("Error listening on port %s\n", port);
		r_socket_free (s);
		return R_FALSE;
	}

	eprintf ("Listening for commands on port %s\n", port);
	listenport = port;
	for (;;) {
		r_cons_break ((RConsBreak)http_break, core);
		ch = r_socket_accept (s);
		buf[0] = 0;
		ret = r_socket_read (ch, buf, sizeof (buf) - 1);
		if (ret>0) {
			buf[ret] = 0;
			for (i=0; buf[i]; i++)
				if (buf[i] == '\n')
					buf[i] = buf[i+1]? ';': '\0';
			if (!r_config_get_i (core->config, "scr.prompt") \
					&& !strcmp ((char*)buf, "q!"))
				break;
			str = r_core_cmd_str (core, (const char *)buf);
			if (str &&*str)  {
			r_socket_write (ch, str, strlen (str));
			} else
			r_socket_write (ch, "\n", 1);
			free (str);
		}
		if (r_cons_singleton()->breaked)
			break;
		r_socket_close (ch);
		r_cons_break_end ();
	}
	r_socket_free(s);
	r_socket_free(ch);
	return 0;
}
コード例 #7
0
ファイル: esil.c プロジェクト: AitorATuin/radare2
R_API ut64 r_debug_esil_step(RDebug *dbg, ut32 count) {
	count++;
	has_match = 0;
	r_cons_break (NULL, NULL);
	do {
		if (r_cons_is_breaked ())
			break;
		if (has_match) {
			eprintf ("EsilBreak match at 0x%08"PFMT64x"\n", opc);
			break;
		}
		if (count>0) {
			count--;
			if (!count) {
				//eprintf ("Limit reached\n");
				break;
			}
		}
	} while (r_debug_esil_stepi (dbg));
	r_cons_break_end ();
	return opc;
}
コード例 #8
0
ファイル: pipe.c プロジェクト: 13572293130/radare2
static int lang_pipe_run(RLang *lang, const char *code, int len) {
#if __UNIX__
	int safe_in = dup (0);
	int child, ret;
	int input[2];
	int output[2];

	pipe (input);
	pipe (output);

	env ("R2PIPE_IN", input[0]);
	env ("R2PIPE_OUT", output[1]);

	child = r_sys_fork ();
	if (child == -1) {
		/* error */
	} else if (child == 0) {
		/* children */
		r_sandbox_system (code, 1);
		write (input[1], "", 1);
		close (input[0]);
		close (input[1]);
		close (output[0]);
		close (output[1]);
		exit (0);
		return false;
	} else {
		/* parent */
		char *res, buf[1024];

		/* Close pipe ends not required in the parent */
		close (output[1]);
		close (input[0]);

		r_cons_break (NULL, NULL);
		for (;;) {
			if (r_cons_singleton ()->breaked) {
				break;
			}
			memset (buf, 0, sizeof (buf));
			ret = read (output[0], buf, sizeof (buf)-1);
			if (ret <1 || !buf[0]) {
				break;
			}
			buf[sizeof (buf)-1] = 0;
			res = lang->cmd_str ((RCore*)lang->user, buf);
			//eprintf ("%d %s\n", ret, buf);
			if (res) {
				write (input[1], res, strlen (res)+1);
				free (res);
			} else {
				eprintf ("r_lang_pipe: NULL reply for (%s)\n", buf);
				write (input[1], "", 1); // NULL byte
			}
		}
		/* workaround to avoid stdin closed */
		if (safe_in != -1)
			close (safe_in);
		safe_in = open (ttyname(0), O_RDONLY);
		if (safe_in != -1) {
			dup2 (safe_in, 0);
		} else eprintf ("Cannot open ttyname(0) %s\n", ttyname(0));
		r_cons_break_end ();
	}

	close (input[0]);
	close (input[1]);
	close (output[0]);
	close (output[1]);
	if (safe_in != -1)
		close (safe_in);
	waitpid (child, NULL, 0);
	return true;
#else
#if __WINDOWS__
	HANDLE hThread = 0;
	char buf[512];
	sprintf(buf,"R2PIPE_IN%x",_getpid());
	SetEnvironmentVariable("R2PIPE_PATH",buf);
	sprintf(buf,"\\\\.\\pipe\\R2PIPE_IN%x",_getpid());
	hPipeInOut = CreateNamedPipe(buf,
			PIPE_ACCESS_DUPLEX,
			PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
			PIPE_BUF_SIZE,
			PIPE_BUF_SIZE,
			0,
			NULL);
	hproc = myCreateChildProcess (code);
	if (!hproc) {
		return false;
	}
	bStopThread=FALSE;
	hThread = CreateThread (NULL, 0,ThreadFunction,lang, 0,0);
	WaitForSingleObject (hproc, INFINITE );
	bStopThread = TRUE;
	DeleteFile (buf);
	WaitForSingleObject (hThread, INFINITE);
	CloseHandle (hPipeInOut);
	return true;
#endif
#endif
}
コード例 #9
0
ファイル: pipe.c プロジェクト: 0x2F/radare2
static int lang_pipe_run(RLang *lang, const char *code, int len) {
#if __UNIX__
	int safe_in = dup (0);
	int child, ret;
	int input[2];
	int output[2];
	pipe (input);
	pipe (output);

	env ("R2PIPE_IN", input[0]);
	env ("R2PIPE_OUT", output[1]);

	child = r_sys_fork ();
	if (child == -1) {
		/* error */
	} else if (child == 0) {
		/* children */
#if 1
		r_sandbox_system (code, 1);
#else
		/* DEMO */
		char buf[1024];
		/* kid stuff here */
		while (1) {
			write (output[1], "pd 3\n", 6);
			res = read (input[0], buf, sizeof (buf)-1);
			if (res <1) break;
			printf ("---> ((%s))\n", buf);
			sleep (1);
		}
#endif
		write (input[1], "", 1);
		close (input[0]);
		close (input[1]);
		close (output[0]);
		close (output[1]);
		exit (0);
		return R_FALSE;
	} else {
		/* parent */
		char *res, buf[1024];

		/* Close pipe ends not required in the parent */
		close(output[1]);
		close(input[0]);

		r_cons_break (NULL, NULL);
		for (;;) {
			if (r_cons_singleton ()->breaked) {
				break;
			}
			memset (buf, 0, sizeof (buf));
			ret = read (output[0], buf, sizeof (buf)-1);
			if (ret <1 || !buf[0]) {
				break;
			}
			buf[sizeof (buf)-1] = 0;
			res = lang->cmd_str ((RCore*)lang->user, buf);
			//eprintf ("%d %s\n", ret, buf);
			if (res) {
				write (input[1], res, strlen (res)+1);
				free (res);
			} else {
				eprintf ("r_lang_pipe: NULL reply for (%s)\n", buf);
				write (input[1], "", 1); // NULL byte
			}
		}
		/* workaround to avoid stdin closed */
		if (safe_in != -1)
			close (safe_in);
		safe_in = open (ttyname(0), O_RDONLY);
		if (safe_in != -1) {
			dup2 (safe_in, 0);
		} else eprintf ("Cannot open ttyname(0) %s\n", ttyname(0));
		r_cons_break_end ();
	}

	close (input[0]);
	close (input[1]);
	close (output[0]);
	close (output[1]);
	if (safe_in != -1)
		close (safe_in);
	waitpid (child, NULL, 0);
	return R_TRUE;
#else
#if __WINDOWS__
	HANDLE hPipeInOut = NULL;
	HANDLE hproc=NULL;
	DWORD dwRead, dwWritten;
	CHAR buf[1024];
	BOOL bSuccess = FALSE;
	int res=0;
	sprintf(buf,"R2PIPE_IN%x",_getpid());
	SetEnvironmentVariable("R2PIPE_PATH",buf);
	sprintf(buf,"\\\\.\\pipe\\R2PIPE_IN%x",_getpid());
	hPipeInOut = CreateNamedPipe(buf,
		PIPE_ACCESS_DUPLEX,PIPE_TYPE_MESSAGE | \
		PIPE_READMODE_MESSAGE | \
		PIPE_NOWAIT,PIPE_UNLIMITED_INSTANCES,
		sizeof (buf), sizeof (buf), 0, NULL);
	hproc=myCreateChildProcess (code);
	if (hproc==NULL) {
		//eprintf("Error spawning process: %s\n",code);
		return R_TRUE;
	}
	r_cons_break (NULL, NULL);
	for (;;)
	{
		res = ConnectNamedPipe(hPipeInOut, NULL);
		if (GetLastError()==ERROR_PIPE_CONNECTED) {
			//eprintf("new client\n");
			break;
		}
		if (r_cons_singleton ()->breaked) {
			TerminateProcess(hproc,0);
			break;
		}

	}
	for (;;) {
		if (r_cons_singleton ()->breaked) {
			TerminateProcess(hproc,0);
			break;
		}
		memset (buf, 0, sizeof (buf));
		bSuccess = ReadFile( hPipeInOut, buf, sizeof (buf), &dwRead, NULL);
	  	if (dwRead!=0) {
			buf[sizeof(buf)-1] = 0;
			res = lang->cmd_str ((RCore*)lang->user, buf);
			if (res) {
				WriteFile(hPipeInOut, res, strlen (res)+1, &dwWritten, NULL);
				free (res);
			} else {
				WriteFile(hPipeInOut, "", 1, &dwWritten, NULL);
			}
	  	}
	}
	CloseHandle(hPipeInOut);
	r_cons_break_end ();
	return R_TRUE;
#endif
#endif
}
コード例 #10
0
ファイル: bin.c プロジェクト: hidd3ncod3s/radare2
static int bin_strings(RCore *r, int mode, int va) {
	char *q, str[R_FLAG_NAME_SIZE];
	RBinSection *section;
	int hasstr, minstr, maxstr, rawstr;
	RBinString *string;
	RListIter *iter;
	RList *list;
	RBin *bin = r->bin;
	RBinFile * binfile = r_core_bin_cur (r);
	RBinPlugin *plugin = r_bin_file_cur_plugin (binfile);

	if (!binfile) return false;
	minstr = r_config_get_i (r->config, "bin.minstr");
	maxstr = r_config_get_i (r->config, "bin.maxstr");
	rawstr = r_config_get_i (r->config, "bin.rawstr");
	binfile->rawstr = rawstr;

	if (!(hasstr = r_config_get_i (r->config, "bin.strings"))) {
		return 0;
	}

	if (!plugin) return 0;
	if (plugin->info && plugin->name) {
		if (strcmp (plugin->name, "any") == 0 && !rawstr) {
			return false;
		}
	}

	bin->minstrlen = minstr;
	minstr = bin->minstrlen;

	if ((list = r_bin_get_strings (bin)) == NULL) return false;

	if (IS_MODE_JSON (mode)) r_cons_printf ("[");
	if (IS_MODE_RAD (mode)) r_cons_printf ("fs strings");
	if (IS_MODE_SET (mode) && r_config_get_i (r->config, "bin.strings")) {
		r_flag_space_set (r->flags, "strings");
		r_cons_break (NULL, NULL);
	}
	r_list_foreach (list, iter, string) {
		const char *section_name, *type_string;
		ut64 paddr = string->paddr;
		ut64 vaddr = r_bin_get_vaddr (bin, paddr, string->vaddr);
		ut64 addr = va ? vaddr : paddr;

		if (string->length < minstr) continue;
		if (maxstr && string->length > maxstr) continue;

		section = r_bin_get_section_at (r_bin_cur_object (bin), paddr, 0);
		section_name = section ? section->name : "unknown";
		type_string = string->type == 'w' ? "wide" : "ascii";
		if (IS_MODE_SET (mode)) {
			char *f_name;

			if (r_cons_singleton()->breaked) break;
			r_meta_add (r->anal, R_META_TYPE_STRING, addr,
				addr + string->size, string->string);
			f_name = strdup (string->string);
			r_name_filter (f_name, R_FLAG_NAME_SIZE);
			snprintf (str, R_FLAG_NAME_SIZE, "str.%s", f_name);
			r_flag_set (r->flags, str, addr, string->size, 0);
			free (f_name);
		} else if (IS_MODE_SIMPLE (mode)) {
			r_cons_printf ("0x%"PFMT64x" %d %d %s\n", addr,
				string->size, string->length, string->string);
		} else if (IS_MODE_JSON (mode)) {
			q = r_base64_encode_dyn (string->string, -1);
			r_cons_printf ("%s{\"vaddr\":%"PFMT64d
				",\"paddr\":%"PFMT64d",\"ordinal\":%d"
				",\"size\":%d,\"length\":%d,\"section\":\"%s\","
				"\"type\":\"%s\",\"string\":\"%s\"}",
				iter->p ? ",": "",
				vaddr, paddr, string->ordinal, string->size,
				string->length, section_name, type_string, q);
			free (q);
		} else if (IS_MODE_RAD (mode)) {
			char *f_name;

			f_name = strdup (string->string);
			r_name_filter (f_name, R_FLAG_NAME_SIZE);
			snprintf (str, R_FLAG_NAME_SIZE, "str.%s", f_name);
			r_cons_printf ("f str.%s %"PFMT64d" @ 0x%08"PFMT64x"\n"
				"Cs %"PFMT64d" @ 0x%08"PFMT64x"\n",
				f_name, string->size, addr,
				string->size, addr);
			free (f_name);
		} else {
			r_cons_printf ("vaddr=0x%08"PFMT64x" paddr=0x%08"
				PFMT64x" ordinal=%03u sz=%u len=%u "
				"section=%s type=%s string=%s\n",
				vaddr, paddr, string->ordinal, string->size,
				string->length, section_name, type_string,
				string->string);
		}
	}
	if (IS_MODE_JSON (mode)) r_cons_printf ("]");
	if (IS_MODE_SET (mode)) r_cons_break_end ();

	return true;
}
コード例 #11
0
ファイル: rtr.c プロジェクト: dialeth/radare2
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;
}