Initial implementation of the #!cpipe rlang

This commit is contained in:
pancake 2015-08-19 23:11:53 +02:00
parent f4528faa93
commit 5feb28e0c0
5 changed files with 133 additions and 25 deletions

View file

@ -88,6 +88,10 @@ a = (b << 3) * 5;
- This way we reduce the number of local variables per function
and it's easier to find which variables are used, where and so on.
* Always put a space before every parenthesis (function calls, conditionals,
fors, etc, ...) except when defining the function signature. This is
useful for grepping.
* Comments should be smart. Function names should be explicit enough
to not require a comment to explain what it does. If this is not
possible at all, we can still use a comment. But it is a bad idea

View file

@ -5,9 +5,12 @@
R_LIB_VERSION(r_lang);
#include "p/pipe.c" // hardcoded
#include "p/vala.c" // hardcoded
#include "p/c.c" // hardcoded
#include "p/pipe.c" // hardcoded
#include "p/vala.c" // hardcoded
#include "p/c.c" // hardcoded
#if __UNIX__
#include "p/cpipe.c" // hardcoded
#endif
static RLang *__lang = NULL;
@ -27,6 +30,9 @@ R_API RLang *r_lang_new() {
lang->defs->free = (RListFree)r_lang_def_free;
lang->cb_printf = (PrintfCallback)printf;
r_lang_add (lang, &r_lang_plugin_c);
#if __UNIX__
r_lang_add (lang, &r_lang_plugin_cpipe);
#endif
r_lang_add (lang, &r_lang_plugin_vala);
r_lang_add (lang, &r_lang_plugin_pipe);
}

82
libr/lang/p/cpipe.c Normal file
View file

@ -0,0 +1,82 @@
/* radare - LGPL - Copyright 2011-2015 pancake */
/* vala extension for libr (radare2) */
// TODO: add cache directory (~/.r2/cache)
#include "r_lib.h"
#include "r_core.h"
#include "r_lang.h"
static int lang_cpipe_file(RLang *lang, const char *file) {
char *a, *cc, *p, name[512], buf[512];
const char *libpath, *libname, *binfile;
if (strlen (file) > (sizeof (name)-10))
return R_FALSE;
if (!strstr (file, ".c"))
sprintf (name, "%s.c", file);
else strcpy (name, file);
if (!r_file_exists (name)) {
eprintf ("file not found (%s)\n", name);
return R_FALSE;
}
a = (char*)r_str_lchr (name, '/');
if (a) {
*a = 0;
libpath = name;
libname = a+1;
} else {
libpath = ".";
libname = name;
}
r_sys_setenv ("PKG_CONFIG_PATH", R2_LIBDIR"/pkgconfig");
p = strstr (name, ".c");
if (p) *p = 0;
cc = r_sys_getenv ("CC");
if (!cc || !*cc)
cc = strdup ("gcc");
snprintf (buf, sizeof (buf), "%s %s -o %s/bin%s"
" $(pkg-config --cflags --libs r_socket)",
cc, file, libpath, libname);
free (cc);
if (r_sandbox_system (buf, 1) != 0) {
return R_FALSE;
}
binfile = r_str_newf ("%s/bin%s", libpath, libname);
lang_pipe_run (lang, binfile, -1);
r_file_rm (binfile);
return 0;
}
static int lang_cpipe_init(void *user) {
// TODO: check if "valac" is found in path
return R_TRUE;
}
static int lang_cpipe_run(RLang *lang, const char *code, int len) {
FILE *fd = fopen (".tmp.c", "w");
if (fd) {
fputs ("#include <r_socket.h>\n\n"
"#define R2P(x,y...) r2p_cmdf(r2p,x,##y)\n"
"int main() {\n"
"R2Pipe *r2p = r2p_open(NULL);", fd);
fputs (code, fd);
fputs ("\n}\n", fd);
fclose (fd);
lang_cpipe_file (lang, ".tmp.c");
r_file_rm (".tmp.c");
} else eprintf ("Cannot open .tmp.c\n");
return R_TRUE;
}
static struct r_lang_plugin_t r_lang_plugin_cpipe = {
.name = "cpipe",
.ext = "c2",
.desc = "C r2pipe scripting",
.help = NULL,
.run = lang_cpipe_run,
.init = (void*)lang_cpipe_init,
.fini = NULL,
.run_file = (void*)lang_cpipe_file,
.set_argv = NULL,
};

