static int rap__write(RIO *io, RIODesc *fd, const ut8 *buf, int count) { RSocket *s = RIORAP_FD (fd); ut8 *tmp; int ret; if (count < 1) { return count; } // TOOD: if count > RMT_MAX iterate ! if (count > RMT_MAX) { count = RMT_MAX; } if (!(tmp = (ut8 *)malloc (count + 5))) { eprintf ("rap__write: malloc failed\n"); return -1; } tmp[0] = RMT_WRITE; r_write_be32 (tmp + 1, count); memcpy (tmp + 5, buf, count); ret = r_socket_write (s, tmp, count + 5); r_socket_flush (s); if (r_socket_read (s, tmp, 5) != 5) { // TODO read_block? eprintf ("rap__write: error\n"); ret = -1; } else { ret = r_read_be32 (tmp + 1); if (!ret) { ret = -1; } } free (tmp); return ret; }
static int rap__read(RIO *io, RIODesc *fd, ut8 *buf, int count) { RSocket *s = RIORAP_FD (fd); int ret, i = (int)count; ut8 tmp[5]; // XXX. if count is > RMT_MAX, just perform multiple queries if (count > RMT_MAX) { count = RMT_MAX; } // send tmp[0] = RMT_READ; r_write_be32 (tmp + 1, count); r_socket_write (s, tmp, 5); r_socket_flush (s); // recv ret = r_socket_read_block (s, tmp, 5); if (ret != 5 || tmp[0] != (RMT_READ | RMT_REPLY)) { 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; } i = r_read_at_be32 (tmp, 1); if (i >count) { eprintf ("rap__read: Unexpected data size %d\n", i); return -1; } r_socket_read_block (s, buf, i); return count; }
static int rap__read(struct r_io_t *io, RIODesc *fd, ut8 *buf, int count) { RSocket *s = RIORAP_FD (fd); int ret; int i = (int)count; ut8 tmp[5]; if (count>RMT_MAX) count = RMT_MAX; // send tmp[0] = RMT_READ; r_mem_copyendian (tmp+1, (ut8*)&count, 4, ENDIAN); r_socket_write (s, tmp, 5); r_socket_flush (s); // recv ret = r_socket_read_block (s, tmp, 5); if (ret != 5 || tmp[0] != (RMT_READ|RMT_REPLY)) { 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); if (i>count) { eprintf ("rap__read: Unexpected data size %d\n", i); return -1; } r_socket_read_block (s, buf, i); return count; }
static int rap__system(RIO *io, RIODesc *fd, const char *command) { RSocket *s = RIORAP_FD (fd); ut8 buf[RMT_MAX]; char *ptr; int op, ret, i, j = 0; // send if (*command=='!') { op = RMT_SYSTEM; command++; } else op = RMT_CMD; buf[0] = op; i = strlen (command)+1; if (i>RMT_MAX) { eprintf ("Command too long\n"); return -1; } r_mem_copyendian (buf+1, (ut8*)&i, 4, ENDIAN); memcpy (buf+5, command, i); r_socket_write (s, buf, i+5); r_socket_flush (s); // read ret = r_socket_read_block (s, buf, 5); if (ret != 5) return -1; if (buf[0] != (op | RMT_REPLY)) { eprintf ("Unexpected system reply\n"); return -1; } r_mem_copyendian ((ut8*)&i, buf+1, 4, ENDIAN); if (i == -1) return -1; ret = 0; ptr = (char *)malloc (i); if (ptr) { int ir, tr = 0; do { ir = r_socket_read_block (s, (ut8*)ptr+tr, i-tr); if (ir>0) tr += ir; else break; } while (tr<i); // TODO: use io->printf() with support for \x00 ptr[i] = 0; if (io->printf) { io->printf ("%s", ptr); j = i; } else j = write (1, ptr, i); free (ptr); } /* Clean */ if (ret > 0) { ret -= r_socket_read (s, (ut8*)buf, RMT_MAX); } return i-j; }
static int rap__system(RIO *io, RIODesc *fd, const char *command) { RSocket *s = RIORAP_FD (fd); ut8 buf[RMT_MAX]; char *ptr; int op, ret, i, j = 0; // send if (*command=='!') { op = RMT_SYSTEM; command++; } else op = RMT_CMD; buf[0] = op; i = strlen (command); if (i>RMT_MAX) { eprintf ("Command too long\n"); return -1; } r_mem_copyendian (buf+1, (ut8*)&i, 4, ENDIAN); memcpy (buf+5, command, i); r_socket_write (s, buf, i+5); r_socket_flush (s); // read ret = r_socket_read_block (s, buf, 5); if (ret != 5) return -1; if (buf[0] != (op | RMT_REPLY)) { eprintf ("Unexpected system reply\n"); return -1; } r_mem_copyendian ((ut8*)&i, buf+1, 4, ENDIAN); if (i == -1) return -1; ret = 0; if (i>RMT_MAX) { ret = i-RMT_MAX; i = RMT_MAX; } ptr = (char *)malloc (i); if (ptr) { r_socket_read_block (s, (ut8*)ptr, i); j = write (1, ptr, i); free (ptr); } /* Clean */ if (ret > 0) { ret -= r_socket_read (s, (ut8*)buf, RMT_MAX); } return i-j; }
static ut64 rap__lseek(struct r_io_t *io, RIODesc *fd, ut64 offset, int whence) { RSocket *s = RIORAP_FD (fd); int ret; ut8 tmp[10]; // query tmp[0] = RMT_SEEK; tmp[1] = (ut8)whence; r_mem_copyendian (tmp+2, (ut8*)&offset, 8, ENDIAN); r_socket_write (s, &tmp, 10); r_socket_flush (s); // get reply ret = r_socket_read_block (s, (ut8*)&tmp, 9); if (ret!=9) return -1; if (tmp[0] != (RMT_SEEK | RMT_REPLY)) { eprintf ("Unexpected lseek reply\n"); return -1; } r_mem_copyendian ((ut8 *)&offset, tmp+1, 8, !ENDIAN); return offset; }
static ut64 rap__lseek(RIO *io, RIODesc *fd, ut64 offset, int whence) { RSocket *s = RIORAP_FD (fd); ut8 tmp[10]; int ret; // query tmp[0] = RMT_SEEK; tmp[1] = (ut8)whence; r_write_be64 (tmp + 2, offset); r_socket_write (s, &tmp, 10); r_socket_flush (s); // get reply memset (tmp, 0, 9); ret = r_socket_read_block (s, (ut8*)&tmp, 9); if (ret != 9 || tmp[0] != (RMT_SEEK | RMT_REPLY)) { // eprintf ("%d %d - %02x %02x %02x %02x %02x %02x %02x\n", // ret, whence, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6]); eprintf ("Unexpected lseek reply\n"); return -1; } offset = r_read_at_be64 (tmp, 1); return offset; }
static int rap__write(struct r_io_t *io, RIODesc *fd, const ut8 *buf, int count) { RSocket *s = RIORAP_FD (fd); int ret; ut8 *tmp; if (count>RMT_MAX) count = RMT_MAX; if (!(tmp = (ut8 *)malloc (count+5))) { eprintf ("rap__write: malloc failed\n"); return -1; } tmp[0] = RMT_WRITE; r_mem_copyendian ((ut8 *)tmp+1, (ut8*)&count, 4, ENDIAN); memcpy (tmp+5, buf, count); ret = r_socket_write (s, tmp, count+5); r_socket_flush (s); if (r_socket_read (s, tmp, 5) != 5) { // TODO read_block? eprintf ("rap__write: error\n"); ret = -1; } free (tmp); // TODO: get reply return ret; }
static int rap__system(RIO *io, RIODesc *fd, const char *command) { int ret, reslen = 0, cmdlen = 0; RSocket *s = RIORAP_FD (fd); unsigned int i, j = 0; char *ptr, *res, *str; ut8 buf[RMT_MAX]; buf[0] = RMT_CMD; i = strlen (command) + 1; if (i > RMT_MAX - 5) { eprintf ("Command too long\n"); return -1; } r_write_be32 (buf + 1, i); memcpy (buf + 5, command, i); r_socket_write (s, buf, i+5); r_socket_flush (s); /* read reverse cmds */ for (;;) { ret = r_socket_read_block (s, buf, 1); if (ret != 1) { return -1; } /* system back in the middle */ /* TODO: all pkt handlers should check for reverse queries */ if (buf[0] != RMT_CMD) { break; } // run io->cmdstr // return back the string buf[0] |= RMT_REPLY; memset (buf + 1, 0, 4); ret = r_socket_read_block (s, buf + 1, 4); cmdlen = r_read_at_be32 (buf, 1); if (cmdlen + 1 == 0) // check overflow cmdlen = 0; str = calloc (1, cmdlen + 1); ret = r_socket_read_block (s, (ut8*)str, cmdlen); eprintf ("RUN %d CMD(%s)\n", ret, str); if (str && *str) { res = io->cb_core_cmdstr (io->user, str); } else { res = strdup (""); } eprintf ("[%s]=>(%s)\n", str, res); reslen = strlen (res); free (str); r_write_be32 (buf + 1, reslen); memcpy (buf + 5, res, reslen); free (res); r_socket_write (s, buf, reslen + 5); r_socket_flush (s); } // read ret = r_socket_read_block (s, buf + 1, 4); if (ret != 4) { return -1; } if (buf[0] != (RMT_CMD | RMT_REPLY)) { eprintf ("Unexpected rap cmd reply\n"); return -1; } i = r_read_at_be32 (buf, 1); ret = 0; if (i > ST32_MAX) { eprintf ("Invalid length\n"); return -1; } ptr = (char *)calloc (1, i + 1); if (ptr) { int ir, tr = 0; do { ir = r_socket_read_block (s, (ut8*)ptr + tr, i - tr); if (ir < 1) break; tr += ir; } while (tr < i); // TODO: use io->cb_printf() with support for \x00 ptr[i] = 0; if (io->cb_printf) { io->cb_printf ("%s", ptr); j = i; } else { j = write (1, ptr, i); } free (ptr); } #if DEAD_CODE /* Clean */ if (ret > 0) { ret -= r_socket_read (s, (ut8*)buf, RMT_MAX); } #endif return i - j; }
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); }
static int rap__system(RIO *io, RIODesc *fd, const char *command) { RSocket *s = RIORAP_FD (fd); ut8 buf[RMT_MAX]; char *ptr; int op, ret; unsigned int i, j = 0; // send if (*command=='!') { op = RMT_SYSTEM; command++; } else { op = RMT_CMD; } buf[0] = op; i = strlen (command)+1; if (i>RMT_MAX-5) { eprintf ("Command too long\n"); return -1; } r_mem_copyendian (buf+1, (ut8*)&i, 4, ENDIAN); memcpy (buf+5, command, i); r_socket_write (s, buf, i+5); r_socket_flush (s); /* read reverse cmds */ for (;;) { ret = r_socket_read_block (s, buf, 1); if (ret != 1) { return -1; } /* system back in the middle */ /* TODO: all pkt handlers should check for reverse queries */ if (buf[0] == RMT_SYSTEM || buf[0] == RMT_CMD) { char *res, *str; ut32 reslen = 0, cmdlen = 0; // run io->cmdstr // return back the string buf[0] |= RMT_REPLY; ret = r_socket_read_block (s, buf+1, 4); r_mem_copyendian ((ut8*)&cmdlen, buf+1, 4, ENDIAN); if (cmdlen+1==0) // check overflow cmdlen = 0; str = calloc (1, cmdlen+1); ret = r_socket_read_block (s, (ut8*)str, cmdlen); //eprintf ("RUN CMD(%s)\n", str); res = io->cb_core_cmdstr (io->user, str); eprintf ("[%s]=>(%s)\n", str, res); reslen = strlen (res); free (str); r_mem_copyendian ((ut8*)buf+1, (const ut8*)&reslen, sizeof(ut32), ENDIAN); memcpy (buf+5, res, reslen); free (res); r_socket_write (s, buf, 5+reslen); r_socket_flush (s); } else { break; } } // read ret = r_socket_read_block (s, buf+1, 4); if (ret != 4) return -1; if (buf[0] != (op | RMT_REPLY)) { eprintf ("Unexpected system reply\n"); return -1; } r_mem_copyendian ((ut8*)&i, buf+1, 4, ENDIAN); ret = 0; if (i>0xffffffff) { eprintf ("Invalid length\n"); return -1; } ptr = (char *)malloc (i+1); if (ptr) { int ir; unsigned int tr = 0; do { ir = r_socket_read_block (s, (ut8*)ptr+tr, i-tr); if (ir>0) tr += ir; else break; } while (tr<i); // TODO: use io->cb_printf() with support for \x00 ptr[i] = 0; if (io->cb_printf) { io->cb_printf ("%s", ptr); j = i; } else j = write (1, ptr, i); free (ptr); } /* Clean */ if (ret > 0) { ret -= r_socket_read (s, (ut8*)buf, RMT_MAX); } return i-j; }
R_API int r_socket_rap_server_continue (RSocketRapServer *rap_s) { int endian, i, pipe_fd, ret; ut64 offset; char *ptr = NULL; if ( !rap_s || !rap_s->fd || !r_socket_is_connected (rap_s->fd)) return R_FALSE; r_socket_read_block (rap_s->fd, rap_s->buf, 1); endian = getEndian(); ret = rap_s->buf[0]; switch (rap_s->buf[0]) { case RAP_RMT_OPEN: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 2); r_socket_read_block (rap_s->fd, &rap_s->buf[3], (int)rap_s->buf[2]); rap_s->open (rap_s->user, (const char *)&rap_s->buf[3], (int)rap_s->buf[1], 0); rap_s->buf[0] = RAP_RMT_OPEN | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 5); r_socket_flush (rap_s->fd); break; case RAP_RMT_READ: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4); r_mem_copyendian ((ut8*)&i, &rap_s->buf[1], 4, !endian); if (i > RAP_RMT_MAX || i < 0) i = RAP_RMT_MAX; rap_s->read (rap_s->user, &rap_s->buf[5], i); rap_s->buf[0] = RAP_RMT_READ | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, i + 5); r_socket_flush (rap_s->fd); break; case RAP_RMT_WRITE: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4); r_mem_copyendian ((ut8*)&i, &rap_s->buf[1], 4, !endian); if (i > RAP_RMT_MAX || i < 0) i = RAP_RMT_MAX; r_socket_read_block (rap_s->fd, &rap_s->buf[5], i); rap_s->write(rap_s->user, &rap_s->buf[5], i); rap_s->buf[0] = RAP_RMT_WRITE | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 1); r_socket_flush (rap_s->fd); break; case RAP_RMT_SEEK: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 9); i = rap_s->buf[1]; r_mem_copyendian ((ut8*)&offset, &rap_s->buf[2], 8, !endian); rap_s->seek (rap_s->user, offset, i); rap_s->buf[0] = RAP_RMT_WRITE | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 1); r_socket_flush (rap_s->fd); break; case RAP_RMT_SYSTEM: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4); r_mem_copyendian ((ut8 *)&i, &rap_s->buf[1], 4, !endian); r_socket_read_block (rap_s->fd, &rap_s->buf[5], i); ptr = rap_s->system (rap_s->user, &rap_s->buf[5]); if (ptr) i = strlen (ptr) + 1; else i = 0; r_mem_copyendian (&rap_s->buf[1], (ut8 *)&i, 4, !endian); rap_s->buf[0] = RAP_RMT_SYSTEM | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 5); if (i) r_socket_write (rap_s->fd, ptr, i); r_socket_flush (rap_s->fd); free (ptr); ptr = NULL; break; case RAP_RMT_CMD: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4); r_mem_copyendian ((ut8 *)&i, &rap_s->buf[1], 4, !endian); r_socket_read_block (rap_s->fd, &rap_s->buf[5], i); ptr = rap_s->cmd (rap_s->user, &rap_s->buf[5]); if (ptr) i = strlen (ptr) + 1; else i = 0; r_mem_copyendian (&rap_s->buf[1], (ut8 *)&i, 4, !endian); rap_s->buf[0] = RAP_RMT_CMD | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 5); if (i) r_socket_write (rap_s->fd, ptr, i); r_socket_flush (rap_s->fd); free (ptr); ptr = NULL; break; case RAP_RMT_CLOSE: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4); r_mem_copyendian ((ut8 *)&i, &rap_s->buf[1], 4, !endian); rap_s->close (rap_s->user, i); rap_s->buf[0] = RAP_RMT_CLOSE | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 5); r_socket_flush (rap_s->fd); break; default: eprintf ("unknown command 0x%02hhx\n", rap_s->buf[0]); r_socket_close (rap_s->fd); ret = -1; break; } return ret; }
R_API bool r_socket_rap_server_continue (RSocketRapServer *rap_s) { int i, whence, ret = true; ut64 offset; char *ptr = NULL; if (!rap_s || !rap_s->fd) return false; if (!r_socket_is_connected (rap_s->fd)) return false; r_socket_read_block (rap_s->fd, rap_s->buf, 1); ret = rap_s->buf[0]; switch (ret) { case RAP_RMT_OPEN: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 2); r_socket_read_block (rap_s->fd, &rap_s->buf[3], (int)rap_s->buf[2]); rap_s->open (rap_s->user, (const char *)&rap_s->buf[3], (int)rap_s->buf[1], 0); rap_s->buf[0] = RAP_RMT_OPEN | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 5); r_socket_flush (rap_s->fd); break; case RAP_RMT_READ: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4); i = r_read_be32 (&rap_s->buf[1]); if (i > RAP_RMT_MAX || i < 0) i = RAP_RMT_MAX; rap_s->read (rap_s->user, &rap_s->buf[5], i); rap_s->buf[0] = RAP_RMT_READ | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, i + 5); r_socket_flush (rap_s->fd); break; case RAP_RMT_WRITE: r_socket_read_block (rap_s->fd, rap_s->buf + 1, 4); i = r_read_be32 (rap_s->buf + 1); if (i > RAP_RMT_MAX || i < 0) { i = RAP_RMT_MAX; } r_socket_read_block (rap_s->fd, rap_s->buf + 5, i); int ret = rap_s->write (rap_s->user, rap_s->buf + 5, i); r_write_be32 (rap_s->buf + 1, ret); rap_s->buf[0] = RAP_RMT_WRITE | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 5); r_socket_flush (rap_s->fd); break; case RAP_RMT_SEEK: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 9); whence = rap_s->buf[1]; offset = r_read_be64 (rap_s->buf + 2); offset = rap_s->seek (rap_s->user, offset, whence); /* prepare reply */ rap_s->buf[0] = RAP_RMT_SEEK | RAP_RMT_REPLY; r_write_be64 (rap_s->buf + 1, offset); r_socket_write (rap_s->fd, rap_s->buf, 9); r_socket_flush (rap_s->fd); break; case RAP_RMT_CMD: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4); i = r_read_be32 (&rap_s->buf[1]); r_socket_read_block (rap_s->fd, &rap_s->buf[5], i); ptr = rap_s->cmd (rap_s->user, (const char *)&rap_s->buf[5]); i = (ptr)? strlen (ptr) + 1: 0; r_write_be32 (&rap_s->buf[1], i); rap_s->buf[0] = RAP_RMT_CMD | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 5); if (i) r_socket_write (rap_s->fd, ptr, i); r_socket_flush (rap_s->fd); free (ptr); ptr = NULL; break; case RAP_RMT_CLOSE: r_socket_read_block (rap_s->fd, &rap_s->buf[1], 4); i = r_read_be32 (&rap_s->buf[1]); rap_s->close (rap_s->user, i); rap_s->buf[0] = RAP_RMT_CLOSE | RAP_RMT_REPLY; r_socket_write (rap_s->fd, rap_s->buf, 5); r_socket_flush (rap_s->fd); break; default: eprintf ("unknown command 0x%02x\n", \ (unsigned int)(unsigned char)rap_s->buf[0]); r_socket_close (rap_s->fd); ret = false; break; } return ret; }