Пример #1
0
R_API int r_sys_cmd(const char *str) {
	if (r_sandbox_enable (0)) {
		return false;
	}
#if __FreeBSD__
	/* freebsd system() is broken */
	int st, pid, fds[2];
	if (pipe (fds)) {
		return -1;
	}
	pid = vfork ();
	if (pid == -1) {
		return -1;
	}
	if (!pid) {
		dup2 (1, fds[1]);
		// char *argv[] = { "/bin/sh", "-c", str, NULL};
		// execv (argv[0], argv);
		r_sandbox_system (str, 0);
		_exit (127); /* error */
	} else {
		dup2 (1, fds[0]);
		waitpid (pid, &st, 0);
	}
	return WEXITSTATUS (st);
#else
	return r_sandbox_system (str, 1);
#endif
}
Пример #2
0
R_API R2Pipe *r2p_open(const char *cmd) {
	R2Pipe *r2p = R_NEW0 (R2Pipe);
	r2p->magic = R2P_MAGIC;
#if __WINDOWS__
	w32_createPipe (r2p, cmd);
	r2p->child = (int)(r2p->pipe);
#else
	pipe (r2p->input);
	pipe (r2p->output);
	r2p->child = fork ();
	if (r2p->child == -1) {
		r2p_close (r2p);
		return NULL;
	}
	env ("R2PIPE_IN", r2p->input[0]);
	env ("R2PIPE_OUT", r2p->output[1]);

	if (r2p->child) {
		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);
		r2p_close (r2p);
		exit (0);
		return NULL;
	}
#endif
	return r2p;
}
Пример #3
0
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);
			}
			free (in);
			free (out);
		 }
		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);
#else
	pipe (r2p->input);
	pipe (r2p->output);
	r2p->child = fork ();
	if (r2p->child == -1) {
		r2p_close (r2p);
		return NULL;
	}
	env ("R2PIPE_IN", r2p->input[0]);
	env ("R2PIPE_OUT", r2p->output[1]);

	if (r2p->child) {
		eprintf ("Child is %d\n", r2p->child);
	} else {
		int rc;
		if (cmd && *cmd) {
			rc = r_sandbox_system (cmd, 1);
		} else rc = 0;
		r2p_close (r2p);
		exit (0);
		return NULL;
	}
