|
|
|
@ -104,7 +104,7 @@ static const unsigned char ssb_cap[] = {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void usage() {
|
|
|
|
|
fputs("usage: sbotc [-j] [-T]\n"
|
|
|
|
|
fputs("usage: sbotc [-j] [-T] [-l]\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);
|
|
|
|
@ -578,7 +578,7 @@ static int bs_read_out(struct boxs *bs, int fd, size_t len) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int bs_read_error(struct boxs *bs, int errfd, enum pkt_flags flags, size_t len) {
|
|
|
|
|
static int bs_read_error(struct boxs *bs, int errfd, enum pkt_flags flags, size_t len, bool no_newline) {
|
|
|
|
|
// suppress printing "true" indicating end without error
|
|
|
|
|
if (flags & pkt_flags_json && len == 4) {
|
|
|
|
|
char buf[4];
|
|
|
|
@ -590,7 +590,7 @@ static int bs_read_error(struct boxs *bs, int errfd, enum pkt_flags flags, size_
|
|
|
|
|
} else {
|
|
|
|
|
if (bs_read_out(bs, errfd, len) < 0) return -1;
|
|
|
|
|
}
|
|
|
|
|
if (flags & (pkt_flags_json | pkt_flags_string)) {
|
|
|
|
|
if (flags & (pkt_flags_json | pkt_flags_string) && !no_newline) {
|
|
|
|
|
if (write_buf(errfd, "\n") < 0) return -1;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
@ -703,7 +703,7 @@ static void ps_reject(struct boxs *bs, size_t len, int32_t req, enum pkt_flags f
|
|
|
|
|
write_buf(STDERR_FILENO, "\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static enum stream_state muxrpc_read_source_1(struct boxs *bs, int outfd, int req_id) {
|
|
|
|
|
static enum stream_state muxrpc_read_source_1(struct boxs *bs, int outfd, int req_id, bool no_newline) {
|
|
|
|
|
enum pkt_flags flags;
|
|
|
|
|
size_t len;
|
|
|
|
|
int32_t req;
|
|
|
|
@ -719,28 +719,28 @@ static enum stream_state muxrpc_read_source_1(struct boxs *bs, int outfd, int re
|
|
|
|
|
return stream_state_open;
|
|
|
|
|
}
|
|
|
|
|
if (flags & pkt_flags_end) {
|
|
|
|
|
rc = bs_read_error(bs, STDERR_FILENO, flags, len);
|
|
|
|
|
rc = bs_read_error(bs, STDERR_FILENO, flags, len, no_newline);
|
|
|
|
|
if (rc < 0) err(1, "bs_read_error");
|
|
|
|
|
if (rc == 1) return stream_state_ended_error;
|
|
|
|
|
return stream_state_ended_ok;
|
|
|
|
|
}
|
|
|
|
|
rc = bs_read_out(bs, outfd, len);
|
|
|
|
|
if (rc < 0) err(1, "bs_read_out");
|
|
|
|
|
if (flags & (pkt_flags_json | pkt_flags_string)) {
|
|
|
|
|
if (flags & (pkt_flags_json | pkt_flags_string) && !no_newline) {
|
|
|
|
|
rc = write_buf(outfd, "\n");
|
|
|
|
|
if (rc < 0) err(1, "write_buf");
|
|
|
|
|
}
|
|
|
|
|
return stream_state_open;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int muxrpc_read_source(struct boxs *bs, int outfd, int req_id) {
|
|
|
|
|
static int muxrpc_read_source(struct boxs *bs, int outfd, int req_id, bool no_newline) {
|
|
|
|
|
enum stream_state state;
|
|
|
|
|
while ((state = muxrpc_read_source_1(bs, outfd, req_id)) == stream_state_open);
|
|
|
|
|
while ((state = muxrpc_read_source_1(bs, outfd, req_id, no_newline)) == stream_state_open);
|
|
|
|
|
return state == stream_state_ended_ok ? 0 :
|
|
|
|
|
state == stream_state_ended_error ? 2 : 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int muxrpc_read_async(struct boxs *bs, int outfd, int req_id) {
|
|
|
|
|
static int muxrpc_read_async(struct boxs *bs, int outfd, int req_id, bool no_newline) {
|
|
|
|
|
enum pkt_flags flags;
|
|
|
|
|
size_t len;
|
|
|
|
|
int32_t req;
|
|
|
|
@ -754,14 +754,14 @@ static int muxrpc_read_async(struct boxs *bs, int outfd, int req_id) {
|
|
|
|
|
ps_reject(bs, len, req, flags);
|
|
|
|
|
}
|
|
|
|
|
if (flags & pkt_flags_end) {
|
|
|
|
|
rc = bs_read_error(bs, STDERR_FILENO, flags, len);
|
|
|
|
|
rc = bs_read_error(bs, STDERR_FILENO, flags, len, no_newline);
|
|
|
|
|
if (rc < 0) err(1, "bs_read_error");
|
|
|
|
|
if (rc == 1) return 2;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
rc = bs_read_out(bs, outfd, len);
|
|
|
|
|
if (rc < 0) err(1, "bs_read_out");
|
|
|
|
|
if (flags & (pkt_flags_json | pkt_flags_string)) {
|
|
|
|
|
if (flags & (pkt_flags_json | pkt_flags_string) && !no_newline) {
|
|
|
|
|
rc = write_buf(outfd, "\n");
|
|
|
|
|
if (rc < 0) err(1, "write_buf");
|
|
|
|
|
}
|
|
|
|
@ -798,7 +798,7 @@ static enum stream_state muxrpc_write_sink_1_hashed(struct boxs *bs, int infd,
|
|
|
|
|
return stream_state_open;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int muxrpc_write_sink(struct boxs *bs, int infd, enum pkt_type ptype, int req_id) {
|
|
|
|
|
static int muxrpc_write_sink(struct boxs *bs, int infd, enum pkt_type ptype, int req_id, bool no_newline) {
|
|
|
|
|
int rc;
|
|
|
|
|
fd_set rd;
|
|
|
|
|
int sfd = bs->s;
|
|
|
|
@ -813,14 +813,14 @@ static int muxrpc_write_sink(struct boxs *bs, int infd, enum pkt_type ptype, int
|
|
|
|
|
rc = select(maxfd + 1, &rd, 0, 0, NULL);
|
|
|
|
|
if (rc < 0) err(1, "select");
|
|
|
|
|
if (FD_ISSET(infd, &rd)) in = muxrpc_write_sink_1(bs, infd, ptype, req_id);
|
|
|
|
|
if (FD_ISSET(sfd, &rd)) out = muxrpc_read_source_1(bs, -1, req_id);
|
|
|
|
|
if (FD_ISSET(sfd, &rd)) out = muxrpc_read_source_1(bs, -1, req_id, no_newline);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return in == stream_state_ended_ok && out == stream_state_ended_ok ? 0 :
|
|
|
|
|
in == stream_state_ended_error || out == stream_state_ended_error ? 2 : 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int muxrpc_write_blob_add(struct boxs *bs, int infd, int outfd, int req_id) {
|
|
|
|
|
static int muxrpc_write_blob_add(struct boxs *bs, int infd, int outfd, int req_id, bool no_newline) {
|
|
|
|
|
int rc;
|
|
|
|
|
fd_set rd;
|
|
|
|
|
int sfd = bs->s;
|
|
|
|
@ -841,7 +841,7 @@ static int muxrpc_write_blob_add(struct boxs *bs, int infd, int outfd, int req_i
|
|
|
|
|
rc = select(maxfd + 1, &rd, 0, 0, NULL);
|
|
|
|
|
if (rc < 0) err(1, "select");
|
|
|
|
|
if (FD_ISSET(infd, &rd)) in = muxrpc_write_sink_1_hashed(bs, infd, &hash_state, req_id);
|
|
|
|
|
if (FD_ISSET(sfd, &rd)) out = muxrpc_read_source_1(bs, -1, req_id);
|
|
|
|
|
if (FD_ISSET(sfd, &rd)) out = muxrpc_read_source_1(bs, -1, req_id, no_newline);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rc = crypto_hash_sha256_final(&hash_state, hash);
|
|
|
|
@ -857,7 +857,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) {
|
|
|
|
|
static int muxrpc_duplex(struct boxs *bs, int infd, int outfd, enum pkt_type in_ptype, int req_id, bool no_newline) {
|
|
|
|
|
int rc;
|
|
|
|
|
fd_set rd;
|
|
|
|
|
int sfd = bs->s;
|
|
|
|
@ -873,7 +873,7 @@ static int muxrpc_duplex(struct boxs *bs, int infd, int outfd, enum pkt_type in_
|
|
|
|
|
rc = select(maxfd + 1, &rd, 0, 0, NULL);
|
|
|
|
|
if (rc < 0) err(1, "select");
|
|
|
|
|
if (FD_ISSET(infd, &rd)) in = muxrpc_write_sink_1(bs, infd, in_ptype, req_id);
|
|
|
|
|
if (FD_ISSET(sfd, &rd)) out = muxrpc_read_source_1(bs, outfd, req_id);
|
|
|
|
|
if (FD_ISSET(sfd, &rd)) out = muxrpc_read_source_1(bs, outfd, req_id, no_newline);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return in == stream_state_ended_ok && out == stream_state_ended_ok ? 0 :
|
|
|
|
@ -956,6 +956,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
ssize_t len;
|
|
|
|
|
bool test = false;
|
|
|
|
|
bool noauth = false;
|
|
|
|
|
bool no_newline = false;
|
|
|
|
|
bool host_arg = false;
|
|
|
|
|
bool port_arg = false;
|
|
|
|
|
bool key_arg = false;
|
|
|
|
@ -997,6 +998,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
case '4': ipv4_arg = true; break;
|
|
|
|
|
case '6': ipv6_arg = true; break;
|
|
|
|
|
case 'a': passthrough = true; break;
|
|
|
|
|
case 'l': no_newline = true; break;
|
|
|
|
|
default: usage();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1038,7 +1040,7 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
ssize_t type_len = json_get_value(manifest_buf, methodstr, &typestr);
|
|
|
|
|
if (!typestr && errno == ENOMSG) errx(1,
|
|
|
|
|
"unable to find method '%s' in manifest", methodstr);
|
|
|
|
|
if (!typestr) err(1, "unable to read manifest");
|
|
|
|
|
if (!typestr) err(1, "unable to read manifest %s/%s", manifest_buf, methodstr);
|
|
|
|
|
((char *)typestr)[type_len] = '\0';
|
|
|
|
|
}
|
|
|
|
|
if (strcmp(typestr, "sync") == 0) type = muxrpc_type_async;
|
|
|
|
@ -1134,20 +1136,20 @@ do_tcp_connect:
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case muxrpc_type_async:
|
|
|
|
|
rc = muxrpc_read_async(&bs, STDOUT_FILENO, 1);
|
|
|
|
|
rc = muxrpc_read_async(&bs, STDOUT_FILENO, 1, no_newline);
|
|
|
|
|
break;
|
|
|
|
|
case muxrpc_type_source:
|
|
|
|
|
rc = muxrpc_read_source(&bs, STDOUT_FILENO, 1);
|
|
|
|
|
rc = muxrpc_read_source(&bs, STDOUT_FILENO, 1, no_newline);
|
|
|
|
|
break;
|
|
|
|
|
case muxrpc_type_sink:
|
|
|
|
|
if (!strcmp(methodstr, "blobs.add")) {
|
|
|
|
|
rc = muxrpc_write_blob_add(&bs, STDIN_FILENO, STDOUT_FILENO, 1);
|
|
|
|
|
rc = muxrpc_write_blob_add(&bs, STDIN_FILENO, STDOUT_FILENO, 1, no_newline);
|
|
|
|
|
} else {
|
|
|
|
|
rc = muxrpc_write_sink(&bs, STDIN_FILENO, ptype, 1);
|
|
|
|
|
rc = muxrpc_write_sink(&bs, STDIN_FILENO, ptype, 1, no_newline);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case muxrpc_type_duplex:
|
|
|
|
|
rc = muxrpc_duplex(&bs, STDIN_FILENO, STDOUT_FILENO, ptype, 1);
|
|
|
|
|
rc = muxrpc_duplex(&bs, STDIN_FILENO, STDOUT_FILENO, ptype, 1, no_newline);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|