X-Git-Url: https://code.citadel.org/?p=citadel.git;a=blobdiff_plain;f=ctdlsh%2Fmain.c;h=cda33ec44c1fff20c562b3d02dc04576afbf815e;hp=6fc29315c51ab7d35cc5f1ae3f16297689e7dffe;hb=HEAD;hpb=ab71006c986efb39298cf0b9e5eed3988e8e2a74 diff --git a/ctdlsh/main.c b/ctdlsh/main.c index 6fc29315c..7e1d93e5b 100644 --- a/ctdlsh/main.c +++ b/ctdlsh/main.c @@ -1,16 +1,12 @@ /* - * (c) 2009-2012 by Art Cancro and citadel.org - * This program is released under the terms of the GNU General Public License v3. + * (c) 2009-2020 by Art Cancro and citadel.org + * This program is open source. It runs great on the Linux operating system. + * It's released under the General Public License (GPL) version 3. */ #include "ctdlsh.h" -int cmd_quit(int sock, char *cmdbuf) { - return(cmdret_exit); -} - - /* * Commands understood by ctdlsh */ @@ -21,34 +17,46 @@ typedef struct { } COMMAND; COMMAND commands[] = { - { "?", cmd_help, "Display this message" }, - { "help", cmd_help, "Display this message" }, - { "date", cmd_datetime, "Print the server's date and time" }, - { "config", cmd_config, "Configure the Citadel server" }, - { "export", cmd_export, "Export all Citadel databases" }, - { "shutdown", cmd_shutdown, "Shut down the Citadel server" }, - { "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" }, - { "exit", cmd_quit, "Quit using ctdlsh" }, - { "quit", cmd_quit, "Quit using ctdlsh" }, - { NULL, NULL, NULL } + { "?", cmd_help, "Display this message" }, + { "help", cmd_help, "Display this message" }, + { "date", cmd_datetime, "Print the server's date and time" }, + { "config", cmd_config, "Configure the Citadel server" }, + { "export", cmd_export, "Export all Citadel databases" }, + { "shutdown", cmd_shutdown, "Shut down the Citadel server" }, + { "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" }, + { "mailq", cmd_mailq, "Show the outbound email queue" }, + { NULL, NULL, NULL } }; -int cmd_help(int sock, char *cmdbuf) { + +int cmd_help(int sock, char *cmdbuf) +{ int i; - for (i=0; commands[i].func != NULL; ++i) { - printf("%-10s %s\n", commands[i].name, commands[i].doc); + 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; +int do_one_command(int server_socket, char *cmd) +{ + int i; + int ret; + 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); + } + } + return ret; +} + +char *command_name_generator(const char *text, int state) +{ + static int list_index, len; char *name; if (!state) { @@ -56,34 +64,25 @@ char *command_generator(const char *text, int state) { len = strlen(text); } - while (name = commands[list_index].name) { - ++list_index; - - if (!strncmp(name, text, len)) { - return(strdup(name)); + while (name = commands[list_index++].name) { + if (strncmp(name, text, len) == 0) { + return strdup(name); } } - return(NULL); + 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); +char **command_name_completion(const char *text, int start, int end) +{ + rl_attempted_completion_over = 1; + return rl_completion_matches(text, command_name_generator); } -void do_main_loop(int server_socket) { +void do_main_loop(int server_socket) +{ char *cmd = NULL; char prompt[1024]; char buf[1024]; @@ -98,7 +97,8 @@ void do_main_loop(int server_socket) { sock_getln(server_socket, buf, sizeof buf); if (buf[0] == '1') { i = 0; - while(sock_getln(server_socket, buf, sizeof buf), strcmp(buf, "000")) { + while (sock_getln(server_socket, buf, sizeof buf), + strcmp(buf, "000")) { if (i == 1) { sprintf(prompt, "\n%s> ", buf); } @@ -106,23 +106,13 @@ 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 ((ret != cmdret_exit) && (cmd = readline(prompt))) { - - if ((cmd) && (*cmd)) { + rl_attempted_completion_function = command_name_completion; + while ((cmd = readline(prompt)), cmd) { + if (*cmd) { add_history(cmd); - - 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); - } - } - + ret = do_one_command(server_socket, cmd); } - free(cmd); } } @@ -135,33 +125,32 @@ int main(int argc, char **argv) { int server_socket = 0; char buf[1024]; - int c; + int i; char *ctdldir = CTDLDIR; - - printf("\nCitadel administration shell (c) 2009-2016 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) { - switch(c) { - case 'h': - ctdldir = optarg; - break; - case '?': - if (optopt == 'h') { - fprintf(stderr, "Option -%c requires an argument\n", optopt); + char cmd[1024] = { 0 }; + int exitcode = 0; + + for (i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "-h")) { + ctdldir = argv[++i]; + } else { + if (strlen(cmd) > 0) { + strcat(cmd, " "); } - else { - fprintf(stderr, "Unknown option '-%c'\n", optopt); - fprintf(stderr, "usage: %s [-h citadel_dir]\n", argv[0]); - } - exit(1); + strcat(cmd, argv[i]); } } - printf("Trying %s...\n", ctdldir); + int is_interactive = ((strlen(cmd) == 0) ? 1 : 0); + + if (is_interactive) { + printf + ("\nCitadel administration shell (c) 2009-2020 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"); + printf("Connecting to Citadel server in %s...\n", ctdldir); + } + sprintf(buf, "%s/citadel-admin.socket", ctdldir); server_socket = uds_connectsock(buf); if (server_socket < 0) { @@ -170,13 +159,19 @@ int main(int argc, char **argv) sock_getln(server_socket, buf, sizeof buf); if (buf[0] == '2') { - printf("Connected: %s\n", buf); - do_main_loop(server_socket); + if (is_interactive) { + printf("Connected: %s\n", buf); + do_main_loop(server_socket); + } else { + exitcode = do_one_command(server_socket, cmd); + } } sock_puts(server_socket, "QUIT"); sock_getln(server_socket, buf, sizeof buf); - printf("%s\n", buf); + if (is_interactive) { + printf("%s\n", buf); + } close(server_socket); - exit(0); + exit(exitcode); }