static RIODesc *r2k__open(RIO *io, const char *pathname, int rw, int mode) { if (!strncmp (pathname, "r2k://", 6)) { rw |= R_IO_WRITE; rw |= R_IO_EXEC; #if __WINDOWS__ RIOW32 *w32 = R_NEW0 (RIOW32); if (Init (&pathname[6]) == FALSE) { eprintf ("r2k__open: Error cant init driver: %s\n", &pathname[6]); free (w32); return NULL; } //return r_io_desc_new (&r_io_plugin_r2k, -1, pathname, rw, mode, w32); return r_io_desc_new (io, &r_io_plugin_r2k, pathname, rw, mode, w32); #elif defined (__linux__) && !defined (__GNU__) int fd = open ("/dev/r2k", O_RDONLY); if (fd == -1) { io->cb_printf ("r2k__open: Error in opening /dev/r2k."); return NULL; } r2k_struct.beid = 0; r2k_struct.pid = 0; r2k_struct.wp = 1; return r_io_desc_new (io, &r_io_plugin_r2k, pathname, rw, mode, (void *)(size_t)fd); #else io->cb_printf ("Not supported on this platform\n"); #endif } return NULL; }
static RIODesc *__open(RIO *io, const char *file, int rw, int mode) { int pid = getpid (); self_sections_count = 0; #if __APPLE__ mach_port_t task; kern_return_t rc; rc = task_for_pid (mach_task_self(),pid, &task); if (rc) { eprintf ("task_for_pid failed\n"); return NULL; } macosx_debug_regions (task, (void*)(size_t)1, 1000); io->va = R_TRUE; // nop return r_io_desc_new (&r_io_plugin_self, pid, file, rw, mode, NULL); #elif __linux__ char *pos_c; char null[64]; char path[1024], line[1024]; char region[100], region2[100], perms[5]; snprintf (path, sizeof (path)-1, "/proc/%d/maps", pid); FILE *fd = fopen (file, "r"); if (!fd) return NULL; while (!feof (fd)) { line[0]='\0'; fgets (line, sizeof (line)-1, fd); if (line[0]=='\0') break; path[0]='\0'; sscanf (line, "%s %s %s %s %s %s", ®ion[2], perms, null, null, null, path); pos_c = strchr (®ion[2], '-'); if (pos_c) strncpy (path, pos_c, sizeof (path)-1); else path[0] = 0; int i, perm = 0; for (i = 0; perms[i] && i < 4; i++) switch (perms[i]) { case 'r': perm |= R_IO_READ; break; case 'w': perm |= R_IO_WRITE; break; case 'x': perm |= R_IO_EXEC; break; } self_sections[self_sections_count].from = r_num_get (NULL, region); self_sections[self_sections_count].to = r_num_get (NULL, region2); self_sections[self_sections_count].perm = perm; self_sections_count++; r_num_get (NULL, region2); if (!pos_c) continue; } return r_io_desc_new (&r_io_plugin_self, pid, file, rw, mode, NULL); #else #warning not yet implemented for this platform #endif return NULL; }
static RIODesc *r_io_def_mmap_open(RIO *io, const char *file, int flags, int mode) { RIOMMapFileObj *mmo = r_io_def_mmap_create_new_file (io, file, mode, flags); if (!mmo) { return NULL; } return r_io_desc_new (io, &r_io_plugin_default, mmo->filename, flags, mode, mmo); }
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) { if (__plugin_open (io, pathname,0)) { RIOSparse *mal = R_NEW0 (RIOSparse); int size = (int)r_num_math (NULL, pathname + 9); mal->buf = r_buf_new_sparse (io->Oxff); if (!mal->buf) { free (mal); return NULL; } if (size > 0) { ut8 *data = malloc (size); if (!data) { eprintf ("Cannot allocate (%s) %d byte(s)\n", pathname+9, size); mal->offset = 0; } else { memset (data, 0x00, size); r_buf_write_at (mal->buf, 0, data, size); free (data); } } if (mal->buf) { return r_io_desc_new (io, &r_io_plugin_sparse, pathname, rw, mode, mal); } r_buf_free (mal->buf); free (mal); } return NULL; }
static RIODesc *__open(struct r_io_t *io, const char *file, int rw, int mode) { RIOMach *riom; int pid; task_t task; if (!__plugin_open (io, file)) return NULL; pid = atoi (file+(file[0]=='a'?9:7)); if (pid<1) return NULL; task = debug_attach (pid); if ((int)task == -1) { switch (errno) { case EPERM: eprintf ("Operation not permitted\n"); break; case EINVAL: perror ("ptrace: Cannot attach"); eprintf ("ERRNO: %d (EINVAL)\n", errno); break; default: eprintf ("unknown error in debug_attach\n"); break; } return NULL; } riom = R_NEW (RIOMach); riom->pid = pid; riom->task = task; return r_io_desc_new (&r_io_plugin_mach, riom->pid, file, 1, mode, riom); }
static RIODesc *__open(RIO *io, const char *file, int rw, int mode) { char host[128], *port, *p; if (!__plugin_open (io, file, 0)) return NULL; RIOGdb *riog; strncpy (host, file+6, sizeof (host)-1); port = strchr (host , ':'); if (!port) { eprintf ("Port not specified. Please use gdb://[host]:[port]\n"); return NULL; } *port = '\0'; port++; p = strchr (port, '/'); if (p) *p=0; if (r_sandbox_enable (0)) { eprintf ("sandbox: Cannot use network\n"); return NULL; } riog = R_NEW (RIOGdb); gdbr_init(&riog->desc); int i_port = atoi(port); if (gdbr_connect(&riog->desc, host, i_port) == 0) { desc = &riog->desc; return r_io_desc_new (&r_io_plugin_gdb, riog->desc.fd, file, rw, mode, riog); } eprintf ("gdb.io.open: Cannot connect to host.\n"); free (riog); return NULL; }
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) { char *out; int rlen, code; if (__plugin_open (io, pathname, 0)) { out = r_socket_http_get (pathname, &code, &rlen); if (out && rlen>0) { RIOMalloc *mal = R_NEW0 (RIOMalloc); if (!mal) return NULL; mal->size = rlen; mal->buf = malloc (mal->size+1); if (!mal->buf) { free (mal); return NULL; } if (mal->buf != NULL) { mal->fd = getmalfd (mal); memcpy (mal->buf, out, mal->size); free (out); return r_io_desc_new (io, &r_io_plugin_http, pathname, rw, mode, mal); } eprintf ("Cannot allocate (%s) %d bytes\n", pathname+9, mal->size); free (mal); } free (out); } return NULL; }
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) { char *out; int rlen; if (__plugin_open (io, pathname, 0)) { RIOBind iob; RIOBfdbg *mal = R_NEW0 (RIOBfdbg); r_io_bind (io, &iob); mal->fd = getmalfd (mal); mal->bfvm = bfvm_new (&iob); out = r_file_slurp (pathname+8, &rlen); if (!out || rlen < 1) { free (mal); free (out); return NULL; } mal->size = rlen; mal->buf = malloc (mal->size+1); if (mal->buf != NULL) { memcpy (mal->buf, out, rlen); free (out); return r_io_desc_new (&r_io_plugin_bfdbg, mal->fd, pathname, rw, mode, mal); } eprintf ("Cannot allocate (%s) %d bytes\n", pathname+9, mal->size); free (mal); free (out); } return NULL; }
static RIODesc *__open(struct r_io_t *io, const char *file, int rw, int mode) { int ret = -1; if (__plugin_open (io, file)) { int pid = atoi (file+9); ret = ptrace (PTRACE_ATTACH, pid, 0, 0); if (file[0]=='p') //ptrace ret = 0; else if (ret == -1) { #ifdef __ANDROID__ eprintf ("ptrace_attach: Operation not permitted\n"); #else switch (errno) { case EPERM: ret = pid; eprintf ("ptrace_attach: Operation not permitted\n"); break; case EINVAL: perror ("ptrace: Cannot attach"); eprintf ("ERRNO: %d (EINVAL)\n", errno); break; } #endif } else if (__waitpid (pid)) ret = pid; else eprintf ("Error in waitpid\n"); if (ret != -1) { RIOPtrace *riop = R_NEW (RIOPtrace); riop->pid = riop->tid = pid; return r_io_desc_new (&r_io_plugin_ptrace, -1, file, R_TRUE, 0, riop); } } return NULL; }
static RIODesc *__open(RIO *io, const char *file, int rw, int mode) { void *io_ctx; WindCtx *ctx; if (!__plugin_open (io, file, 0)) return NULL; if (!iob_select ("pipe")) { eprintf("Could not initialize the IO backend\n"); return NULL; } io_ctx = iob_open (file + 9); if (!io_ctx) { eprintf ("Could not open the pipe\n"); return NULL; } ctx = wind_ctx_new (io_ctx); if (!ctx) return NULL; return r_io_desc_new (&r_io_plugin_windbg, -1, file, R_TRUE, mode, ctx); }
static RIODesc *__open(struct r_io_t *io, const char *pathname, int rw, int mode) { if (__plugin_open (io, pathname)) { RIOMalloc *mal = R_NEW (RIOMalloc); mal->fd = -1; /* causes r_io_desc_new() to set the correct fd */ if (!memcmp (pathname, "hex://", 6)) { mal->size = strlen (pathname); mal->buf = malloc (mal->size); memset (mal->buf, 0, mal->size); mal->size = r_hex_str2bin (pathname+6, mal->buf); } else { mal->size = r_num_math (NULL, pathname+9); if ((mal->size)>0) { mal->buf = malloc (mal->size); memset (mal->buf, '\0', mal->size); } else { eprintf ("Cannot allocate (%s) 0 bytes\n", pathname+9); return NULL; } } if (mal->buf != NULL) return r_io_desc_new (&r_io_plugin_malloc, mal->fd, pathname, rw, mode, mal); eprintf ("Cannot allocate (%s) %d bytes\n", pathname+9, mal->size); free (mal); } return NULL; }
static RIODesc *haret__open(struct r_io_t *io, const char *pathname, int rw, int mode) { char *port, *ptr, buf[1024]; RSocket *s; strncpy (buf, pathname, sizeof (buf)-1); if (haret__plugin_open (io, pathname)) { ptr = buf + 8; if (!(port = strchr (ptr, ':'))) { eprintf ("haret: wrong url\n"); return NULL; } if (!r_sandbox_enable (0)) { eprintf ("sandbox: cannot use network\n"); return NULL; } *port++ = 0; if ((s = r_socket_new (R_FALSE)) == NULL) { eprintf ("Cannot create new socket\n"); return NULL; } if (!r_socket_connect_tcp (s, ptr, port, 30)) { eprintf ("Cannot connect to '%s' (%s)\n", ptr, port); return NULL; } else eprintf ("Connected to: %s at port %s\n", ptr, port); haret_wait_until_prompt (s); return r_io_desc_new (&r_io_plugin_haret, s->fd, pathname, rw, mode, (void*)s); } return NULL; }
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) { char *out; int rlen, code; if (__plugin_open (io, pathname, 0)) { RIOR2Web *mal = R_NEW0 (RIOR2Web); if (!mal) return NULL; char *url = r_str_newf ("http://%s/?V", pathname+8); //eprintf ("URL:(%s)\n", url); out = r_socket_http_get (url, &code, &rlen); //eprintf ("RES %d %d\n", code, rlen); //eprintf ("OUT(%s)\n", out); if (out && rlen>0) { mal->fd = getmalfd (mal); mal->url = r_str_newf ("http://%s", pathname+8); free (out); free (url); return r_io_desc_new (&r_io_plugin_r2web, mal->fd, pathname, rw, mode, mal); } free (url); free (mal); free (out); } return NULL; }
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) { R2Pipe *r2p = NULL; if (__check (io, pathname, 0)) { r2p = r2p_open (pathname + 9); } return r2p? r_io_desc_new (io, &r_io_plugin_r2pipe, pathname, rw, mode, r2p): NULL; }
// Below this line are the r_io_zip plugin APIs static RList *r_io_zip_open_many(RIO *io, const char *file, int rw, int mode) { RList *list_fds = NULL; RListIter *iter; RList *filenames = NULL; RIODesc *res = NULL; RIOZipFileObj *zfo = NULL; char *filename_in_zipfile, *zip_filename = NULL, *zip_uri; if (!r_io_zip_plugin_open (io, file, true)) { return NULL; } zip_uri = strdup (file); if (!zip_uri) { return NULL; } // 1) Tokenize to the '//' and find the base file directory ('/') zip_filename = strstr(zip_uri, "//"); if (zip_filename && zip_filename[2]) { if (zip_filename[0] && zip_filename[0] == '/' && zip_filename[1] && zip_filename[1] == '/' ) { *zip_filename++ = 0; } *zip_filename++ = 0; } else { free (zip_uri); return NULL; } filenames = r_io_zip_get_files(zip_filename, 0, mode, rw ); if (!filenames) { free (zip_uri); return NULL; } list_fds = r_list_new (); r_list_foreach (filenames, iter, filename_in_zipfile) { size_t v = strlen (filename_in_zipfile); if (filename_in_zipfile[v - 1] == '/') { continue; } zfo = r_io_zip_alloc_zipfileobj (zip_filename, filename_in_zipfile, ZIP_CREATE, mode, rw); if (zfo && zfo->entry == -1) { eprintf ("Warning: File did not exist, creating a new one.\n"); } if (zfo) { zfo->io_backref = io; res = r_io_desc_new (io, &r_io_plugin_zip, zfo->name, rw, mode, zfo); } r_list_append (list_fds, res); }
static RIODesc *r_io_def_mmap_open(RIO *io, const char *file, int flags, int mode) { const char* name = NULL; RIOMMapFileObj *mmo; name = file; mmo = r_io_def_mmap_create_new_file (io, name, mode, flags); if (!mmo) return NULL; return r_io_desc_new (&r_io_plugin_default, mmo->fd, mmo->filename, flags, mode, mmo); }
static RIODesc *r_io_mmap_open(RIO *io, const char *file, int flags, int mode) { const char* name = NULL; RIOMMapFileObj *mmo; name = !strncmp (file, "mmap://", 7) ? file+7 : file; mmo = r_io_mmap_create_new_file (io, name, mode, flags); if (!mmo) return NULL; return r_io_desc_new (&r_io_plugin_mmap, mmo->fd, mmo->filename, flags, mode, mmo); }
static RIODesc *__open(RIO *io, const char *file, int rw, int mode) { int ret, pid = getpid (); if (r_sandbox_enable (0)) return NULL; io->va = R_TRUE; // nop ret = update_self_regions (pid); if (ret) { return r_io_desc_new (&r_io_plugin_self, pid, file, rw, mode, NULL); } return NULL; }
static RIODesc* __open(RIO* io, const char* pathname, int rw, int mode) { RIONull* null; if (__plugin_open (io, pathname,0)) { if (!strncmp (pathname, "null://", 7) && strlen (pathname + 7)) { null = R_NEW0 (RIONull); null->size = r_num_math (NULL, pathname + 7) + 1; //??? null->offset = 0LL; return r_io_desc_new (io, &r_io_plugin_null, pathname, rw, mode, null); } } return NULL; }
static RIODesc *__open(RIO *io, const char *file, int rw, int mode) { RIODesc *ret = NULL; RIOMach *riom; const char *pidfile; char *pidpath, *endptr; int pid; task_t task; if (!__plugin_open (io, file, 0)) { return NULL; } pidfile = file + (file[0] == 'a' ? 9 : 7); pid = (int)strtol (pidfile, &endptr, 10); if (endptr == pidfile || pid < 0) { return NULL; } task = pid_to_task (pid); if (task == -1) { return NULL; } if (!task) { if (pid > 0 && io->referer && !strncmp (io->referer, "dbg://", 6)) { eprintf ("Child killed\n"); kill (pid, 9); } switch (errno) { case EPERM: eprintf ("Operation not permitted\n"); break; case EINVAL: perror ("ptrace: Cannot attach"); eprintf ("Possibly unsigned r2. Please see doc/osx.md\n"); eprintf ("ERRNO: %d (EINVAL)\n", errno); break; default: eprintf ("unknown error in debug_attach\n"); break; } return NULL; } riom = R_NEW0 (RIOMach); riom->pid = pid; riom->task = task; // sleep 1s to get proper path (program name instead of ls) (racy) pidpath = pid ? r_sys_pid_to_path (pid) : strdup ("kernel"); ret = r_io_desc_new (&r_io_plugin_mach, riom->pid, pidpath, rw | R_IO_EXEC, mode, riom); free (pidpath); return ret; }
static RIODesc *w32__open(RIO *io, const char *pathname, int rw, int mode) { if (!strncmp (pathname, "w32://", 6)) { RIOW32 *w32 = R_NEW0 (RIOW32); const char *filename = pathname+6; w32->hnd = CreateFileA (filename, GENERIC_READ | rw?GENERIC_WRITE:0, FILE_SHARE_READ | rw? FILE_SHARE_WRITE:0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (w32->hnd != INVALID_HANDLE_VALUE) return r_io_desc_new (io, &r_io_plugin_w32, pathname, rw, mode, w32); free (w32); } return NULL; }
R_API RIODesc *r_io_open(struct r_io_t *io, const char *file, int flags, int mode) { RIODesc *desc = NULL; int fd = -2; char *uri = strdup (file); struct r_io_plugin_t *plugin; if (!io) return NULL; for (;;) { plugin = r_io_plugin_resolve (io, uri); if (plugin && plugin->open) { desc = plugin->open (io, uri, flags, mode); if (io->redirect) { free ((void *)uri); uri = strdup (io->redirect); r_io_redirect (io, NULL); continue; } if (desc != NULL) { r_io_desc_add (io, desc); fd = desc->fd; if (fd != -1) r_io_plugin_open (io, fd, plugin); if (desc != io->fd) io->plugin = plugin; } } break; } if (fd == -2) { #if __WINDOWS__ if (flags & R_IO_WRITE) { fd = open (file, O_BINARY | 1); if (fd == -1) creat (file, O_BINARY); fd = open (file, O_BINARY | 1); } else fd = open (file, O_BINARY); #else fd = open (file, (flags&R_IO_WRITE)?O_RDWR:O_RDONLY, mode); #endif } if (fd >= 0) { if (desc == NULL) desc = r_io_desc_new (io->plugin, fd, file, flags, mode, NULL); r_io_desc_add (io, desc); r_io_set_fd (io, desc); } free ((void *)uri); return desc; }
R_API RIODesc *r_io_open(RIO *io, const char *file, int flags, int mode) { RIODesc *desc = __getioplugin (io, file, flags, mode); int fd; if (desc) { fd = desc->fd; } else { fd = __io_posix_open (io, file, flags, mode); if (fd>=0) desc = r_io_desc_new (io->plugin, fd, file, flags, mode, NULL); } if (fd >= 0) { r_io_desc_add (io, desc); r_io_set_fd (io, desc); } return desc; }
static RIODesc *shm__open(RIO *io, const char *pathname, int rw, int mode) { if (!memcmp (pathname, "shm://", 6)) { RIOShm *shm = R_NEW (RIOShm); const char *ptr = pathname+6; shm->id = getshmid (ptr); shm->buf = shmat (shm->id, 0, 0); shm->fd = getshmfd (shm); shm->size = SHMATSZ; if (shm->fd != -1) { eprintf ("Connected to shared memory 0x%08x\n", shm->id); return r_io_desc_new (&r_io_plugin_shm, shm->fd, pathname, rw, mode, shm); } eprintf ("Cannot connect to shared memory (%d)\n", shm->id); free (shm); } return NULL; }
static RIODesc *__open(RIO *io, const char *file, int rw, int mode) { RIODesc *ret = NULL; RIOMach *riom; const char *pidfile; char *pidpath; int pid; task_t task; if (!__plugin_open (io, file, 0)) return NULL; pidfile = file+(file[0]=='a'?9:7); if (!strcmp (pidfile, "0")) { /* tfp0 */ pid = 0; } else { pid = atoi (pidfile); if (pid<1) return NULL; } task = debug_attach (pid); if ((int)task == -1) { switch (errno) { case EPERM: eprintf ("Operation not permitted\n"); break; case EINVAL: perror ("ptrace: Cannot attach"); eprintf ("ERRNO: %d (EINVAL)\n", errno); break; default: eprintf ("unknown error in debug_attach\n"); break; } return NULL; } riom = R_NEW0 (RIOMach); riom->pid = pid; riom->task = task; // sleep 1s to get proper path (program name instead of ls) (racy) pidpath = r_sys_pid_to_path (pid); ret = r_io_desc_new (&r_io_plugin_mach, riom->pid, pidpath, rw | R_IO_EXEC, mode, riom); free (pidpath); return ret; }
static RIODesc *__open(RIO *io, const char *file, int rw, int mode) { char host[128], *port, *p; RSocket *_fd; RIOGdb *riog; if (!__plugin_open (io, file, 0)) return NULL; strncpy (host, file+6, sizeof (host)-1); port = strchr (host , ':'); if (!port) { eprintf ("Port not specified. Please use gdb://[host]:[port]\n"); return NULL; } *port = '\0'; port++; p = strchr (port, '/'); if (p) *p=0; if (r_sandbox_enable (0)) { eprintf ("sandbox: Cannot use network\n"); return NULL; } _fd = r_socket_new (R_FALSE); if (_fd && r_socket_connect_tcp (_fd, host, port, 3)) { riog = R_NEW (RIOGdb); riog->fd = _fd; riog->desc = gdbwrap_init (_fd->fd, NUM_REGS, 4); if (!riog->desc) { r_socket_free (_fd); free (riog); return NULL; } #if __WINDOWS__ // XXX: bypass lazylinking RETURN_IO_DESC_NEW (&r_io_plugin_gdb, _fd->fd, file, rw, mode, riog); #else return r_io_desc_new (&r_io_plugin_gdb, _fd->fd, file, rw, mode, riog); #endif } eprintf ("gdb.io.open: Cannot connect to host.\n"); return NULL; }
static RIODesc *__open(RIO *io, const char *file, int rw, int mode) { if (__plugin_open (io, file, 0)) { char *pidpath; RIODesc *ret; RIOW32Dbg *dbg = R_NEW0 (RIOW32Dbg); if (!dbg) { return NULL; } dbg->pid = atoi (file + 9); if (__open_proc (dbg, !strncmp (file, "attach://", 9)) == -1) { free (dbg); return NULL; } pidpath = r_sys_pid_to_path (dbg->pid); ret = r_io_desc_new (io, &r_io_plugin_w32dbg, file, rw | R_PERM_X, mode, dbg); ret->name = pidpath; return ret; } return NULL; }
static RIODesc *__open(struct r_io_t *io, const char *file, int rw, int mode) { char procpidpath[64]; int fd, ret = -1; if (__plugin_open (io, file,0)) { int pid = atoi (file+10); if (file[0]=='a') { ret = ptrace (PTRACE_ATTACH, pid, 0, 0); if (ret == -1) { switch (errno) { case EPERM: ret = pid; eprintf ("Operation not permitted\n"); break; case EINVAL: perror ("ptrace: Cannot attach"); eprintf ("ERRNO: %d (EINVAL)\n", errno); break; } } else if (__waitpid(pid)) ret = pid; else eprintf ("Error in waitpid\n"); } else ret = pid; fd = ret;//TODO: use r_io_fd api snprintf (procpidpath, sizeof (procpidpath), "/proc/%d/mem", pid); fd = open (procpidpath, O_RDWR); if (fd != -1) { RIOProcpid *riop = R_NEW (RIOProcpid); riop->pid = pid; riop->fd = fd; return r_io_desc_new (&r_io_plugin_procpid, -1, file, R_TRUE, 0, riop); } /* kill children */ eprintf ("Cannot open /proc/%d/mem of already attached process\n", pid); ptrace (PTRACE_DETACH, pid, 0, 0); } return NULL; }
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) { if (__plugin_open (io, pathname, 0)) { if (gs) { return NULL; } gs = r_socket_new (0); char *cmd = r_str_newf ("winedbg '%s'", pathname + 10); int res = r_socket_spawn (gs, cmd, 1000); free (cmd); if (!res) { return NULL; } char *reply = runcmd (NULL); if (reply) { int rw = 7; free (reply); eprintf ("Wine-dbg is ready to go!\n"); return r_io_desc_new (io, &r_io_plugin_winedbg, pathname, rw, mode, gs); } eprintf ("Can't find the Wine-dbg prompt\n"); } return NULL; }
static RIODesc *rap__open(RIO *io, const char *pathname, int rw, int mode) { int i, p, listenmode; char *file, *port; const char *ptr; RSocket *rap_fd; char buf[1024]; RIORap *rior; if (!rap__plugin_open (io, pathname, 0)) { return NULL; } bool is_ssl = (!strncmp (pathname, "raps://", 7)); ptr = pathname + (is_ssl? 7: 6); if (!(port = strchr (ptr, ':'))) { eprintf ("rap: wrong uri\n"); return NULL; } listenmode = (*ptr == ':'); *port++ = 0; if (!*port) { return NULL; } p = atoi (port); if ((file = strchr (port + 1, '/'))) { *file = 0; file++; } if (r_sandbox_enable (0)) { eprintf ("sandbox: Cannot use network\n"); return NULL; } if (listenmode) { if (p <= 0) { eprintf ("rap: cannot listen here. Try rap://:9999\n"); return NULL; } //TODO: Handle ^C signal (SIGINT, exit); // ??? eprintf ("rap: listening at port %s ssl %s\n", port, (is_ssl)?"on":"off"); rior = R_NEW0 (RIORap); rior->listener = true; rior->client = rior->fd = r_socket_new (is_ssl); if (!rior->fd) { free (rior); return NULL; } if (is_ssl) { if (file && *file) { if (!r_socket_listen (rior->fd, port, file)) { free (rior); return NULL; } } else { free (rior); return NULL; } } else { if (!r_socket_listen (rior->fd, port, NULL)) { return NULL; } } return r_io_desc_new (&r_io_plugin_rap, rior->fd->fd, pathname, rw, mode, rior); } if (!(rap_fd = r_socket_new (is_ssl))) { eprintf ("Cannot create new socket\n"); return NULL; } if (r_socket_connect_tcp (rap_fd, ptr, port, 30) == false) { eprintf ("Cannot connect to '%s' (%d)\n", ptr, p); r_socket_free (rap_fd); return NULL; } eprintf ("Connected to: %s at port %s\n", ptr, port); rior = R_NEW0 (RIORap); rior->listener = false; rior->client = rior->fd = rap_fd; if (file && *file) { // send buf[0] = RMT_OPEN; buf[1] = rw; buf[2] = (ut8)strlen (file); memcpy (buf + 3, file, buf[2]); r_socket_write (rap_fd, buf, buf[2] + 3); r_socket_flush (rap_fd); // read eprintf ("waiting... "); buf[0] = 0; r_socket_read_block (rap_fd, (ut8*)buf, 5); if (buf[0] != (char)(RMT_OPEN | RMT_REPLY)) { eprintf ("rap: Expecting OPEN|REPLY packet. got %02x\n", buf[0]); r_socket_free (rap_fd); free (rior); return NULL; } i = r_read_at_be32 (buf, 1); if (i > 0) { eprintf ("ok\n"); } #if 0 /* Read meta info */ r_socket_read (rap_fd, (ut8 *)&buf, 4); r_mem_copyendian ((ut8 *)&i, (ut8*)buf, 4, ENDIAN); while (i>0) { int n = r_socket_read (rap_fd, (ut8 *)&buf, i); if (n<1) break; buf[i] = 0; io->core_cmd_cb (io->user, buf); n = r_socket_read (rap_fd, (ut8 *)&buf, 4); if (n<1) break; r_mem_copyendian ((ut8 *)&i, (ut8*)buf, 4, ENDIAN); i -= n; } #endif } else { // r_socket_free (rap_fd); // free (rior); //return NULL; } //r_socket_free (rap_fd); return r_io_desc_new (&r_io_plugin_rap, rior->fd->fd, pathname, rw, mode, rior); }