static char *projectScriptPath(RCore *core, const char *file) { const char *magic = "# r2 rdb project file"; char *data, *prjfile; if (r_file_is_abspath (file)) { prjfile = strdup (file); } else { if (!is_valid_project_name (file)) { return NULL; } prjfile = r_file_abspath (r_config_get (core->config, "dir.projects")); prjfile = r_str_append (prjfile, R_SYS_DIR); prjfile = r_str_append (prjfile, file); if (!r_file_exists (prjfile) || r_file_is_directory (prjfile)) { prjfile = r_str_append (prjfile, R_SYS_DIR "rc"); } } data = r_file_slurp (prjfile, NULL); if (data) { if (strncmp (data, magic, strlen (magic))) { R_FREE (prjfile); } } free (data); return prjfile; }
R_API char *r_cons_hud_path(const char *path, int dir) { char *tmp = NULL, *ret = NULL; RList *files; if (path){ while (*path==' ') path++; tmp = (*path)? strdup(path): strdup ("./"); } else tmp = strdup ("./"); files = r_sys_dir (tmp); if (files) { ret = r_cons_hud (files, tmp); if (ret) { tmp = r_str_concat (tmp, "/"); tmp = r_str_concat (tmp, ret); ret = r_file_abspath (tmp); free (tmp); tmp = ret; if (r_file_is_directory (tmp)) { ret = r_cons_hud_path (tmp, dir); free (tmp); tmp = ret; } } r_list_free (files); } else eprintf ("No files found\n"); if (!ret) { free (tmp); return NULL; } return tmp; }
static int __io_posix_open(const char *file, int perm, int mode) { int fd; if (r_str_startswith (file, "file://")) { file += strlen ("file://"); } if (r_file_is_directory (file)) { return -1; } #if __WINDOWS__ // probably unnecessary to have this ifdef nowadays windows is posix enough if (perm & R_PERM_W) { fd = r_sandbox_open (file, O_BINARY | O_RDWR, 0); if (fd == -1 && perm & R_PERM_CREAT) { r_sandbox_creat (file, 0644); fd = r_sandbox_open (file, O_BINARY | O_RDWR | O_CREAT, 0); } } else { fd = r_sandbox_open (file, O_BINARY, 0); } #else const int posixFlags = (perm & R_PERM_W) ? (perm & R_PERM_CREAT) ? (O_RDWR | O_CREAT) : O_RDWR : O_RDONLY; fd = r_sandbox_open (file, posixFlags, mode); #endif return fd; }
static char* get_file_in_cur_dir(const char *filepath) { filepath = r_file_basename (filepath); if (r_file_exists (filepath) && !r_file_is_directory (filepath)) { return r_file_abspath (filepath); } return NULL; }
R_API int r_core_project_delete(RCore *core, const char *prjfile) { if (r_sandbox_enable (0)) { eprintf ("Cannot delete project in sandbox mode\n"); return 0; } char *path = projectScriptPath (core, prjfile); if (!path) { eprintf ("Invalid project name '%s'\n", prjfile); return false; } if (r_core_is_project (core, prjfile)) { char *prjDir = r_file_dirname (path); if (!prjDir) { eprintf ("Cannot resolve directory\n"); free (path); return false; } // rm project file if (r_file_exists (path)) { r_file_rm (path); eprintf ("rm %s\n", path); } //rm notes.txt file char *notes_txt = r_str_newf ("%s%s%s", prjDir, R_SYS_DIR, "notes.txt"); if (r_file_exists (notes_txt)) { r_file_rm (notes_txt); eprintf ("rm %s\n", notes_txt); } free(notes_txt); char *rop_d = r_str_newf ("%s%s%s", prjDir, R_SYS_DIR, "rop.d"); if (r_file_is_directory (rop_d)) { char *f; RListIter *iter; RList *files = r_sys_dir (rop_d); r_list_foreach (files, iter, f) { char *filepath = r_str_append (strdup (rop_d), R_SYS_DIR); filepath = r_str_append (filepath, f); if (!r_file_is_directory (filepath)) { eprintf ("rm %s\n", filepath); r_file_rm (filepath); } free (filepath); } r_file_rm (rop_d); eprintf ("rm %s\n", rop_d); r_list_free (files); } free (rop_d); // remove directory only if it's empty r_file_rm (prjDir); free (prjDir); }
static int r_core_is_project(RCore *core, const char *name) { int ret = 0; if (name && *name && *name!='.') { char *path = r_core_project_file (core, name); if (!path) return 0; path = r_str_concat (path, ".d"); if (r_file_is_directory (path)) ret = 1; free (path); } return ret; }
static int cmd_log(void *data, const char *input) { RCore *core = (RCore *)data; const char *input2 = input + (*input? (*input==' '? 2: 1): 0); char *arg = strchr (input2, ' '); int n = atoi (input2); int n2 = arg? atoi (arg+1): 0; switch (*input) { case 'l': r_cons_printf ("%d\n", core->log->last-1); break; case '-': r_core_log_del (core, n); break; case '?': r_cons_printf ("Usage: l[-][ num|msg]\n" " l new comment 0x80480\n" " ll get last log message id\n" " l- delete all logs\n" " l-123 delete logs before 123\n" " l 123 list log from 123 \n" " l list all log messages\n" " l 10 3 list 3 log messages starting from 10\n" " ls list files in current directory (see pwd, cd)\n" " lj list in json format\n" " l* list in radare commands\n" ); break; case ' ': if (!n) { r_core_log_add (core, input+1); break; } case 's': { char *name; RListIter *iter; RList *files = r_sys_dir ("."); r_list_foreach (files, iter, name) { r_cons_printf ("%s%s\n", name, r_file_is_directory (name)? "/":""); } r_list_free (files); } break; case 'j': case '*': case '\0': r_core_log_list (core, n, n2, *input); break; }
static int __io_posix_open (const char *file, int flags, int mode) { int fd; if (r_file_is_directory (file)) return -1; #if __WINDOWS__ if (flags & R_IO_WRITE) { fd = r_sandbox_open (file, O_BINARY | 1, 0); if (fd == -1) r_sandbox_creat (file, O_BINARY); fd = r_sandbox_open (file, O_BINARY | 1, 0); } else fd = r_sandbox_open (file, O_BINARY, 0); #else fd = r_sandbox_open (file, (flags&R_IO_WRITE)? (O_RDWR|O_CREAT): O_RDONLY, mode); #endif return fd; }
R_API bool r_core_is_project(RCore *core, const char *name) { bool ret = false; if (name && *name && *name != '.') { char *path = projectScriptPath (core, name); if (!path) { return false; } if (r_str_endswith (path, R_SYS_DIR "rc") && r_file_exists (path)) { ret = true; } else { path = r_str_append (path, ".d"); if (r_file_is_directory (path)) { ret = true; } } free (path); } return ret; }
static int __io_posix_open(const char *file, int flags, int mode) { int fd; if (r_str_startswith (file, "file://")) { file += strlen ("file://"); } if (r_file_is_directory (file)) { return -1; } #if __WINDOWS__ if (flags & R_IO_WRITE) { fd = r_sandbox_open (file, O_BINARY | O_RDWR, 0); if (fd == -1) { r_sandbox_creat (file, 0644); fd = r_sandbox_open (file, O_BINARY | O_RDWR, 0); } } else { fd = r_sandbox_open (file, O_BINARY, 0); } #else fd = r_sandbox_open (file, (flags & R_IO_WRITE) ? (O_RDWR|O_CREAT) : O_RDONLY, mode); #endif return fd; }
R_API int r_core_project_delete(RCore *core, const char *prjfile) { char *path; if (r_sandbox_enable (0)) { eprintf ("Cannot delete project in sandbox mode\n"); return 0; } path = r_core_project_file (core, prjfile); if (!path) { eprintf ("Invalid project name '%s'\n", prjfile); return false; } if (r_core_is_project (core, prjfile)) { // rm project file r_file_rm (path); eprintf ("rm %s\n", path); path = r_str_concat (path, ".d"); if (r_file_is_directory (path)) { char *f; RListIter *iter; RList *files = r_sys_dir (path); r_list_foreach (files, iter, f) { char *filepath = r_str_concat (strdup (path), R_SYS_DIR); filepath =r_str_concat (filepath, f); if (!r_file_is_directory (filepath)) { eprintf ("rm %s\n", filepath); r_file_rm (filepath); } free (filepath); } r_file_rm (path); eprintf ("rm %s\n", path); r_list_free (files); } // TODO: remove .d directory (BEWARE OF ROOT RIMRAFS!) // TODO: r_file_rmrf (path); }
R_API int r_cons_w32_print(const ut8 *ptr, int len, int vmode) { HANDLE hConsole = GetStdHandle (STD_OUTPUT_HANDLE); int esc = 0; int bg = 0, fg = 1|2|4|8; const ut8 *ptr_end, *str = ptr; int ret = 0; int inv = 0; int linelen = 0; int ll = 0; int lines, cols = r_cons_get_size (&lines); if (I->is_wine==-1) { I->is_wine = r_file_is_directory ("/proc")? 1: 0; } if (len < 0) { len = strlen ((const char *)ptr); } ptr_end = ptr + len; if (ptr && hConsole) for (; *ptr && ptr < ptr_end; ptr++) { if (ptr[0] == 0xa) { ll = (size_t)(ptr - str); lines--; if (vmode && lines < 0) { break; } if (ll < 1) { continue; } if (vmode) { // TODO: Fix utf8 chop /* only chop columns if necessary */ if (ll + linelen >= cols) { // chop line if too long ll = (cols - linelen) - 1; if (ll < 0) { continue; } } } if (ll > 0) { write (1, str, ll); linelen += ll; } esc = 0; str = ptr + 1; if (vmode) { int wlen = cols - linelen; char white[1024]; if (wlen > 0 && wlen < sizeof (white)) { memset (white, ' ', sizeof (white)); write (1, white, wlen-1); } } write (1, "\n\r", 2); // reset colors for next line SetConsoleTextAttribute (hConsole, 1 | 2 | 4 | 8); linelen = 0; continue; } if (ptr[0] == 0x1b) { ll = (size_t)(ptr-str); if (str[0] == '\n') { str++; ll--; if (vmode) { int wlen = cols - linelen - 1; char white[1024]; //wlen = 5; if (wlen > 0) { memset (white, ' ', sizeof (white)); write (1, white, wlen); } } write (1, "\n\r", 2); //write (1, "\r\n", 2); //lines--; linelen = 0; } if (vmode) { if (linelen + ll >= cols) { // chop line if too long ll = (cols-linelen) - 1; if (ll > 0) { // fix utf8 len here ll = wrapline ((const char*)str, cols - linelen - 1); } } } if (ll > 0) { write (1, str, ll); linelen += ll; } esc = 1; str = ptr + 1; continue; } if (esc == 1) { // \x1b[2J if (ptr[0] != '[') { eprintf ("Oops invalid escape char\n"); esc = 0; str = ptr + 1; continue; } esc = 2; continue; } else if (esc == 2) { const char *ptr2 = NULL; int x, y, i, state = 0; for (i = 0; ptr[i] && state >= 0; i++) { switch (state) { case 0: if (ptr[i] == ';') { y = atoi ((const char *)ptr); state = 1; ptr2 = (const char *)ptr+i+1; } else if (ptr[i] >='0' && ptr[i]<='9') { // ok } else { state = -1; // END FAIL } break; case 1: if (ptr[i]=='H') { x = atoi (ptr2); state = -2; // END OK } else if (ptr[i] >='0' && ptr[i]<='9') { // ok } else { state = -1; // END FAIL } break; } } if (state == -2) { w32_gotoxy (x, y); ptr += i; str = ptr + 1;// + i-2; continue; } if (ptr[0]=='0' && ptr[1] == ';' && ptr[2]=='0') { // \x1b[0;0H /** clear screen if gotoxy **/ if (vmode) { // fill row here fill_tail (cols, lines); } w32_gotoxy (0, 0); lines = 0; esc = 0; ptr += 3; str = ptr + 1; continue; } else if (ptr[0]=='2'&&ptr[1]=='J') { //fill_tail(cols, lines); w32_clear (); //r_cons_clear (); esc = 0; ptr = ptr + 1; str = ptr + 1; continue; } else if (ptr[0]=='0'&&(ptr[1]=='m' || ptr [1]=='K')) { SetConsoleTextAttribute (hConsole, 1|2|4|8); fg = 1|2|4|8; bg = 0; inv = 0; esc = 0; ptr++; str = ptr + 1; continue; // reset color } else if (ptr[0]=='2'&&ptr[1]=='7'&&ptr[2]=='m') { SetConsoleTextAttribute (hConsole, bg|fg); inv = 0; esc = 0; ptr = ptr + 2; str = ptr + 1; continue; // invert off } else if (ptr[0]=='7'&&ptr[1]=='m') { SetConsoleTextAttribute (hConsole, bg|fg|128); inv = 128; esc = 0; ptr = ptr + 1; str = ptr + 1; continue; // invert } else if (ptr[0]=='3' && (ptr[2]=='m' || ptr[2] == ';')) { // http://www.betarun.com/Pages/ConsoleColor/ switch (ptr[1]) { case '0': // BLACK fg = 0; break; case '1': // RED fg = 4; break; case '2': // GREEN fg = 2; break; case '3': // YELLOW fg = 2|4; break; case '4': // BLUE fg = 1; break; case '5': // MAGENTA fg = 1|4; break; case '6': // TURQOISE fg = 1|2|8; break; case '7': // WHITE fg = 1|2|4; break; case '8': // GRAY fg = 8; break; case '9': // ??? break; } SetConsoleTextAttribute (hConsole, bg|fg|inv); esc = 0; ptr = ptr + 2; str = ptr + 1; continue; } else if (ptr[0]=='4' && ptr[2]=='m') { /* background color */ switch (ptr[1]) { case '0': // BLACK bg = 0; break; case '1': // RED bg = 40; break; case '2': // GREEN bg = 20; break; case '3': // YELLOW bg = 20|40; break; case '4': // BLUE bg = 10; break; case '5': // MAGENTA bg = 10|40; break; case '6': // TURQOISE bg = 10|20|80; break; case '7': // WHITE bg = 10|20|40; break; case '8': // GRAY bg = 80; break; case '9': // ??? break; } esc = 0; ptr = ptr + 2; str = ptr + 1; continue; } } ret++; } if (vmode) { /* fill partial line */ int wlen = cols-linelen - 1; if (wlen > 0) { char white[1024]; memset (white, ' ', sizeof (white)); write (1, white, wlen); } /* fill tail */ fill_tail (cols, lines); } else { int ll = (size_t)(ptr - str); if (ll > 0) { write (1, str, ll); linelen += ll; } } return ret; }
int main(int argc, char **argv) { int i, ret, c, rad = 0, bsize = 0, numblocks = 0, ule = 0, b64mode = 0; const char *algo = "sha256"; /* default hashing algorithm */ const char *seed = NULL; char *hashstr = NULL; int hashstr_len = 0; int hashstr_hex = 0; ut64 algobit; RHash *ctx; RIO *io; while ((c = getopt (argc, argv, "jdDrvea:i:S:s:x:b:nBhf:t:kLq")) != -1) { switch (c) { case 'q': quiet = 1; break; case 'i': iterations = atoi (optarg); if (iterations<0) { eprintf ("error: -i argument must be positive\n"); return 1; } break; case 'j': rad = 'j'; break; case 'S': seed = optarg; break; case 'n': numblocks = 1; break; case 'd': b64mode = 1; break; case 'D': b64mode = 2; break; case 'L': algolist (); return 0; case 'e': ule = 1; break; case 'r': rad = 1; break; case 'k': rad = 2; break; case 'a': algo = optarg; break; case 'B': incremental = 0; break; case 'b': bsize = (int)r_num_math (NULL, optarg); break; case 'f': from = r_num_math (NULL, optarg); break; case 't': to = 1+r_num_math (NULL, optarg); break; case 'v': return blob_version ("rahash2"); case 'h': return do_help (0); case 's': setHashString (optarg, 0); break; case 'x': setHashString (optarg, 1); break; break; default: eprintf ("rahash2: Unknown flag\n"); return 1; } } if ((st64)from>=0 && (st64)to<0) { to = 0; // end of file } if (from || to) { if (to && from>=to) { eprintf ("Invalid -f or -t offsets\n"); return 1; } } do_hash_seed (seed); if (hashstr) { #define INSIZE 32768 if (!strcmp (hashstr, "-")) { int res = 0; hashstr = malloc (INSIZE); if (!hashstr) return 1; res = fread ((void*)hashstr, 1, INSIZE-1, stdin); if (res<1) res = 0; hashstr[res] = '\0'; hashstr_len = res; } if (hashstr_hex) { ut8 *out = malloc ((strlen (hashstr)+1)*2); hashstr_len = r_hex_str2bin (hashstr, out); if (hashstr_len<1) { eprintf ("Invalid hex string\n"); free (out); } hashstr = (char *)out; /* out memleaks here, hashstr can't be freed */ } else { hashstr_len = strlen (hashstr); } if (from) { if (from>=hashstr_len) { eprintf ("Invalid -f.\n"); return 1; } } if (to) { if (to>hashstr_len) { eprintf ("Invalid -t.\n"); return 1; } } else { to = hashstr_len; } hashstr = hashstr+from; hashstr_len = to-from; hashstr[hashstr_len] = '\0'; hashstr_len = r_str_unescape (hashstr); switch (b64mode) { case 1: // encode { char *out = malloc (((hashstr_len+1)*4)/3); if (out) { r_base64_encode (out, (const ut8*)hashstr, hashstr_len); printf ("%s\n", out); fflush (stdout); free (out); } } break; case 2: // decode { ut8 *out = malloc (INSIZE); if (out) { int outlen = r_base64_decode (out, (const char *)hashstr, hashstr_len); write (1, out, outlen); free (out); } } break; default: { char *str = (char *)hashstr; int strsz = hashstr_len; if (_s) { // alloc/concat/resize str = malloc (strsz + s.len); if (s.prefix) { memcpy (str, s.buf, s.len); memcpy (str+s.len, hashstr, hashstr_len); } else { memcpy (str, hashstr, hashstr_len); memcpy (str+strsz, s.buf, s.len); } strsz += s.len; str[strsz] = 0; } algobit = r_hash_name_to_bits (algo); for (i=1; i<0x800000; i<<=1) { if (algobit & i) { int hashbit = i & algobit; ctx = r_hash_new (R_TRUE, hashbit); from = 0; to = strsz; do_hash_internal (ctx, hashbit, (const ut8*)str, strsz, rad, 1, ule); r_hash_free (ctx); } } if (_s) { free (str); free (s.buf); } } } return 0; } if (optind>=argc) return do_help (1); if (numblocks) { bsize = -bsize; } else if (bsize<0) { eprintf ("rahash2: Invalid block size\n"); return 1; } io = r_io_new (); for (ret=0, i=optind; i<argc; i++) { switch (b64mode) { case 1: // encode { int binlen; char *out; ut8 *bin = (ut8*)r_file_slurp (argv[i], &binlen); if (!bin) { eprintf ("Cannot open file\n"); continue; } out = malloc (((binlen+1)*4)/3); if (out) { r_base64_encode (out, bin, binlen); printf ("%s\n", out); fflush (stdout); free (out); } free (bin); } break; case 2: // decode { int binlen, outlen; ut8 *out, *bin = (ut8*)r_file_slurp (argv[i], &binlen); if (!bin) { eprintf ("Cannot open file\n"); continue; } out = malloc (binlen+1); if (out) { outlen = r_base64_decode (out, (const char*)bin, binlen); write (1, out, outlen); free (out); } free (bin); } break; default: if (r_file_is_directory (argv[i])) { eprintf ("rahash2: Cannot hash directories\n"); return 1; } if (!r_io_open_nomap (io, argv[i], 0, 0)) { eprintf ("rahash2: Cannot open '%s'\n", argv[i]); return 1; } ret |= do_hash (argv[i], algo, io, bsize, rad, ule); } } free (hashstr); r_io_free (io); return ret; }
int main(int argc, char **argv) { const char *algo = "sha256"; /* default hashing algorithm */ int c, rad = 0, quit = 0, bsize = 0; RIO *io; while ((c = getopt (argc, argv, "rva:s:b:Bhf:t:kL")) != -1) { switch (c) { case 'L': algolist (); return 0; case 'r': rad = 1; break; case 'k': rad = 2; break; case 'a': algo = optarg; break; case 'B': incremental = 0; break; case 'b': bsize = (int)r_num_math (NULL, optarg); break; case 's': { ut64 algobit = r_hash_name_to_bits (algo); RHash *ctx = r_hash_new (R_TRUE, algobit); from = 0; to = strlen (optarg); do_hash_internal (ctx, //0, strlen (optarg), algobit, (const ut8*) optarg, strlen (optarg), rad, 1); r_hash_free (ctx); quit = R_TRUE; } break; case 'f': from = r_num_math (NULL, optarg); break; case 't': to = r_num_math (NULL, optarg); break; case 'v': printf ("rahash2 v"R2_VERSION"\n"); return 0; case 'h': return do_help (0); } } if (quit) return 0; if (optind>=argc) return do_help (1); io = r_io_new (); if (r_file_is_directory (argv[optind])) { eprintf ("Cannot hash directories\n"); return 1; } // TODO: use mmap if (!r_io_open (io, argv[optind], 0, 0)) { eprintf ("Cannot open '%s'\n", argv[optind]); return 1; } if (bsize<1) { eprintf ("Invalid block size\n"); return 1; } return do_hash (algo, io, bsize, rad); }
R_API int r_core_project_save(RCore *core, const char *file) { int fd, fdold, tmp, ret = R_TRUE; char *prj; if (file == NULL || *file == '\0') return R_FALSE; prj = r_core_project_file (core, file); if (r_file_is_directory (prj)) { eprintf ("Error: Target is a directory\n"); free (prj); return R_FALSE; } r_core_project_init (core); r_anal_project_save (core->anal, prj); fd = r_sandbox_open (prj, O_BINARY|O_RDWR|O_CREAT, 0644); if (fd != -1) { fdold = r_cons_singleton ()->fdout; r_cons_singleton ()->fdout = fd; r_cons_singleton ()->is_interactive = R_FALSE; r_str_write (fd, "# r2 rdb project file\n"); r_str_write (fd, "# flags\n"); tmp = core->flags->space_idx; core->flags->space_idx = -1; r_flag_list (core->flags, R_TRUE); core->flags->space_idx = tmp; r_cons_flush (); r_str_write (fd, "# eval\n"); // TODO: r_str_writef (fd, "e asm.arch=%s", r_config_get ("asm.arch")); r_config_list (core->config, NULL, R_TRUE); r_cons_flush (); r_str_write (fd, "# sections\n"); r_io_section_list (core->io, core->offset, 1); r_cons_flush (); r_str_write (fd, "# meta\n"); r_meta_list (core->anal, R_META_TYPE_ANY, 1); r_cons_flush (); { char buf[1024]; snprintf (buf, sizeof (buf), "%s.d/xrefs", prj); sdb_file (core->anal->sdb_xrefs, buf); sdb_sync (core->anal->sdb_xrefs); } r_core_cmd (core, "ax*", 0); r_cons_flush (); r_core_cmd (core, "af*", 0); r_cons_flush (); r_core_cmd (core, "ah*", 0); r_cons_flush (); r_str_write (fd, "# seek\n"); r_str_writef (fd, "s 0x%08"PFMT64x, core->offset); r_cons_flush (); close (fd); r_cons_singleton ()->fdout = fdold; r_cons_singleton ()->is_interactive = R_TRUE; } else { eprintf ("Cannot open '%s' for writing\n", prj); ret = R_FALSE; } free (prj); return ret; }
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; }