X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=ctdlsh%2Fsrc%2Fmain.c;h=7e18d2e6b64dda3aeef9fc55be2f1d5ca59a7c40;hb=6f940f7734c8209955d3c5acfa7f96fff4935938;hp=e37a3d1662c9aa2ab81dc52b187b18057cef3e65;hpb=18484af967a978c7eaa5cfbb1a7a2b2b8e8de19c;p=citadel.git diff --git a/ctdlsh/src/main.c b/ctdlsh/src/main.c index e37a3d166..7e18d2e6b 100644 --- a/ctdlsh/src/main.c +++ b/ctdlsh/src/main.c @@ -1,65 +1,83 @@ /* - * (c) 2009-2011 by Art Cancro and citadel.org + * (c) 2009-2012 by Art Cancro and citadel.org * This program is released under the terms of the GNU General Public License v3. */ -#include -#include -#include -#include -#include -#include -#include #include "ctdlsh.h" -#define CTDLDIR "/appl/citadel" - - -int com_quit(char *cmdbuf) { - abort(); +int cmd_quit(int sock, char *cmdbuf) { + return(cmdret_exit); } - - /* * Commands understood by ctdlsh */ typedef struct { char *name; - rl_icpfunc_t *func; + ctdlsh_cmdfunc_t *func; char *doc; } COMMAND; COMMAND commands[] = { - { "quit", com_quit, "Quit using ctdlsh" }, - { "exit", com_quit, "Quit using ctdlsh" }, - { NULL, NULL, NULL } + { "?", cmd_help, "Display this message" }, + { "help", cmd_help, "Display this message" }, + { "quit", cmd_quit, "Quit using ctdlsh" }, + { "exit", cmd_quit, "Quit using ctdlsh" }, + { "date", cmd_datetime, "Print the server's date and time" }, + { "time", cmd_datetime, "Print the server's date and time" }, + { "passwd", cmd_passwd, "Set or change an account password" }, + { "who", cmd_who, "Display a list of online users" }, + { "shutdown", cmd_shutdown, "Shut down the Citadel server" }, + { NULL, NULL, NULL } }; -int discover_ipgm_secret(char *dirname) { - int fd; - struct partial_config ccc; - char configfile[1024]; +int cmd_help(int sock, char *cmdbuf) { + int i; - sprintf(configfile, "%s/citadel.config", dirname); - fd = open(configfile, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "%s: %s\n", configfile, strerror(errno)); - return(-1); + for (i=0; commands[i].func != NULL; ++i) { + printf("%-10s %s\n", commands[i].name, commands[i].doc); } +} + + +/* Auto-completer function */ +char *command_generator(const char *text, int state) { + static int list_index; + static int len; + char *name; - if (read(fd, &ccc, sizeof(struct partial_config)) != sizeof(struct partial_config)) { - fprintf(stderr, "%s: %s\n", configfile, strerror(errno)); - return(-1); + if (!state) { + list_index = 0; + len = strlen(text); } - if (close(fd) != 0) { - fprintf(stderr, "%s: %s\n", configfile, strerror(errno)); - return(-1); + + while (name = commands[list_index].name) { + ++list_index; + + if (!strncmp(name, text, len)) { + return(strdup(name)); + } } - return(ccc.c_ipgm_secret); + + return(NULL); +} + + +/* Auto-completer function */ +char **ctdlsh_completion(const char *text, int start, int end) { + char **matches = (char **) NULL; + + if (start == 0) { + matches = rl_completion_matches(text, command_generator); + } + else { + rl_bind_key('\t', rl_abort); + } + + return (matches); } @@ -69,6 +87,7 @@ void do_main_loop(int server_socket) { char buf[1024]; char server_reply[1024]; int i; + int ret = (-1); strcpy(prompt, "> "); @@ -85,24 +104,18 @@ void do_main_loop(int server_socket) { } } + /* Tell libreadline how we will help with auto-completion of commands */ + rl_attempted_completion_function = ctdlsh_completion; + /* Here we go ... main command loop */ - while (cmd = readline(prompt)) { + while ((ret != cmdret_exit) && (cmd = readline(prompt))) { if ((cmd) && (*cmd)) { add_history(cmd); - sock_puts(server_socket, cmd); - sock_getln(server_socket, server_reply, sizeof server_reply); - printf("%s\n", server_reply); - - if ((server_reply[0] == '4') || (server_reply[0] == '8')) { - /* we might consider putting something here */ - sock_puts(server_socket, "000"); - } - - if ((server_reply[0] == '1') || (server_reply[0] == '8')) { - while(sock_getln(server_socket, buf, sizeof buf), strcmp(buf, "000")) { - printf("%s\n", buf); + for (i=0; commands[i].func != NULL; ++i) { + if (!strncasecmp(cmd, commands[i].name, strlen(commands[i].name))) { + ret = (*commands[i].func) (server_socket, cmd); } } @@ -112,16 +125,21 @@ void do_main_loop(int server_socket) { } } + +/* + * If you don't know what main() does by now you probably shouldn't be reading this code. + */ int main(int argc, char **argv) { int server_socket = 0; char buf[1024]; - int ipgm_secret = (-1); int c; char *ctdldir = CTDLDIR; - printf("\nCitadel administration shell v" PACKAGE_VERSION "\n"); - printf("(c) 2009-2011 citadel.org GPLv3\n"); + printf("\nCitadel administration shell v" PACKAGE_VERSION " (c) 2009-2012 by citadel.org\n" + "This is open source software made available to you under the terms\n" + "of the GNU General Public License v3. All other rights reserved.\n" + ); opterr = 0; while ((c = getopt (argc, argv, "h:")) != -1) { @@ -141,25 +159,14 @@ int main(int argc, char **argv) } } - ipgm_secret = discover_ipgm_secret(ctdldir); - if (ipgm_secret < 0) { - exit(1); - } - printf("Trying %s...\n", ctdldir); - sprintf(buf, "%s/citadel.socket", ctdldir); + sprintf(buf, "%s/citadel-admin.socket", ctdldir); server_socket = uds_connectsock(buf); if (server_socket < 0) { exit(1); } sock_getln(server_socket, buf, sizeof buf); - printf("%s\n", buf); - - sock_printf(server_socket, "IPGM %d\n", ipgm_secret); - sock_getln(server_socket, buf, sizeof buf); - printf("%s\n", buf); - if (buf[0] == '2') { do_main_loop(server_socket); }