* Implement rap:// remote radare protocol support
- Fully compatible with radare1 - Server $ r2 rap://:9999 - Client $ r2 rap://127.0.0.1:9999//etc/fstab * r_io has been refactorized to support client/server io plugins - Requires make clean * Enhacements in Visual mode: - [] keys change scr.cols eval variable (hex columns) - Handle offscreen cursor and selection - Handle <0 seeking in visual mode
This commit is contained in:
parent
5742b10641
commit
53587faf25
48
TODO
48
TODO
|
@ -6,9 +6,20 @@
|
|||
|
||||
Visual mode
|
||||
-----------
|
||||
- cursor mode by default? (imho no)
|
||||
- cursor can move outside screen (visual broken)
|
||||
- scrollup by bwdisasm not yet implemented
|
||||
* Add print support for bitfields (pb, pm b...)
|
||||
* For each "call" or "push offset"+"ret" create a function.
|
||||
- And, if deep code analysis is enabled:
|
||||
- Search every possible function by searching typical prologs and put them in a queue.
|
||||
- Perform the same actions as in the previous steps with the entry points.
|
||||
* Stolen from pyew
|
||||
- e anal.ops = true
|
||||
INT num: Interruptions. Typically used as antiemulation (INT 4) and antidebugging tricks (INT 3).
|
||||
UD2: Undefined instruction. Found in some packers/protectors as an antiemulation tricks.
|
||||
RDTSC: Widely used in malware to check if the software is being traced. A typical way to detect binary instrumentation (PIN, DynamoRIO, etc...).
|
||||
SIDT/SGDT: Store Interrupt/Global Descriptor Table. Trick used to detect some Virtual Machines (known as the red pill trick).
|
||||
CPUID: Used to detect Virtual Machines and emulators.
|
||||
// NOP args: NOP with arguments are typical antiemulation tricks.
|
||||
SYSENTER: Direct system calls. Commonly, used as antiemulation tricks.
|
||||
|
||||
* RAsmOp RAnalOp // Aop->Op
|
||||
* implement aoe = anal op exec
|
||||
|
@ -19,7 +30,6 @@ Visual mode
|
|||
pancake
|
||||
-------
|
||||
* Implement BLOCK in r_core_sysenv_begin|end ()
|
||||
* Fix r2 rap://:9999 and c2s comms
|
||||
* r2-swig : Distribute generated .i files and cxx files.. so build is faster
|
||||
- ./configure --without-valaswig # compile without generating cxx files
|
||||
- build with swig/
|
||||
|
@ -33,9 +43,20 @@ earada
|
|||
* Implement print Zoom mode (copypasta from r1) (useful for forensics) <-- MUST
|
||||
* mount /mnt/ must chop last '/'
|
||||
* test fatfs and others
|
||||
* Add SSL support to r_socket
|
||||
* remove all uses of alloca() // mingw and grep reports them all :)
|
||||
* typedef all function pointers, like in r_bp
|
||||
* Implement /A : search AES
|
||||
* Implement case-insensitive search (e search.casematters ?) any better name? Use /i?
|
||||
* Implement /. to search using a file .. isnt zignatures about this?
|
||||
* Implement /p to search for patterns
|
||||
- implement it in r_core ?? or add r_io_bind support
|
||||
* Implement search and replace /s
|
||||
- insert or append? (see r1 cfg vars)
|
||||
|
||||
nibble
|
||||
------
|
||||
* scrollup by bwdisasm not yet implemented
|
||||
* '+' key in visual cursor mode only increments lower nibble!
|
||||
- only in debugger mode :/
|
||||
* register renaming (per-instruction or ranges)
|
||||
|
@ -175,23 +196,6 @@ nibble
|
|||
2nd level:
|
||||
- basic block level diffing (output in graph mode)
|
||||
|
||||
earada
|
||||
------
|
||||
* Add SSL support to r_socket
|
||||
* r_file_slurp should work fine for big files (not prio) r_file_slurp_buf?
|
||||
- mmap if supported
|
||||
- add r_file_mmap ?
|
||||
- read file in blocks instead of the whole file in a single syscall
|
||||
* remove all uses of alloca() // mingw and grep reports them all :)
|
||||
* typedef all function pointers, like in r_bp
|
||||
* Implement /A : search AES
|
||||
* Implement case-insensitive search (e search.casematters ?) any better name? Use /i?
|
||||
* Implement /. to search using a file .. isnt zignatures about this?
|
||||
* Implement /p to search for patterns
|
||||
- implement it in r_core ?? or add r_io_bind support
|
||||
* Implement search and replace /s
|
||||
- insert or append? (see r1 cfg vars)
|
||||
|
||||
|
||||
Questions
|
||||
=========
|
||||
|
@ -243,6 +247,8 @@ Refactoring
|
|||
|
||||
Future
|
||||
======
|
||||
* r_file_slurp should work fine for big files (not prio) r_file_slurp_buf?
|
||||
- mmap if supported - add r_file_mmap ? - read file in blocks instead of the whole file in a single syscall
|
||||
* Realign flags when using project in debug mode
|
||||
* FileDescriptors: dd -- copy from !fd in r1
|
||||
* Initial analysis looking for xrefs to strings and so? ax? ./a@@entry0 - Launched at startup
|
||||
|
|
|
@ -173,8 +173,9 @@ int main(int argc, char **argv) {
|
|||
const char *prj = r_config_get (r.config, "file.project");
|
||||
if (prj && *prj) {
|
||||
char *file = r_core_project_info (&r, prj);
|
||||
if (file) fh = r_core_file_open (&r, file, perms);
|
||||
else eprintf ("No file\n");
|
||||
if (file) {
|
||||
fh = r_core_file_open (&r, file, perms);
|
||||
} else eprintf ("No file\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -247,8 +248,7 @@ int main(int argc, char **argv) {
|
|||
r_core_cmd (&r, "fo", 0);
|
||||
r_cons_flush ();
|
||||
}
|
||||
// read current block
|
||||
r_core_seek (&r, r.offset, 1);
|
||||
r_core_seek (&r, r.offset, 1); // read current block
|
||||
|
||||
/* XXX: find better solution.. files > 10MB does not hash */
|
||||
#define SLURP_LIMIT (10*1024*1024)
|
||||
|
@ -275,9 +275,6 @@ int main(int argc, char **argv) {
|
|||
if (cmdfile)
|
||||
r_core_cmd_file (&r, cmdfile);
|
||||
|
||||
if (r_io_is_listener (r.io)) {
|
||||
r_core_serve (&r, r.io->fd);
|
||||
} else
|
||||
for (;;) {
|
||||
do {
|
||||
if (r_core_prompt (&r, R_FALSE)<1)
|
||||
|
|
|
@ -58,7 +58,7 @@ R_API const char *r_config_get(RConfig *cfg, const char *name) {
|
|||
return (const char *)
|
||||
(((!strcmp("true", node->value))
|
||||
|| (!strcmp("1", node->value)))?
|
||||
(char *)1:NULL); // XXX (char*)1 is ugly
|
||||
(const char *)"true":"false"); // XXX (char*)1 is ugly
|
||||
return node->value;
|
||||
}
|
||||
cfg->last_notfound = 1;
|
||||
|
|
|
@ -337,7 +337,7 @@ R_API int r_core_config_init(RCore *core) {
|
|||
r_config_set (cfg, "asm.linesout", "true");
|
||||
r_config_set (cfg, "asm.linesstyle", "false");
|
||||
r_config_set (cfg, "asm.lineswide", "false");
|
||||
r_config_set_i_cb (cfg, "asm.lineswidth", 0, &config_asmlineswidth_callback);
|
||||
r_config_set_i_cb (cfg, "asm.lineswidth", 10, &config_asmlineswidth_callback);
|
||||
r_config_set (cfg, "asm.linescall", "false");
|
||||
r_config_set (cfg, "asm.offset", "true");
|
||||
r_config_set_cb (cfg, "asm.os", R_SYS_OS, &config_asmos_callback);
|
||||
|
|
|
@ -406,13 +406,14 @@ R_API int r_core_serve(RCore *core, RIODesc *file) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
eprintf ("RAP Server running\n");
|
||||
eprintf ("RAP Server started (rap.loop=%s)\n", r_config_get (core->config, "rap.loop"));
|
||||
#if __UNIX__
|
||||
// XXX: ugly workaround
|
||||
signal (SIGINT, SIG_DFL);
|
||||
signal (SIGPIPE, SIG_DFL);
|
||||
#endif
|
||||
reaccept:
|
||||
core->io->plugin = NULL;
|
||||
while ((c = r_socket_accept (fd))) {
|
||||
if (c == -1) {
|
||||
eprintf ("rap: cannot accept\n");
|
||||
|
@ -421,13 +422,15 @@ reaccept:
|
|||
}
|
||||
|
||||
eprintf ("rap: client connected\n");
|
||||
|
||||
r_io_accept (core->io, c);
|
||||
for (;;) {
|
||||
i = r_socket_read (c, &cmd, 1);
|
||||
if (i==0) {
|
||||
eprintf ("rap: connection closed\n");
|
||||
if (r_config_get_i (core->config, "rap.loop"))
|
||||
if (r_config_get_i (core->config, "rap.loop")) {
|
||||
eprintf ("rap: waiting for new connection\n");
|
||||
goto reaccept;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -225,6 +225,10 @@ R_API RCoreFile *r_core_file_open(RCore *r, const char *file, int mode) {
|
|||
RIODesc *fd = r_io_open (r->io, file, mode, 0644);
|
||||
if (fd == NULL)
|
||||
return NULL;
|
||||
if (r_io_is_listener (r->io)) {
|
||||
r_core_serve (r, r->io->fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fh = R_NEW (RCoreFile);
|
||||
fh->fd = fd;
|
||||
|
|
|
@ -770,13 +770,6 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
|
|||
}
|
||||
r_cons_set_raw(1);
|
||||
break;
|
||||
/* select */
|
||||
case 'H':
|
||||
if (curset) {
|
||||
if (ocursor==-1) ocursor=cursor;
|
||||
cursor--;
|
||||
} else r_core_cmd (core, "s-2", 0);
|
||||
break;
|
||||
case 'e':
|
||||
r_core_visual_config (core);
|
||||
break;
|
||||
|
@ -786,12 +779,6 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
|
|||
case 'v':
|
||||
r_core_visual_anal (core);
|
||||
break;
|
||||
case 'J':
|
||||
if (curset) {
|
||||
if (ocursor==-1) ocursor = cursor;
|
||||
cursor += cols;
|
||||
} else r_core_cmd (core, "s++", 0);
|
||||
break;
|
||||
case 'g':
|
||||
r_core_cmd (core, "s 0", 0);
|
||||
break;
|
||||
|
@ -800,64 +787,129 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
|
|||
r_io_sundo_push (core->io);
|
||||
//r_core_cmd(core, "s 0", 0);
|
||||
break;
|
||||
case 'K':
|
||||
if (curset) {
|
||||
if (ocursor==-1) ocursor=cursor;
|
||||
cursor -= cols;
|
||||
} else r_core_cmd (core, "s--", 0);
|
||||
break;
|
||||
case 'L':
|
||||
if (curset) {
|
||||
if (ocursor==-1) ocursor=cursor;
|
||||
cursor++;
|
||||
} else r_core_cmd (core, "s+2", 0);
|
||||
break;
|
||||
/* move */
|
||||
case 'h':
|
||||
if (curset) {
|
||||
cursor--;
|
||||
ocursor=-1;
|
||||
if (cursor<0) {
|
||||
r_core_seek (core, core->offset-cols, 1);
|
||||
cursor ++;
|
||||
}
|
||||
} else r_core_cmd (core, "s-1", 0);
|
||||
break;
|
||||
case 'H':
|
||||
if (curset) {
|
||||
if (ocursor==-1) ocursor=cursor;
|
||||
cursor--;
|
||||
if (cursor<0) {
|
||||
r_core_seek (core, core->offset-cols, 1);
|
||||
cursor += cols;
|
||||
ocursor += cols;
|
||||
}
|
||||
} else r_core_cmd (core, "s-2", 0);
|
||||
break;
|
||||
case 'l':
|
||||
if (curset) {
|
||||
cursor++;
|
||||
ocursor=-1;
|
||||
{
|
||||
int offscreen = (core->cons->rows-3)*cols;
|
||||
if (cursor>=offscreen) {
|
||||
r_core_seek (core, core->offset+cols, 1);
|
||||
cursor-=cols;
|
||||
}
|
||||
}
|
||||
} else r_core_cmd (core, "s+1", 0);
|
||||
break;
|
||||
case 'u':
|
||||
if (r_io_sundo (core->io))
|
||||
r_core_seek (core, core->io->off, 1);
|
||||
break;
|
||||
case 'U':
|
||||
if (r_io_sundo_redo (core->io))
|
||||
r_core_seek (core, core->io->off, 1);
|
||||
case 'L':
|
||||
if (curset) {
|
||||
if (ocursor==-1) ocursor=cursor;
|
||||
cursor++;
|
||||
{
|
||||
int offscreen = (core->cons->rows-3)*cols;
|
||||
if (cursor>=offscreen) {
|
||||
r_core_seek (core, core->offset+cols, 1);
|
||||
cursor-=cols;
|
||||
ocursor-=cols;
|
||||
}
|
||||
}
|
||||
} else r_core_cmd (core, "s+2", 0);
|
||||
break;
|
||||
case 'j':
|
||||
// r_asm_disassemble (core->assembler, &aop, core->block, 32);
|
||||
if (curset) {
|
||||
if (printidx == 1)
|
||||
cols = r_asm_disassemble (core->assembler, &aop, core->block, 32);
|
||||
cursor += cols;
|
||||
ocursor = -1;
|
||||
{
|
||||
int offscreen = (core->cons->rows-3)*cols;
|
||||
if (cursor>=offscreen) {
|
||||
r_core_seek (core, core->offset+cols, 1);
|
||||
cursor-=cols;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (printidx == 1)
|
||||
cols = core->inc;
|
||||
r_core_seek (core, core->offset+cols, 1);
|
||||
}
|
||||
break;
|
||||
case 'J':
|
||||
if (curset) {
|
||||
if (ocursor==-1) ocursor = cursor;
|
||||
cursor += cols;
|
||||
{
|
||||
int offscreen = (core->cons->rows-3)*cols;
|
||||
if (cursor>=offscreen) {
|
||||
r_core_seek (core, core->offset+cols, 1);
|
||||
cursor-=cols;
|
||||
ocursor-=cols;
|
||||
}
|
||||
}
|
||||
} else r_core_cmd (core, "s++", 0);
|
||||
break;
|
||||
case 'k':
|
||||
if (curset) {
|
||||
if (printidx == 1)
|
||||
cols = r_asm_disassemble (core->assembler, &aop, core->block, 32);
|
||||
cursor -= cols;
|
||||
if (cursor<0 && cols<core->offset) {
|
||||
r_core_seek (core, core->offset-cols, 1);
|
||||
cursor += cols;
|
||||
}
|
||||
ocursor = -1;
|
||||
} else {
|
||||
if (printidx == 1)
|
||||
cols = core->inc;
|
||||
if (cols>core->offset)
|
||||
r_core_seek (core, core->offset-cols, 1);
|
||||
}
|
||||
break;
|
||||
case 'K':
|
||||
if (curset) {
|
||||
if (ocursor==-1) ocursor=cursor;
|
||||
cursor -= cols;
|
||||
if (cursor<0 && cols<core->offset) {
|
||||
r_core_seek (core, core->offset-cols, 1);
|
||||
cursor += cols;
|
||||
ocursor += cols;
|
||||
}
|
||||
} else r_core_cmd (core, "s--", 0);
|
||||
break;
|
||||
case '[':
|
||||
{
|
||||
int scrcols = r_config_get_i (core->config, "scr.cols");
|
||||
if (scrcols>2)
|
||||
r_config_set_i (core->config, "scr.cols", scrcols-2);
|
||||
}
|
||||
break;
|
||||
case ']':
|
||||
{
|
||||
int scrcols = r_config_get_i (core->config, "scr.cols");
|
||||
//if (scrcols<32)
|
||||
r_config_set_i (core->config, "scr.cols", scrcols+2);
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
r_core_cmd (core, "ds", 0);
|
||||
r_core_cmd (core, ".dr*", 0);
|
||||
|
@ -957,6 +1009,14 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
|
|||
obs = core->blocksize;
|
||||
else r_core_block_size (core, obs);
|
||||
break;
|
||||
case 'u':
|
||||
if (r_io_sundo (core->io))
|
||||
r_core_seek (core, core->io->off, 1);
|
||||
break;
|
||||
case 'U':
|
||||
if (r_io_sundo_redo (core->io))
|
||||
r_core_seek (core, core->io->off, 1);
|
||||
break;
|
||||
case 'x':
|
||||
r_core_cmdf (core, "./a 0x%08llx @ entry0", core->offset);
|
||||
break;
|
||||
|
@ -998,7 +1058,10 @@ R_API void r_core_visual_prompt(RCore *core, int color) {
|
|||
if (autoblocksize)
|
||||
switch (printidx) {
|
||||
case 0:
|
||||
r_core_block_size (core, core->cons->rows * 16);
|
||||
{
|
||||
int scrcols = r_config_get_i (core->config, "scr.cols");
|
||||
r_core_block_size (core, core->cons->rows * scrcols);
|
||||
}
|
||||
break;
|
||||
case 1: // pd
|
||||
case 2: // pd+dbg
|
||||
|
|
|
@ -122,6 +122,7 @@ typedef struct r_io_plugin_t {
|
|||
int (*write)(RIO *io, RIODesc *fd, const ut8 *buf, int count);
|
||||
int (*close)(RIODesc *desc);
|
||||
int (*resize)(RIO *io, RIODesc *fd, ut64 size);
|
||||
int (*accept)(RIO *io, RIODesc *desc, int fd);
|
||||
int (*plugin_open)(RIO *io, const char *);
|
||||
//int (*plugin_fd)(RIO *, int);
|
||||
} RIOPlugin;
|
||||
|
@ -199,6 +200,7 @@ R_API int r_io_system(RIO *io, const char *cmd);
|
|||
R_API int r_io_close(RIO *io, RIODesc *fd);
|
||||
R_API ut64 r_io_size(RIO *io); //, int fd);
|
||||
R_API int r_io_resize(struct r_io_t *io, ut64 newsize);
|
||||
R_API int r_io_accept(RIO *io, int fd);
|
||||
|
||||
/* io/cache.c */
|
||||
R_API void r_io_cache_commit(RIO *io);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - LGPL - Copyright 2009-2010 pancake<nopcode.org> */
|
||||
/* radare - LGPL - Copyright 2009-2011 pancake<nopcode.org> */
|
||||
|
||||
#include <r_io.h>
|
||||
// TODO: to be deprecated.. this is slow and boring
|
||||
|
|
14
libr/io/io.c
14
libr/io/io.c
|
@ -110,9 +110,7 @@ R_API RIODesc *r_io_open(struct r_io_t *io, const char *file, int flags, int mod
|
|||
fd = open (file, 1);
|
||||
} else fd = open (file, 0);
|
||||
#else
|
||||
if (flags & R_IO_WRITE)
|
||||
fd = open (file, O_RDWR, mode);
|
||||
else fd = open (file, O_RDONLY, mode);
|
||||
fd = open (file, (flags&R_IO_WRITE)?O_RDWR:O_RDONLY, mode);
|
||||
#endif
|
||||
}
|
||||
if (fd >= 0) {
|
||||
|
@ -321,6 +319,8 @@ R_API ut64 r_io_seek(struct r_io_t *io, ut64 offset, int whence) {
|
|||
|
||||
R_API ut64 r_io_size(RIO *io) {
|
||||
ut64 size, here;
|
||||
if (r_io_is_listener (io))
|
||||
return UT64_MAX;
|
||||
//r_io_set_fdn (io, fd);
|
||||
here = r_io_seek (io, 0, R_IO_SEEK_CUR);
|
||||
size = r_io_seek (io, 0, R_IO_SEEK_END);
|
||||
|
@ -360,3 +360,11 @@ R_API int r_io_bind(RIO *io, RIOBind *bnd) {
|
|||
//bnd->fd = io->fd;// do we need to store ptr to fd??
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
R_API int r_io_accept(RIO *io, int fd) {
|
||||
if (r_io_is_listener (io)) {
|
||||
if (io->plugin->accept)
|
||||
return io->plugin->accept (io, io->fd, fd);
|
||||
}
|
||||
return R_FALSE;
|
||||
}
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
#define ENDIAN (0)
|
||||
typedef struct {
|
||||
int fd;
|
||||
int client;
|
||||
int listener;
|
||||
} RIORap;
|
||||
#define RIORAP_FD(x) (((RIORap*)(x->data))->fd)
|
||||
#define RIORAP_FD(x) ((x->data)?(((RIORap*)(x->data))->client):-1)
|
||||
#define RIORAP_IS_LISTEN(x) (((RIORap*)(x->data))->listener)
|
||||
#define RIORAP_IS_VALID(x) ((x) && (x->data) && (x->plugin == &r_io_plugin_rap))
|
||||
|
||||
|
@ -42,6 +43,15 @@ static int rap__write(struct r_io_t *io, RIODesc *fd, const ut8 *buf, int count)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int rap__accept(RIO *io, RIODesc *desc, int fd) {
|
||||
RIORap *rap = desc->data;
|
||||
if (rap) {
|
||||
rap->client = fd;
|
||||
return R_TRUE;
|
||||
}
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
static int rap__read(struct r_io_t *io, RIODesc *fd, ut8 *buf, int count) {
|
||||
int ret;
|
||||
int i = (int)count;
|
||||
|
@ -57,7 +67,8 @@ static int rap__read(struct r_io_t *io, RIODesc *fd, ut8 *buf, int count) {
|
|||
// recv
|
||||
ret = r_socket_read (RIORAP_FD (fd), tmp, 5);
|
||||
if (ret != 5 || tmp[0] != (RMT_READ|RMT_REPLY)) {
|
||||
eprintf ("rap__read: Unexpected rap read reply (0x%02x)\n", tmp[0]);
|
||||
eprintf ("rap__read: Unexpected rap read reply (%d=0x%02x) expected (%d=0x%02x)\n",
|
||||
ret, tmp[0], 2, (RMT_READ|RMT_REPLY));
|
||||
return -1;
|
||||
}
|
||||
r_mem_copyendian ((ut8*)&i, tmp+1, 4, ENDIAN);
|
||||
|
@ -66,9 +77,9 @@ static int rap__read(struct r_io_t *io, RIODesc *fd, ut8 *buf, int count) {
|
|||
return -1;
|
||||
}
|
||||
r_socket_read_block (RIORAP_FD (fd), buf, i);
|
||||
if (count>0 && count<RMT_MAX)
|
||||
eprintf ("READ %d\n" ,i);
|
||||
else count = 0;
|
||||
if (count>0 && count<RMT_MAX) {
|
||||
//eprintf ("READ %d\n" ,i);
|
||||
} else count = 0;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -140,7 +151,7 @@ static RIODesc *rap__open(struct r_io_t *io, const char *pathname, int rw, int m
|
|||
eprintf ("rap: listening at port %d\n", p);
|
||||
rior = R_NEW (RIORap);
|
||||
rior->listener = R_TRUE;
|
||||
rior->fd = r_socket_listen (p);
|
||||
rior->client = rior->fd = r_socket_listen (p);
|
||||
// TODO: listen mode is broken.. here must go the root loop!!
|
||||
#warning TODO: implement rap:/:9999 listen mode
|
||||
return r_io_desc_new (&r_io_plugin_rap, rior->fd, pathname, rw, mode, rior);
|
||||
|
@ -152,7 +163,7 @@ static RIODesc *rap__open(struct r_io_t *io, const char *pathname, int rw, int m
|
|||
eprintf ("Connected to: %s at port %d\n", ptr, p);
|
||||
rior = R_NEW (RIORap);
|
||||
rior->listener = R_FALSE;
|
||||
rior->fd = rap_fd;
|
||||
rior->client = rior->fd = rap_fd;
|
||||
if (file && *file) {
|
||||
// send
|
||||
buf[0] = RMT_OPEN;
|
||||
|
@ -224,6 +235,7 @@ struct r_io_plugin_t r_io_plugin_rap = {
|
|||
.lseek = rap__lseek,
|
||||
.system = rap__system,
|
||||
.write = rap__write,
|
||||
.accept = rap__accept,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
|
|
Loading…
Reference in New Issue