Add -e option for encoding arguments as strings

main
cel 6 years ago
parent 1938337af3
commit 1412c8b5f9

@ -16,7 +16,7 @@ sudo make install
## Usage
```sh
sbotc [-j] [-T] [-l] [-r]
sbotc [-j] [-T] [-l] [-r] [-e]
[ -n | [-c <cap>] [-k <key>] [-K <keypair_seed>] ]
[ [-s <host>] [-p <port>] [ -4 | -6 ] | [-u <socket_path>] ]
[ -a | [-t <type>] <method> [<argument>...] ]

@ -11,6 +11,7 @@
.Op Fl l
.Op Fl r
.Op Fl T
.Op Fl e
.Op Fl a
.
.Oo
@ -52,6 +53,8 @@ Don't output newlines after string or JSON packets.
.It Fl r
Raw mode. Disables stdin line buffering/editing and echoing. Implies
.Fl l .
.It Fl e
Encode arguments as strings, rather than expecting them to be JSON-encoded.
.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
@ -104,7 +107,9 @@ Default is to look up the method in
.It Ar method
Method name.
.It Op Ar argument ...
Arguments to pass to the method call. Each argument must be JSON-encoded.
Arguments to pass to the method call. Each argument must be JSON-encoded, unless the
.Fl e
option is used, in which the arguments are treated as strings.
.El
.Sh ENVIRONMENT
.Bl -tag

@ -112,7 +112,7 @@ static void reset_termios() {
}
static void usage() {
fputs("usage: sbotc [-j] [-T] [-l] [-r]\n"
fputs("usage: sbotc [-j] [-T] [-l] [-r] [-e]\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);
@ -916,25 +916,54 @@ static int method_to_json(char *out, size_t outlen, const char *str) {
return i;
}
static int args_to_json_length(int argc, char *argv[]) {
static int args_to_json_length(int argc, char *argv[], bool encode_strings) {
int i = 0;
int len = 3; // "[]\0"
for (i = 0; i < argc; i++)
for (i = 0; i < argc; i++) {
if (!encode_strings) {
len += strlen(argv[i])+1;
} else {
len += 3; // "\"\","
char *arg = argv[i], c;
while ((c = *arg++)) switch (c) {
case '"': len += 2; break;
case '\\': len += 2; break;
default: len++;
}
}
}
return len;
}
static int args_to_json(char *out, size_t outlen, unsigned int argc, char *argv[]) {
static int args_to_json(char *out, size_t outlen, unsigned int argc, char *argv[], bool encode_strings) {
size_t i = 0;
size_t j;
if (i+1 > outlen) return -1;
out[i++] = '[';
for (j = 0; j < argc; j++) {
if (!encode_strings) {
size_t len = strlen(argv[j]);
if (j > 0) out[i++] = ',';
if (i+len > outlen) return -1;
strncpy(out+i, argv[j], len);
i += len;
} else {
char *arg = argv[j];
char c;
if (j > 0) {
if (i+1 > outlen) return -1;
out[i++] = ',';
}
if (i+1 > outlen) return -1;
out[i++] = '"';
while ((c = *arg++)) {
if (i+2 > outlen) return -1;
if (c == '"' || c == '\\') out[i++] = '\\';
out[i++] = c;
}
if (i+1 > outlen) return -1;
out[i++] = '"';
}
}
if (i+2 > outlen) return -1;
out[i++] = ']';
@ -972,6 +1001,7 @@ int main(int argc, char *argv[]) {
bool ipv4_arg = false;
bool ipv6_arg = false;
bool passthrough = false;
bool strings = false;
enum ip_family ip_family;
get_app_dir(app_dir, sizeof(app_dir));
@ -1008,6 +1038,7 @@ int main(int argc, char *argv[]) {
case 'a': passthrough = true; break;
case 'l': no_newline = true; break;
case 'r': raw = true; no_newline = true; break;
case 'e': strings = true; break;
default: usage();
}
}
@ -1027,7 +1058,7 @@ int main(int argc, char *argv[]) {
memcpy(shs_cap_key, ssb_cap, 32);
}
argument_len = test ? 0 : args_to_json_length(argc-i, argv+i);
argument_len = test ? 0 : args_to_json_length(argc-i, argv+i, strings);
char argument[argument_len];
if (passthrough) {
@ -1037,7 +1068,7 @@ int main(int argc, char *argv[]) {
if (test) errx(1, "-a option conflicts with -T test");
} else if (!test) {
rc = args_to_json(argument, sizeof(argument), argc-i, argv+i);
rc = args_to_json(argument, sizeof(argument), argc-i, argv+i, strings);
if (rc < 0) errx(1, "unable to collect arguments");
char manifest_buf[8192];

Loading…
Cancel
Save