#endif
	return r2p;
}
Пример #4
0
R_API R2Pipe *r2p_open(const char *cmd) {
	R2Pipe *r2p = R_NEW0 (R2Pipe);
	if (!r2p) return NULL;
	r2p->magic = R2P_MAGIC;
	if (!cmd) {
		r2p->child = -1;
		return r2p_open_spawn (r2p, cmd);
	}
#if __WINDOWS__ && !defined(__CYGWIN__)
	w32_createPipe (r2p, cmd);
	r2p->child = (int)(r2p->pipe);
#else
	pipe (r2p->input);
	pipe (r2p->output);
#if LIBC_HAVE_FORK
	r2p->child = fork ();
#else
	r2p->child = -1;
#endif
	if (r2p->child == -1) {
		r2p_close (r2p);
		return NULL;
	}
	env ("R2PIPE_IN", r2p->input[0]);
	env ("R2PIPE_OUT", r2p->output[1]);

	if (r2p->child) {
		char ch;
		eprintf ("[+] r2pipe child is %d\n", r2p->child);
#if 0
		if (read (r2p->output[0], &ch, 1) != 1) {
			eprintf ("Failed to read 1 byte\n");
			r2p_close (r2p);
			return NULL;
		}
		if (ch == 0x00) {
			eprintf ("[+] r2pipe-io link stablished\n");
		}
#endif
	} else {
		int rc = 0;
		if (cmd && *cmd) {
			close (0);
			close (1);
			dup2 (r2p->input[0], 0);
			dup2 (r2p->output[1], 1);
			rc = r_sandbox_system (cmd, 0);
		}
		r2p_close (r2p);
		exit (rc);
		return NULL;
	}
#endif
	return r2p;
}
Пример #5
0
R_API int r_sys_cmdbg (const char *str) {
#if __UNIX__
	int ret, pid = fork ();
	if (pid == -1) return -1;
	if (pid) return pid;
	ret = r_sandbox_system (str, 0);
	eprintf ("{exit: %d, pid: %d, cmd: \"%s\"}", ret, pid, str);
	exit (0);
	return -1;
#else
#warning r_sys_cmdbg is not implemented for this platform
	return -1;
#endif
}
Пример #6
0
static int lang_c_file(RLang *lang, const char *file) {
    void *lib;
    char *cc, *p, name[512], buf[512];
    const char *libpath, *libname;

    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;
    }

    {
        char *a = (char*)r_str_lchr (name, '/');
        if (a) {
            *a = 0;
            libpath = name;
            libname = a+1;
        } else {
            libpath = ".";
            libname = name;
        }
    }
    p = strstr (name, ".c");
    if (p) *p=0;
    cc = r_sys_getenv ("CC");
    if (!cc || !*cc)
        cc = strdup ("gcc");
    snprintf (buf, sizeof (buf), "%s -fPIC -shared %s -o %s/lib%s."R_LIB_EXT
              " $(pkg-config --cflags --libs r_core)", cc, file, libpath, libname);
    free (cc);
    if (r_sandbox_system (buf, 1) != 0)
        return R_FALSE;

    snprintf (buf, sizeof (buf), "%s/lib%s."R_LIB_EXT, libpath, libname);
    lib = r_lib_dl_open (buf);
    if (lib!= NULL) {
        void (*fcn)(RCore *);
        fcn = r_lib_dl_sym (lib, "entry");
        if (fcn) fcn (lang->user);
        else eprintf ("Cannot find 'entry' symbol in library\n");
        r_lib_dl_close (lib);
    } else eprintf ("Cannot open library\n");
    r_file_rm (buf); // remove lib
    return 0;
}
Пример #7
0
static int lang_cpipe_file(RLang *lang, const char *file) {
	char *a, *cc, *p, name[512];
	const char *libpath, *libname;

	if (strlen (file) > (sizeof (name)-10))
		return 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 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) {
		free (cc);
		cc = strdup ("gcc");
	}
	char *buf = r_str_newf ("%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) {
		char *binfile = r_str_newf ("%s/bin%s", libpath, libname);
		lang_pipe_run (lang, binfile, -1);
		r_file_rm (binfile);
		free (binfile);
	}
	free (buf);
	return 0;
}
Пример #8
0
R_API R2Pipe *r2p_open(const char *cmd) {
    R2Pipe *r2p = R_NEW0 (R2Pipe);
    r2p->magic = R2P_MAGIC;
    if (!cmd) {
        r2p->child = -1;
        return r2p_open_spawn (r2p, cmd);
    }
#if __WINDOWS__ && !defined(__CYGWIN__)
    w32_createPipe (r2p, cmd);
    r2p->child = (int)(r2p->pipe);
#else
    pipe (r2p->input);
    pipe (r2p->output);
    r2p->child = fork ();
    if (r2p->child == -1) {
        r2p_close (r2p);
        return NULL;
    }
    env ("R2PIPE_IN", r2p->input[0]);
    env ("R2PIPE_OUT", r2p->output[1]);

    if (r2p->child) {
        eprintf ("Child is %d\n", r2p->child);
        char ch;
        read (r2p->output[0], &ch, 1);
    } else {
        int rc = 0;
        if (cmd && *cmd) {
            close (0);
            close (1);
            dup2 (r2p->input[0], 0);
            dup2 (r2p->output[1], 1);
            rc = r_sandbox_system (cmd, 0);
        }
        r2p_close (r2p);
        exit (rc);
        return NULL;
    }
#endif
    return r2p;
}
Пример #9
0
R_API int r_sys_cmdbg (const char *str) {
#if __UNIX__ || __CYGWIN && !defined(MINGW32)
	int ret, pid = r_sys_fork ();
	if (pid == -1) {
		return -1;
	}
	if (pid) {
		return pid;
	}
	ret = r_sandbox_system (str, 0);
	eprintf ("{exit: %d, pid: %d, cmd: \"%s\"}", ret, pid, str);
	exit (0);
	return -1;
#else
#ifdef _MSC_VER
#pragma message ("r_sys_cmdbg is not implemented for this platform")
#else
#warning r_sys_cmdbg is not implemented for this platform
#endif
	return -1;
#endif
}
Пример #10
0
R_API int r_sys_cmd_str_full(const char *cmd, const char *input, char **output, int *len, char **sterr) {
	char buffer[1024], *outputptr = NULL;
	char *inputptr = (char *)input;
	int pid, bytes = 0, status;
	int sh_in[2], sh_out[2], sh_err[2];

	if (len) *len = 0;
	if (pipe (sh_in))
		return R_FALSE;
	if (output) {
		if (pipe (sh_out)) {
			close (sh_in[0]);
			close (sh_in[1]);
			close (sh_out[0]);
			close (sh_out[1]);
			return R_FALSE;
		}
	}
	if (pipe (sh_err)) {
		close (sh_in[0]);
		close (sh_in[1]);
		return R_FALSE;
	}

	switch ((pid=fork ())) {
	case -1:
		return R_FALSE;
	case 0:
		dup2 (sh_in[0], 0); close (sh_in[0]); close (sh_in[1]);
		if (output) { dup2 (sh_out[1], 1); close (sh_out[0]); close (sh_out[1]); }
		if (sterr) dup2 (sh_err[1], 2); else close (2);
		close (sh_err[0]); close (sh_err[1]);
		exit (r_sandbox_system (cmd, 0));
	default:
		outputptr = strdup ("");
		if (!outputptr)
			return R_FALSE;
		if (sterr) {
			*sterr = strdup ("");
			if (!*sterr) {
				free (outputptr);
				return R_FALSE;
			}
		}
		if (output) close (sh_out[1]);
		close (sh_err[1]);
		close (sh_in[0]);
		if (!inputptr || !*inputptr)
			close (sh_in[1]);

		for (;;) {
			fd_set rfds, wfds;
			int nfd;

			FD_ZERO (&rfds);
			FD_ZERO (&wfds);
			if (output)
				FD_SET (sh_out[0], &rfds);
			if (sterr)
				FD_SET (sh_err[0], &rfds);
			if (inputptr && *inputptr)
				FD_SET (sh_in[1], &wfds);
			memset (buffer, 0, sizeof (buffer));
			nfd = select (sh_err[0] + 1, &rfds, &wfds, NULL, NULL);
			if (nfd < 0)
				break;
			if (output && FD_ISSET (sh_out[0], &rfds)) {
				if ((bytes = read (sh_out[0], buffer, sizeof (buffer)-1)) == 0) break;
				buffer[sizeof(buffer) - 1] = '\0';
				if (len) *len += bytes;
				outputptr = r_str_concat (outputptr, buffer);
			} else if (FD_ISSET (sh_err[0], &rfds) && sterr) {
				if (read (sh_err[0], buffer, sizeof (buffer)-1) == 0) break;
				buffer[sizeof(buffer) - 1] = '\0';
				*sterr = r_str_concat (*sterr, buffer);
			} else if (FD_ISSET (sh_in[1], &wfds) && inputptr && *inputptr) {
				bytes = write (sh_in[1], inputptr, strlen (inputptr));
				inputptr += bytes;
				if (!*inputptr) {
					close (sh_in[1]);
					/* If neither stdout nor stderr should be captured,
					 * abort now - nothing more to do for select(). */
					if (!output && !sterr) break;
				}
			}
		}
		if (output)
			close (sh_out[0]);
		close (sh_err[0]);
		close (sh_in[1]);
		waitpid (pid, &status, 0);
		if (status != 0) {
			char *escmd = r_str_escape (cmd);
			eprintf ("%s: failed command '%s'\n", __func__, escmd);
			free (escmd);
			return R_FALSE;
		}

		if (output) *output = outputptr;
		else free (outputptr);
		return R_TRUE;
	}
	return R_FALSE;
}
Пример #11
0
R_API R2Pipe *r2pipe_open(const char *cmd) {
	R2Pipe *r2pipe = r2pipe_new ();
	if (!r2pipe) {
		return NULL;
	}
	if (!cmd) {
		r2pipe->child = -1;
		return r2pipe_open_spawn (r2pipe);
	}
#if __WINDOWS__ && !defined(__CYGWIN__)
	w32_createPipe (r2pipe, cmd);
	r2pipe->child = (int)(r2pipe->pipe);
#else
	int r = pipe (r2pipe->input);
	if (r != 0) {
		eprintf ("pipe failed on input\n");
		r2pipe_close (r2pipe);
		return NULL;
	}
	r = pipe (r2pipe->output);
	if (r != 0) {
		eprintf ("pipe failed on output\n");
		r2pipe_close (r2pipe);
		return NULL;
	}
#if LIBC_HAVE_FORK
	r2pipe->child = fork ();
#else
	r2pipe->child = -1;
#endif
	if (r2pipe->child == -1) {
		r2pipe_close (r2pipe);
		return NULL;
	}
	env ("R2PIPE_IN", r2pipe->input[0]);
	env ("R2PIPE_OUT", r2pipe->output[1]);

	if (r2pipe->child) {
		char ch = 1;
		// eprintf ("[+] r2pipeipe child is %d\n", r2pipe->child);
		if (read (r2pipe->output[0], &ch, 1) != 1) {
			eprintf ("Failed to read 1 byte\n");
			r2pipe_close (r2pipe);
			return NULL;
		}
		if (ch) {
			eprintf ("[+] r2pipeipe-io link failed. Expected two null bytes.\n");
			r2pipe_close (r2pipe);
			return NULL;
		}
		// Close parent's end of pipes
		close (r2pipe->input[0]);
		close (r2pipe->output[1]);
		r2pipe->input[0] = -1;
		r2pipe->output[1] = -1;
	} else {
		int rc = 0;
		if (cmd && *cmd) {
			close (0);
			close (1);
			dup2 (r2pipe->input[0], 0);
			dup2 (r2pipe->output[1], 1);
			close (r2pipe->input[1]);
			close (r2pipe->output[0]);
			r2pipe->input[1] = -1;
			r2pipe->output[0] = -1;
			rc = r_sandbox_system (cmd, 0);
		}
		r2pipe_close (r2pipe);
		exit (rc);
		return NULL;
	}
#endif
	return r2pipe;
}
Пример #12
0
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
}
Пример #13
0
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
}
Пример #14
0
R_API int r_sys_cmd_str_full(const char *cmd, const char *input, char **output, int *len, char **sterr) {
	char *mysterr = NULL;
	if (!sterr) {
		sterr = &mysterr;
	}
	char buffer[1024], *outputptr = NULL;
	char *inputptr = (char *)input;
	int pid, bytes = 0, status;
	int sh_in[2], sh_out[2], sh_err[2];

	if (len) {
		*len = 0;
	}
	if (pipe (sh_in)) {
		return false;
	}
	if (output) {
		if (pipe (sh_out)) {
			close (sh_in[0]);
			close (sh_in[1]);
			close (sh_out[0]);
			close (sh_out[1]);
			return false;
		}
	}
	if (pipe (sh_err)) {
		close (sh_in[0]);
		close (sh_in[1]);
		return false;
	}

	switch ((pid = r_sys_fork ())) {
	case -1:
		return false;
	case 0:
		dup2 (sh_in[0], 0);
		close (sh_in[0]);
		close (sh_in[1]);
		if (output) {
			dup2 (sh_out[1], 1);
			close (sh_out[0]);
			close (sh_out[1]);
		}
		if (sterr) {
			dup2 (sh_err[1], 2); 
		} else {
			close (2);
		}
		close (sh_err[0]);
		close (sh_err[1]);
		exit (r_sandbox_system (cmd, 0));
	default:
		outputptr = strdup ("");
		if (!outputptr) {
			return false;
		}
		if (sterr) {
			*sterr = strdup ("");
			if (!*sterr) {
				free (outputptr);
				return false;
			}
		}
		if (output) {
			close (sh_out[1]);
		}
		close (sh_err[1]);
		close (sh_in[0]);
		if (!inputptr || !*inputptr) {
			close (sh_in[1]);
		}
		// we should handle broken pipes somehow better
		signal (SIGPIPE, SIG_IGN);
		for (;;) {
			fd_set rfds, wfds;
			int nfd;
			FD_ZERO (&rfds);
			FD_ZERO (&wfds);
			if (output) {
				FD_SET (sh_out[0], &rfds);
			}
			if (sterr) {
				FD_SET (sh_err[0], &rfds);
			}
			if (inputptr && *inputptr) {
				FD_SET (sh_in[1], &wfds);
			}
			memset (buffer, 0, sizeof (buffer));
			nfd = select (sh_err[0] + 1, &rfds, &wfds, NULL, NULL);
			if (nfd < 0) {
				break;
			}
			if (output && FD_ISSET (sh_out[0], &rfds)) {
				if (!(bytes = read (sh_out[0], buffer, sizeof (buffer)-1))) {
					break;
				}
				buffer[sizeof (buffer) - 1] = '\0';
				if (len) {
					*len += bytes;
				}
				outputptr = r_str_append (outputptr, buffer);
			} else if (FD_ISSET (sh_err[0], &rfds) && sterr) {
				if (!read (sh_err[0], buffer, sizeof (buffer)-1)) {
					break;
				}
				buffer[sizeof (buffer) - 1] = '\0';
				*sterr = r_str_append (*sterr, buffer);
			} else if (FD_ISSET (sh_in[1], &wfds) && inputptr && *inputptr) {
				int inputptr_len = strlen (inputptr);
				bytes = write (sh_in[1], inputptr, inputptr_len);
				if (bytes != inputptr_len) {
					break;
				}
				inputptr += bytes;
				if (!*inputptr) {
					close (sh_in[1]);
					/* If neither stdout nor stderr should be captured,
					 * abort now - nothing more to do for select(). */
					if (!output && !sterr) {
						break;
					}
				}
			}
		}
		if (output) {
			close (sh_out[0]);
		}
		close (sh_err[0]);
		close (sh_in[1]);
		waitpid (pid, &status, 0);
		bool ret = true;
		if (status) {
			// char *escmd = r_str_escape (cmd);
			// eprintf ("error code %d (%s): %s\n", WEXITSTATUS (status), escmd, *sterr);
			// eprintf ("(%s)\n", output);
			// eprintf ("%s: failed command '%s'\n", __func__, escmd);
			// free (escmd);
			ret = false;
		}

		if (output) {
			*output = outputptr;
		} else {
			free (outputptr);
		}
		return ret;
	}
	return false;
}
Пример #15
0
static int rafind_open_file(char *file) {
	const char *kw;
	RListIter *iter;
	bool last = false;
	int ret;

	if (!quiet) {
		printf ("File: %s\n", file);
	}

	if (identify) {
		char *cmd = r_str_newf ("r2 -e search.show=false -e search.maxhits=1 -nqcpm '%s'", file);
		r_sandbox_system (cmd, 1);
		free (cmd);
		return 0;
	}

	io = r_io_new ();
	fd = r_io_open_nomap (io, file, R_PERM_R, 0);
	if (!fd) {
		eprintf ("Cannot open file '%s'\n", file);
		return 1;
	}

	r_cons_new ();
	rs = r_search_new (mode);
	if (!rs) {
		return 1;
	}
	buf = calloc (1, bsize);
	if (!buf) {
		eprintf ("Cannot allocate %"PFMT64d" bytes\n", bsize);
		return 1;
	}
	rs->align = align;
	r_search_set_callback (rs, &hit, buf);
	if (to == -1) {
		to = r_io_size(io);
	}
	if (mode == R_SEARCH_STRING) {
		/* TODO: implement using api */
		r_sys_cmdf ("rabin2 -qzzz '%s'", file);
		return 0;
	}
	if (mode == R_SEARCH_MAGIC) {
		char *tostr = (to && to != UT64_MAX)?
			r_str_newf ("-e search.to=%"PFMT64d, to): strdup ("");
		char *cmd = r_str_newf ("r2"
			" -e search.in=range"
			" -e search.align=%d"
			" -e search.from=%"PFMT64d
			" %s -qnc/m '%s'",
			align, from, tostr, file);
		r_sandbox_system (cmd, 1);
		free (cmd);
		free (tostr);
		return 0;
	}
	if (mode == R_SEARCH_ESIL) {
		char *cmd;
		r_list_foreach (keywords, iter, kw) {
			cmd = r_str_newf ("r2 -qc \"/E %s\" %s", kw, file);
			r_sandbox_system (cmd, 1);
			free (cmd);
		}
Пример #16
0
static int lang_vala_file(RLang *lang, const char *file, bool silent) {
	void *lib;
	char *p, name[512], buf[512];
	char *vapidir, *srcdir, *libname;

	if (strlen (file)>500)
		return false;
	if (!strstr (file, ".vala"))
		sprintf (name, "%s.vala", file);
	else strcpy (name, file);
	if (!r_file_exists (name)) {
		eprintf ("file not found (%s)\n", name);
		return false;
	}

	srcdir = strdup (file);
	p = (char*)r_str_lchr (srcdir, '/');
	if (p) {
		*p = 0;
		libname = strdup (p+1);
		if (*file!='/') {
			strcpy (srcdir, ".");
		}
	} else {
		libname = strdup (file);
		strcpy (srcdir, ".");
	}
	r_sys_setenv ("PKG_CONFIG_PATH", R2_LIBDIR"/pkgconfig");
	vapidir = r_sys_getenv ("VAPIDIR");
	char *tail = silent?  " > /dev/null 2>&1": "";
	if (vapidir) {
		if (*vapidir) {
			snprintf (buf, sizeof (buf)-1, "valac -d %s --vapidir=%s --pkg r_core -C %s %s",
				srcdir, vapidir, name, tail);
		}
		free (vapidir);
	} else {
		snprintf (buf, sizeof (buf) - 1, "valac -d %s --pkg r_core -C %s %s", srcdir, name, tail);
	}
	free (srcdir);
	if (r_sandbox_system (buf, 1) != 0) {
		free (libname);
		return false;
	}
	p = strstr (name, ".vala"); if (p) *p=0;
	p = strstr (name, ".gs"); if (p) *p=0;
	// TODO: use CC environ if possible
	snprintf (buf, sizeof (buf), "gcc -fPIC -shared %s.c -o lib%s."R_LIB_EXT
		" $(pkg-config --cflags --libs r_core gobject-2.0)", name, libname);
	if (r_sandbox_system (buf, 1) != 0) {
		free (libname);
		return false;
	}

	snprintf (buf, sizeof (buf), "./lib%s."R_LIB_EXT, libname);
	free (libname);
	lib = r_lib_dl_open (buf);
	if (lib != NULL) {
		void (*fcn)(RCore *);
		fcn = r_lib_dl_sym (lib, "entry");
		if (fcn) fcn (lang->user);
		else eprintf ("Cannot find 'entry' symbol in library\n");
		r_lib_dl_close (lib);
	} else eprintf ("Cannot open library\n");
	r_file_rm (buf); // remove lib
	sprintf (buf, "%s.c", name); // remove .c
	r_file_rm (buf);
	return 0;
}