From d8bc88f9016da527bf5ba572320ad7c9556d053d Mon Sep 17 00:00:00 2001 From: cel Date: Sun, 16 Dec 2018 09:31:42 -1000 Subject: [PATCH] Add -l no newline mode --- README.md | 2 +- sbotc.1 | 3 +++ sbotc.c | 48 +++++++++++++++++++++++++----------------------- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 8e59016..9643e61 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ sudo make install ## Usage ```sh -sbotc [-j] [-T] +sbotc [-j] [-T] [-l] [ -n | [-c ] [-k ] [-K ] ] [ [-s ] [-p ] [ -4 | -6 ] | [-u ] ] [ -a | [-t ] [...] ] diff --git a/sbotc.1 b/sbotc.1 index ee65468..4e62805 100644 --- a/sbotc.1 +++ b/sbotc.1 @@ -8,6 +8,7 @@ .Sh SYNOPSIS .Nm .Op Fl j +.Op Fl r .Op Fl T .Op Fl a . @@ -45,6 +46,8 @@ standard I/O. .Bl -tag .It Fl j Send stdin data as JSON. +.It Fl l +Don't output newlines after string or JSON packets. .It Fl T Test using shs1-testsuite protocol. Instead of connecting to a server and running a command, connect to stdio. On successful handshake, output concatenation of diff --git a/sbotc.c b/sbotc.c index 6015968..3bae9ac 100644 --- a/sbotc.c +++ b/sbotc.c @@ -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 ] [-k ] [-K ] ]\n" " [ [-s ] [-p ] [ -4 | -6 ] | [-u ] ]\n" " [ -a | [-t ] [...] ]\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; }