|
|
|
@ -25,6 +25,7 @@
|
|
|
|
|
#include <sys/socket.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <sys/un.h>
|
|
|
|
|
#include <termios.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
|
|
#include <sodium.h>
|
|
|
|
@ -104,7 +105,7 @@ static const unsigned char ssb_cap[] = {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void usage() {
|
|
|
|
|
fputs("usage: sbotc [-j] [-T] [-l]\n"
|
|
|
|
|
fputs("usage: sbotc [-j] [-T] [-l] [-r]\n"
|
|
|
|
|
" [ -n | [-c <cap>] [-k <key>] [-K <keypair_seed>] ]\n"
|
|
|
|
|
" [ [-s <host>] [-p <port>] [ -4 | -6 ] | [-u <socket_path>] ]\n"
|
|
|
|
|
" [ -a | [-t <type>] <method> [<argument>...] ]\n", stderr);
|
|
|
|
@ -857,7 +858,7 @@ static int muxrpc_write_blob_add(struct boxs *bs, int infd, int outfd, int req_i
|
|
|
|
|
in == stream_state_ended_error || out == stream_state_ended_error ? 2 : 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int muxrpc_duplex(struct boxs *bs, int infd, int outfd, enum pkt_type in_ptype, int req_id, bool no_newline) {
|
|
|
|
|
static int muxrpc_duplex(struct boxs *bs, int infd, int outfd, enum pkt_type in_ptype, int req_id, bool no_newline, bool raw) {
|
|
|
|
|
int rc;
|
|
|
|
|
fd_set rd;
|
|
|
|
|
int sfd = bs->s;
|
|
|
|
@ -866,7 +867,7 @@ static int muxrpc_duplex(struct boxs *bs, int infd, int outfd, enum pkt_type in_
|
|
|
|
|
enum stream_state out = stream_state_open;
|
|
|
|
|
|
|
|
|
|
while (out == stream_state_open
|
|
|
|
|
|| (in == stream_state_open && out != stream_state_ended_error)) {
|
|
|
|
|
|| (!raw && in == stream_state_open && out != stream_state_ended_error)) {
|
|
|
|
|
FD_ZERO(&rd);
|
|
|
|
|
if (in == stream_state_open) FD_SET(infd, &rd);
|
|
|
|
|
if (out == stream_state_open) FD_SET(sfd, &rd);
|
|
|
|
@ -957,6 +958,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
bool test = false;
|
|
|
|
|
bool noauth = false;
|
|
|
|
|
bool no_newline = false;
|
|
|
|
|
bool raw = false;
|
|
|
|
|
bool host_arg = false;
|
|
|
|
|
bool port_arg = false;
|
|
|
|
|
bool key_arg = false;
|
|
|
|
@ -999,6 +1001,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
case '6': ipv6_arg = true; break;
|
|
|
|
|
case 'a': passthrough = true; break;
|
|
|
|
|
case 'l': no_newline = true; break;
|
|
|
|
|
case 'r': raw = true; break;
|
|
|
|
|
default: usage();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1134,6 +1137,17 @@ do_tcp_connect:
|
|
|
|
|
|
|
|
|
|
muxrpc_call(&bs, method, argument, type, typestr, 1);
|
|
|
|
|
|
|
|
|
|
struct termios orig_tc;
|
|
|
|
|
if (raw) {
|
|
|
|
|
struct termios raw_tc;
|
|
|
|
|
rc = tcgetattr(STDIN_FILENO, &orig_tc);
|
|
|
|
|
if (rc < 0) warnx("tcgetattr");
|
|
|
|
|
raw_tc = orig_tc;
|
|
|
|
|
raw_tc.c_lflag &= ~(ICANON | ECHO);
|
|
|
|
|
rc = tcsetattr(STDIN_FILENO, TCSANOW, &raw_tc);
|
|
|
|
|
if (rc < 0) warnx("tcgetattr");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case muxrpc_type_async:
|
|
|
|
|
rc = muxrpc_read_async(&bs, STDOUT_FILENO, 1, no_newline);
|
|
|
|
@ -1149,10 +1163,15 @@ do_tcp_connect:
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case muxrpc_type_duplex:
|
|
|
|
|
rc = muxrpc_duplex(&bs, STDIN_FILENO, STDOUT_FILENO, ptype, 1, no_newline);
|
|
|
|
|
rc = muxrpc_duplex(&bs, STDIN_FILENO, STDOUT_FILENO, ptype, 1, no_newline, raw);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (raw) {
|
|
|
|
|
rc = tcsetattr(STDIN_FILENO, TCSANOW, &orig_tc);
|
|
|
|
|
if (rc < 0) warnx("tcsetattr");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bs_end(&bs);
|
|
|
|
|
close(s);
|
|
|
|
|
return rc;
|
|
|
|
|