Permalink
Browse files

exec cmd: base64 stdout and stderr

Signed-off-by: Jianhui Zhao <jianhuizhao329@gmail.com>
  • Loading branch information...
zhaojh329 committed Jan 7, 2019
1 parent d273c59 commit 80bb133515c4b3eaebcd499e254381fa4f7a3c9e
Showing with 138 additions and 9 deletions.
  1. +32 −9 src/command.c
  2. +57 −0 src/utils.c
  3. +3 −0 src/utils.h
  4. +46 −0 tools/sendcmd.sh
@@ -28,8 +28,10 @@
#include <sys/stat.h>
#include <sys/wait.h>
#include <uwsc/log.h>
#include <math.h>

#include "list.h"
#include "utils.h"
#include "command.h"

static int nrunning;
@@ -147,22 +149,43 @@ static void cmd_err_reply(struct uwsc_client *ws, const char *token, int err)

static void cmd_reply(struct task *t, int code)
{
int len = buffer_length(&t->ob) + buffer_length(&t->eb) + 100;
char *str;
size_t len = buffer_length(&t->ob) + buffer_length(&t->eb);
int ret;
char *str, *pos;

str = malloc(len);
len = ceil(len * 4.0 / 3) + 200;

str = calloc(1, len);
if (!str) {
cmd_err_reply(t->ws, t->token, RTTY_CMD_ERR_NOMEM);
return;
}

snprintf(str, len, "{\"type\":\"cmd\",\"token\":\"%s\","
"\"attrs\":{\"stdout\":\"%.*s\",\"stderr\":\"%.*s\",\"code\":%d}}", t->token,
(int)buffer_length(&t->ob), (char *)buffer_data(&t->ob),
(int)buffer_length(&t->eb), (char *)buffer_data(&t->eb),
code);
pos = str;

ret = snprintf(pos, len, "{\"type\":\"cmd\",\"token\":\"%s\","
"\"attrs\":{\"code\":%d,\"stdout\":\"", t->token, code);

len -= ret;
pos += ret;

ret = b64_encode(buffer_data(&t->ob), buffer_length(&t->ob), pos, len);
len -= ret;
pos += ret;

ret = snprintf(pos, len, "\",\"stderr\":\"");
len -= ret;
pos += ret;

ret = b64_encode(buffer_data(&t->eb), buffer_length(&t->eb), pos, len);
len -= ret;
pos += ret;

ret = snprintf(pos, len, "\"}}");
len -= ret;
pos += ret;

t->ws->send(t->ws, str, strlen(str), UWSC_OP_TEXT);
t->ws->send(t->ws, str, pos - str, UWSC_OP_TEXT);
free(str);
}

@@ -111,3 +111,60 @@ bool valid_id(const char *id)

return true;
}


int b64_encode(const void *src, size_t srclen, void *dest, size_t destlen)
{
static const char *Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const uint8_t *_src = src;
char *target = dest;
size_t datalength = 0;
uint8_t input[3] = "";
uint8_t output[4];
int i;

while (2 < srclen) {
input[0] = *_src++;
input[1] = *_src++;
input[2] = *_src++;
srclen -= 3;

output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
output[3] = input[2] & 0x3f;

if (datalength + 4 > destlen)
return (-1);
target[datalength++] = Base64[output[0]];
target[datalength++] = Base64[output[1]];
target[datalength++] = Base64[output[2]];
target[datalength++] = Base64[output[3]];
}

/* Now we worry about padding. */
if (0 != srclen) {
/* Get what's left. */
input[0] = input[1] = input[2] = '\0';
for (i = 0; i < srclen; i++)
input[i] = *_src++;

output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);

if (datalength + 4 > destlen)
return (-1);
target[datalength++] = Base64[output[0]];
target[datalength++] = Base64[output[1]];
if (srclen == 1)
target[datalength++] = '=';
else
target[datalength++] = Base64[output[2]];
target[datalength++] = '=';
}
if (datalength >= destlen)
return -1;
target[datalength] = '\0'; /* Returned value doesn't count \0. */
return datalength;
}
@@ -21,6 +21,7 @@
#define _UTILS_H

#include <stdbool.h>
#include <sys/types.h>

int get_iface_mac(const char *ifname, char *dst, int len);

@@ -30,4 +31,6 @@ int find_login(char *buf, int len);

bool valid_id(const char *id);

int b64_encode(const void *src, size_t srclen, void *dest, size_t destlen);

#endif
@@ -0,0 +1,46 @@
#!/bin/sh

host=localhost
port=5912
devid="test"
cmd="echo"
params='["hello rtty"]'
username="test"
password="test"

resp=$(curl "http://$host:$port/cmd" -d "{\"devid\":\"$devid\", \"cmd\":\"$cmd\", \"params\": $params, \"username\": \"$username\", \"password\": \"$password\"}" 2>/dev/null)

token=$(echo "$resp" | jq -r '.token')

[ "$token" = "null" ] && {
echo "$resp"
exit 1
}


while [ true ]
do
resp=$(curl "http://$host:$port/cmd?token=$token" 2>/dev/null)
err=$(echo "$resp" | jq -r '.err')
[ "$err" = "1005" ] && {
echo "Pending..."
sleep 1
continue
}

[ -n "err" ] && {
msg=$(echo "$resp" | jq -r '.msg')
echo "err: $err"
echo "msg: $msg"
break
}

code=$(echo "$resp" | jq -r '.code')
stdout=$(echo "$resp" | jq -r '.stdout' | base64 -d)
stderr=$(echo "$resp" | jq -r '.stderr' | base64 -d)

echo "code: $code"
echo "stdout: $stdout"
echo "stderr: $stderr"
break
done

0 comments on commit 80bb133

Please sign in to comment.