|
|
@ -71,20 +71,198 @@ struct _remote_host {
|
|
|
|
sxlink_t *link;
|
|
|
|
sxlink_t *link;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct _shll_cmds {
|
|
|
|
|
|
|
|
char cmd[64];
|
|
|
|
|
|
|
|
int (*execute)(sxlink_t *, char **, int);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int __cwd(sxlink_t *link, char **argv, int argc)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sxchnl_t *channel = sxchannel_open(link, READONLY_CHANNEL);
|
|
|
|
|
|
|
|
sxmsg_t *msg;
|
|
|
|
|
|
|
|
char buf[1024];
|
|
|
|
|
|
|
|
int r = SXE_SUCCESS;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!channel) return SXE_FAILED;
|
|
|
|
|
|
|
|
if(argc < 2) return SXE_SUCCESS; /* nothing to do if we don't have any parameters */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
snprintf(buf, 1024, "(%s %s)", CWD_CMD, argv[1]);
|
|
|
|
|
|
|
|
r = sxmsg_send(channel, buf, strlen(buf), &msg);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(channel) sxchannel_close(channel);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return r;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void __dirlist_out(FILE *f, list_head_t *list)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
char *dname = NULL, *dtype = NULL;
|
|
|
|
|
|
|
|
list_node_t *iter, *siter;
|
|
|
|
|
|
|
|
struct _nn_stream_entry_node *entry;
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
list_for_each_safe(list, iter, siter) {
|
|
|
|
|
|
|
|
entry = list_entry(iter, struct _nn_stream_entry_node, node);
|
|
|
|
|
|
|
|
if(!i) dname = entry->value;
|
|
|
|
|
|
|
|
else if(i == 1) dtype = entry->value;
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(f, "%-24s | %-12s\n", dname, dtype);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int __list(sxlink_t *link, char **argv, int argc)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sxmsg_t *msg;
|
|
|
|
|
|
|
|
char *opt = NULL;
|
|
|
|
|
|
|
|
int r = SXE_SUCCESS;
|
|
|
|
|
|
|
|
sxstream_t *stream;
|
|
|
|
|
|
|
|
list_head_t *list;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(argc > 2) opt = argv[1];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fprintf(stdout, "%-24s | %-12s\n", "Name", "Type");
|
|
|
|
|
|
|
|
fprintf(stdout, "---------------------------------------\n");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stream = sxstream_open(link, opt, DIRLIST_ID, SXE_O_READ);
|
|
|
|
|
|
|
|
if(!stream) {
|
|
|
|
|
|
|
|
fprintf(stderr, "Failed to open stream with %d ID (%d).\n", DIRLIST_ID, errno);
|
|
|
|
|
|
|
|
return SXE_FAILED;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while((list = sxstream_read(stream)) != NULL) __dirlist_out(stdout, list);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(errno != SXE_EOS) fprintf(stderr, "Reading failed (%d)\n", errno);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sxstream_close(stream);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return r;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct _shll_cmds shcmds[] = {
|
|
|
|
|
|
|
|
{ "cd", __cwd },
|
|
|
|
|
|
|
|
{ "ls", __list },
|
|
|
|
|
|
|
|
{ "", NULL},
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* misc remote commands */
|
|
|
|
|
|
|
|
static int __remote_getcwd(sxlink_t *link, char *buf, size_t buflen)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sxchnl_t *channel = sxchannel_open(link, READONLY_CHANNEL);
|
|
|
|
|
|
|
|
sxmsg_t *msg;
|
|
|
|
|
|
|
|
sexp_t *sx = NULL, *isx;
|
|
|
|
|
|
|
|
int r = SXE_SUCCESS, idx;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!channel || !buf) return SXE_FAILED;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
snprintf(buf, buflen, "(%s)", GETCWD_CMD);
|
|
|
|
|
|
|
|
r = sxmsg_send(channel, buf, strlen(buf), &msg);
|
|
|
|
|
|
|
|
if(r == SXE_RAPIDMSG || r == SXE_REPLYREQ) {
|
|
|
|
|
|
|
|
sx = parse_sexp(sxmsg_payload(msg), strlen(sxmsg_payload(msg)));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(r == SXE_RAPIDMSG) sxmsg_clean(msg);
|
|
|
|
|
|
|
|
else sxmsg_return(msg, SXE_SUCCESS);
|
|
|
|
|
|
|
|
} else goto __fini;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!sx) { r = SXE_ENOMEM; goto __fini; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SEXP_ITERATE_LIST(sx, isx, idx) {
|
|
|
|
|
|
|
|
if(isx->ty == SEXP_LIST) { r = SXE_BADPROTO; goto __fini; }
|
|
|
|
|
|
|
|
if(!idx) strcpy(buf, isx->val);
|
|
|
|
|
|
|
|
else { r = SXE_BADPROTO; goto __fini; }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r = SXE_SUCCESS;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__fini:
|
|
|
|
|
|
|
|
if(sx) destroy_sexp(sx);
|
|
|
|
|
|
|
|
if(channel) sxchannel_close(channel);
|
|
|
|
|
|
|
|
return r;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int __exec_line(sxlink_t *link, const char *line)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
char **argv, *tline = (char *)line, *oline;
|
|
|
|
|
|
|
|
int argc, r = SXE_FAILED, i;
|
|
|
|
|
|
|
|
int (*exe)(sxlink_t *, char **, int) = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!strlen(line)) return SXE_NILREPLY;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* get arguments count */
|
|
|
|
|
|
|
|
argc = 1; oline = tline;
|
|
|
|
|
|
|
|
for(tline = strchr(tline, ' '); tline != NULL;
|
|
|
|
|
|
|
|
tline += sizeof(char), tline = strchr(tline, ' ')) {
|
|
|
|
|
|
|
|
if((strlen(oline) - strlen(tline)) > sizeof(char)) argc++;
|
|
|
|
|
|
|
|
oline = tline;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!(argv = malloc(sizeof(uintptr_t)*argc))) return SXE_ENOMEM;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* fill arguments */
|
|
|
|
|
|
|
|
for(oline = tline = (char *)line, i = 0; i < argc; i++) {
|
|
|
|
|
|
|
|
if(!(tline = strchr(tline, ' ')))
|
|
|
|
|
|
|
|
argv[i] = strdup(oline);
|
|
|
|
|
|
|
|
else if((strlen(oline) - strlen(tline)) > sizeof(char)) /* that's our bottle of beer */
|
|
|
|
|
|
|
|
argv[i] = strndup(oline, strlen(oline) - strlen(tline));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tline += sizeof(char);
|
|
|
|
|
|
|
|
oline = tline;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for(i = 0; i < argc; i++) { /* check up */
|
|
|
|
|
|
|
|
if(argv[i] == NULL) { r = SXE_ENOMEM; goto __fini; }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* now let's search our cmd */
|
|
|
|
|
|
|
|
for(i = 0; strlen(shcmds[i].cmd); i++) {
|
|
|
|
|
|
|
|
if(!strcmp(shcmds[i].cmd, argv[0])) exe = shcmds[i].execute;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!exe) r = SXE_IGNORED; /* ignoring stuff like that */
|
|
|
|
|
|
|
|
else r = exe(link, argv, argc);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__fini:
|
|
|
|
|
|
|
|
/* free all arguments */
|
|
|
|
|
|
|
|
if(argv && argc) {
|
|
|
|
|
|
|
|
for(i = 0; i < argc; i++) {
|
|
|
|
|
|
|
|
if(argv[i]) free(argv[i]);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
free(argv);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return r;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* session processing itself */
|
|
|
|
/* session processing itself */
|
|
|
|
static void __shell(sxlink_t *link)
|
|
|
|
static void __shell(sxlink_t *link)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct _session *s = (struct _session *)sxlink_getpriv(link);
|
|
|
|
struct _session *s = (struct _session *)sxlink_getpriv(link);
|
|
|
|
char *line;
|
|
|
|
char *line, cwd[1024], promt[1024];
|
|
|
|
|
|
|
|
int r, rrc;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r = __remote_getcwd(link, cwd, 1024);
|
|
|
|
|
|
|
|
if(r == SXE_SUCCESS)
|
|
|
|
|
|
|
|
snprintf(promt, 1024, "%s$>", cwd);
|
|
|
|
|
|
|
|
else snprintf(promt, 1024, "@e:%d$>", r);
|
|
|
|
|
|
|
|
|
|
|
|
for(;;) {
|
|
|
|
for(;;) {
|
|
|
|
line = readline("$>");
|
|
|
|
line = readline(promt);
|
|
|
|
|
|
|
|
|
|
|
|
if(line && *line) add_history(line);
|
|
|
|
if(line && *line) add_history(line);
|
|
|
|
else break;
|
|
|
|
else break;
|
|
|
|
|
|
|
|
|
|
|
|
if(!strcmp(line, "exit")) break;
|
|
|
|
if(!strcmp(line, "exit")) break;
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
rrc = __exec_line(link, line);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* getcwd, in some cases it might be changed */
|
|
|
|
|
|
|
|
r = __remote_getcwd(link, cwd, 1024);
|
|
|
|
|
|
|
|
if(r == SXE_SUCCESS) {
|
|
|
|
|
|
|
|
if(rrc == SXE_SUCCESS) snprintf(promt, 1024, "%s$>", cwd);
|
|
|
|
|
|
|
|
else snprintf(promt, 1024, "[%d]%s$>", rrc, cwd);
|
|
|
|
|
|
|
|
} else snprintf(promt, 1024, "@e:%d$>", r);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
free(line);
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|