From c8817ca24ba391abdce2c989ceb37ac496eb5ff8 Mon Sep 17 00:00:00 2001 From: Fredrik Tolf Date: Wed, 13 Feb 2008 23:56:23 +0100 Subject: [PATCH] Added an actual command to dcsh. --- clients/tty/dcsh.c | 158 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 133 insertions(+), 25 deletions(-) diff --git a/clients/tty/dcsh.c b/clients/tty/dcsh.c index b8f721f..4354acf 100644 --- a/clients/tty/dcsh.c +++ b/clients/tty/dcsh.c @@ -22,7 +22,9 @@ #include #include #include +#include #include +#include #ifdef HAVE_CONFIG_H #include @@ -34,17 +36,137 @@ int verbose = 0; int dcfd; +struct cmd { + wchar_t *name; + int (*handler)(int argc, wchar_t **argv); +}; + +int cmd_lsnodes(int argc, wchar_t **argv) +{ + int i; + struct dc_response *resp; + struct dc_intresp *ires; + + resp = dc_gettaggedrespsync(dc_queuecmd(NULL, NULL, L"lsnodes", NULL)); + if(resp->code == 200) { + printf(" ID NET USERS S NAME\n"); + while((ires = dc_interpret(resp)) != NULL) { + if(wcslen(ires->argv[2].val.str) > 58) { + for(i = 55; i < 58; i++) + ires->argv[2].val.str[i] = L'.'; + ires->argv[2].val.str[i] = L'\0'; + } + printf("%5i %4ls %6i %c %ls\n", ires->argv[0].val.num, ires->argv[1].val.str, ires->argv[3].val.num, "SHED"[ires->argv[4].val.num], ires->argv[2].val.str); + dc_freeires(ires); + } + } else if(resp->code == 201) { + } else { + fprintf(stderr, "dcsh: %ls\n", resp->rlines[0].argv[0]); + } + return(0); +} + +struct cmd commands[] = { + {L"hubs", cmd_lsnodes}, + {NULL, NULL} +}; + +int run1(int argc, wchar_t **argv) +{ + struct cmd *c; + + for(c = commands; c->handler != NULL; c++) { + if(!wcscmp(argv[0], c->name)) + return(c->handler(argc, argv)); + } + fprintf(stderr, "dcsh: no such command\n"); + return(1); +} + +int runchar(int argc, char **argv) { + int i, rv; + wchar_t **wargv, *buf; + size_t wargvsize, wargvdata; + + wargv = NULL; + wargvsize = wargvdata = 0; + for(i = 0; i < argc; i++) { + if((buf = icmbstowcs(argv[i], NULL)) == NULL) { + fprintf(stderr, "dcsh: could not convert %s to wide char: %s\n", argv[i], strerror(errno)); + for(i = 0; i < wargvdata; i++) + free(wargv[i]); + if(wargv != NULL) + free(wargv); + return(1); + } + addtobuf(wargv, buf); + } + addtobuf(wargv, NULL); + rv = run1(wargvdata - 1, wargv); + dc_freewcsarr(wargv); + return(rv); +} + +int shell(void) +{ + int ret, argc; + wchar_t *buf, **argv; + char *p, cmdbuf[128]; + int cmddata; + struct pollfd pfd[2]; + + cmddata = 0; + while(1) { + pfd[0].fd = dcfd; + pfd[0].events = POLLIN; + if(dc_wantwrite()) + pfd[0].events |= POLLOUT; + pfd[1].fd = 0; + pfd[1].events = POLLIN; + pfd[1].revents = 0; + if(poll(pfd, 2, -1) < 0) { + if(errno != EINTR) { + perror("dcsh: poll"); + exit(1); + } + } + if(((pfd[0].revents & POLLIN) && dc_handleread()) || ((pfd[0].revents & POLLOUT) && dc_handlewrite())) + return(1); + if(pfd[1].revents) { + ret = read(0, cmdbuf + cmddata, sizeof(cmdbuf) - cmddata); + if(ret < 0) { + fprintf(stderr, "dcsh: stdin: %s\n", strerror(errno)); + return(1); + } else if(ret == 0) { + return(0); + } + cmddata += ret; + while((p = memchr(cmdbuf, '\n', cmddata)) != NULL) { + *(p++) = 0; + if((buf = icmbstowcs(cmdbuf, NULL)) == NULL) { + fprintf(stderr, "dcsh: could not convert command to wide chars: %s\n", strerror(errno)); + } else { + argv = dc_lexsexpr(buf); + free(buf); + for(argc = 0; argv[argc] != NULL; argc++); + if(argc > 0) + run1(argc, argv); + dc_freewcsarr(argv); + } + memmove(cmdbuf, p, cmddata -= (p - cmdbuf)); + } + } + } +} + int main(int argc, char **argv) { - int c; + int c, rv; char *server; char *username; int authless, authia; - struct pollfd pfd[2]; - int done; - char cmdbuf[128]; - int cmddata; + setlocale(LC_ALL, ""); server = username = NULL; authless = authia = 1; while((c = getopt(argc, argv, "hvIAs:u:")) != -1) { @@ -65,7 +187,7 @@ int main(int argc, char **argv) verbose++; break; default: - fprintf(stderr, "usage: dcsh [-AIhv] [-s SERVER] [-u USERNAME]\n"); + fprintf(stderr, "usage: dcsh [-AIhv] [-s SERVER] [-u USERNAME] [COMMAND [ARGS...]]\n"); exit((c == 'h')?0:1); } } @@ -85,23 +207,9 @@ int main(int argc, char **argv) } if(verbose) fprintf(stderr, "done\n"); - done = 0; - cmddata = 0; - while(!done) { - pfd[0].fd = dcfd; - pfd[0].events = POLLIN; - if(dc_wantwrite()) - pfd[0].events |= POLLOUT; - pfd[1].fd = 0; - pfd[1].events = POLLIN; - pfd[1].revents = 0; - if(poll(pfd, (cmddata < sizeof(cmdbuf)) ? 2 : 1, -1) < 0) { - if(errno != EINTR) { - perror("dcsh: poll"); - exit(1); - } - } - - } - return(0); + if(optind < argc) + rv = runchar(argc - optind, argv + optind); + else + rv = shell(); + return(rv); } -- 2.11.0