View file

@ -1,4 +1,3 @@
/* radare2 - LGPL - Copyright 2015 pancake */
#include "r_lib.h"
@ -28,7 +27,7 @@ static HANDLE myCreateChildProcess(const char * szCmdline) {
DWORD dwWritten;
ZeroMemory (&piProcInfo, sizeof (PROCESS_INFORMATION));
ZeroMemory (&siStartInfo, sizeof (STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.cb = sizeof (STARTUPINFO);
bSuccess = CreateProcess (NULL, szCmdline, NULL, NULL,
TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo);
if (!bSuccess)
@ -46,6 +45,7 @@ static int lang_pipe_run(RLang *lang, const char *code, int len) {
int child, ret;
int input[2];
int output[2];
pipe (input);
pipe (output);
@ -57,20 +57,7 @@ static int lang_pipe_run(RLang *lang, const char *code, int len) {
/* 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]);
@ -83,8 +70,8 @@ static int lang_pipe_run(RLang *lang, const char *code, int len) {
char *res, buf[1024];
/* Close pipe ends not required in the parent */
close(output[1]);
close(input[0]);
close (output[1]);
close (input[0]);
r_cons_break (NULL, NULL);
for (;;) {
@ -147,8 +134,7 @@ static int lang_pipe_run(RLang *lang, const char *code, int len) {
return R_TRUE;
}
r_cons_break (NULL, NULL);
for (;;)
{
for (;;) {
res = ConnectNamedPipe(hPipeInOut, NULL);
if (GetLastError()==ERROR_PIPE_CONNECTED) {
//eprintf("new client\n");

View file

@ -88,6 +88,33 @@ static int w32_createPipe(R2Pipe *r2p, const char *cmd) {
R_API R2Pipe *r2p_open(const char *cmd) {
R2Pipe *r2p = R_NEW0 (R2Pipe);
r2p->magic = R2P_MAGIC;
if (cmd == NULL) {
r2p->child = -1;
#if __UNIX__
{
char *out = r_sys_getenv ("R2PIPE_IN");
char *in = r_sys_getenv ("R2PIPE_OUT");
int done = R_FALSE;
if (in && out) {
int i_in = atoi (in);
int i_out = atoi (out);
if (i_in>=0 && i_out>=0) {
r2p->input[0] = r2p->input[1] = i_in;
r2p->output[0] = r2p->output[1] = i_out;
done = R_TRUE;
}
}
if (!done) {
eprintf ("Cannot find R2PIPE_IN or R2PIPE_OUT environment\n");
R_FREE (r2p);
}
}
return r2p;
#else
eprintf ("r2p_open(NULL) not supported on windows\n");
return NULL;
#endif
}
#if __WINDOWS__
w32_createPipe (r2p, cmd);
r2p->child = (int)(r2p->pipe);
@ -106,8 +133,9 @@ R_API R2Pipe *r2p_open(const char *cmd) {
eprintf ("Child is %d\n", r2p->child);
} else {
int rc;
rc = r_sandbox_system (cmd, 1);
eprintf ("Child was %d with %d\n", r2p->child, rc);
if (cmd && *cmd) {
rc = r_sandbox_system (cmd, 1);
} else rc = 0;
r2p_close (r2p);
exit (0);
return NULL;
@ -117,8 +145,10 @@ R_API R2Pipe *r2p_open(const char *cmd) {
}
R_API char *r2p_cmd(R2Pipe *r2p, const char *str) {
if (!r2p_write (r2p, str))
if (!r2p_write (r2p, str)) {
perror ("r2p_write");
return NULL;
}
return r2p_read (r2p);
}