static int lang_lib_file_run (RLang *user, const char *file) { char *libpath; void *lib; if (!(libpath = r_str_new (file))) { return -1; } if (!r_str_startswith (libpath, "/") && !r_str_startswith (libpath, "./")) { libpath = r_str_prefix (libpath, "./"); } if (!r_file_exists (libpath)) { if (!r_str_endswith (libpath, R_LIB_EXT)) { libpath = r_str_appendf (libpath, ".%s", R_LIB_EXT); } } if (!r_file_exists (libpath)) { free (libpath); return -1; } lib = r_lib_dl_open (libpath); if (lib) { void (*fcn)(RCore *); fcn = r_lib_dl_sym (lib, "entry"); if (fcn) { fcn (user->user); } else { eprintf ("Cannot find 'entry' symbol in library\n"); } r_lib_dl_close (lib); } free (libpath); return 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; }
static int r_vala_file(RLang *lang, const char *file) { void *lib; char *p, name[512], buf[512]; char *vapidir; 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 R_FALSE; } vapidir = r_sys_getenv ("VAPIDIR"); if (vapidir) { if (*vapidir) { snprintf (buf, sizeof (buf), "valac --vapidir=%s --pkg r_core -C %s", vapidir, name); } free (vapidir); } else sprintf (buf, "valac --pkg r_core -C %s", name); if (system (buf) != 0) return R_FALSE; p = strstr (name, ".vala"); if (p) *p=0; p = strstr (name, ".gs"); if (p) *p=0; 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, name); if (system (buf) != 0) return R_FALSE; snprintf (buf, sizeof (buf), "./lib%s."R_LIB_EXT, name); 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; }
R_API int r_run_start(RRunProfile *p) { #if LIBC_HAVE_FORK if (p->_execve) { exit (execv (p->_program, (char* const*)p->_args)); } #endif #if __APPLE__ && !__POWERPC__ && LIBC_HAVE_FORK posix_spawnattr_t attr = {0}; pid_t pid = -1; int ret; posix_spawnattr_init (&attr); if (p->_args[0]) { char **envp = r_sys_get_environ(); ut32 spflags = 0; //POSIX_SPAWN_START_SUSPENDED; spflags |= POSIX_SPAWN_SETEXEC; if (p->_aslr == 0) { #define _POSIX_SPAWN_DISABLE_ASLR 0x0100 spflags |= _POSIX_SPAWN_DISABLE_ASLR; } (void)posix_spawnattr_setflags (&attr, spflags); if (p->_bits) { size_t copied = 1; cpu_type_t cpu; #if __i386__ || __x86_64__ cpu = CPU_TYPE_I386; if (p->_bits == 64) { cpu |= CPU_ARCH_ABI64; } #else cpu = CPU_TYPE_ANY; #endif posix_spawnattr_setbinpref_np ( &attr, 1, &cpu, &copied); } ret = posix_spawnp (&pid, p->_args[0], NULL, &attr, p->_args, envp); switch (ret) { case 0: break; case 22: eprintf ("posix_spawnp: Invalid argument\n"); break; case 86: eprintf ("posix_spawnp: Unsupported architecture\n"); break; default: eprintf ("posix_spawnp: unknown error %d\n", ret); perror ("posix_spawnp"); break; } exit (ret); } #endif if (p->_system) { if (p->_pid) { eprintf ("PID: Cannot determine pid with 'system' directive. Use 'program'.\n"); } exit (r_sys_cmd (p->_system)); } if (p->_program) { if (!r_file_exists (p->_program)) { char *progpath = r_file_path (p->_program); if (progpath && *progpath) { free (p->_program); p->_program = progpath; } else { free (progpath); eprintf ("rarun2: %s: file not found\n", p->_program); return 1; } } #if __UNIX__ // XXX HACK close all non-tty fds { int i; for (i = 3; i < 10; i++) { close (i); } } // TODO: use posix_spawn if (p->_setgid) { int ret = setgid (atoi (p->_setgid)); if (ret < 0) { return 1; } } if (p->_pid) { eprintf ("PID: %d\n", getpid ()); } if (p->_pidfile) { char pidstr[32]; snprintf (pidstr, sizeof (pidstr), "%d\n", getpid ()); r_file_dump (p->_pidfile, (const ut8*)pidstr, strlen (pidstr), 0); } #endif if (p->_nice) { #if __UNIX__ && !defined(__HAIKU__) if (nice (p->_nice) == -1) { return 1; } #else eprintf ("nice not supported for this platform\n"); #endif } // TODO: must be HAVE_EXECVE #if LIBC_HAVE_FORK exit (execv (p->_program, (char* const*)p->_args)); #endif } if (p->_runlib) { if (!p->_runlib_fcn) { eprintf ("No function specified. Please set runlib.fcn\n"); return 1; } void *addr = r_lib_dl_open (p->_runlib); if (!addr) { eprintf ("Could not load the library '%s'\n", p->_runlib); return 1; } void (*fcn)(void) = r_lib_dl_sym (addr, p->_runlib_fcn); if (!fcn) { eprintf ("Could not find the function '%s'\n", p->_runlib_fcn); return 1; } switch (p->_argc) { case 0: fcn (); break; case 1: r_run_call1 (fcn, p->_args[1]); break; case 2: r_run_call2 (fcn, p->_args[1], p->_args[2]); break; case 3: r_run_call3 (fcn, p->_args[1], p->_args[2], p->_args[3]); break; case 4: r_run_call4 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4]); break; case 5: r_run_call5 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4], p->_args[5]); break; case 6: r_run_call6 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4], p->_args[5], p->_args[6]); break; case 7: r_run_call7 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4], p->_args[5], p->_args[6], p->_args[7]); break; case 8: r_run_call8 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4], p->_args[5], p->_args[6], p->_args[7], p->_args[8]); break; case 9: r_run_call9 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4], p->_args[5], p->_args[6], p->_args[7], p->_args[8], p->_args[9]); break; case 10: r_run_call10 (fcn, p->_args[1], p->_args[2], p->_args[3], p->_args[4], p->_args[5], p->_args[6], p->_args[7], p->_args[8], p->_args[9], p->_args[10]); break; default: eprintf ("Too many arguments.\n"); return 1; } r_lib_dl_close (addr); } return 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; }