2 * (c) 2009-2012 by Art Cancro and citadel.org
3 * This program is released under the terms of the GNU General Public License v3.
9 int cmd_quit(int sock, char *cmdbuf) {
15 * Commands understood by ctdlsh
19 ctdlsh_cmdfunc_t *func;
23 COMMAND commands[] = {
24 { "?", cmd_help, "Display this message" },
25 { "help", cmd_help, "Display this message" },
26 { "date", cmd_datetime, "Print the server's date and time" },
27 { "exit", cmd_quit, "Quit using ctdlsh" },
28 { "export", cmd_export, "Export all Citadel databases" },
29 { "shutdown", cmd_shutdown, "Shut down the Citadel server" },
30 { "time", cmd_datetime, "Print the server's date and time" },
31 { "passwd", cmd_passwd, "Set or change an account password" },
32 { "quit", cmd_quit, "Quit using ctdlsh" },
33 { "who", cmd_who, "Display a list of online users" },
38 int cmd_help(int sock, char *cmdbuf) {
41 for (i=0; commands[i].func != NULL; ++i) {
42 printf("%-10s %s\n", commands[i].name, commands[i].doc);
47 /* Auto-completer function */
48 char *command_generator(const char *text, int state) {
49 static int list_index;
58 while (name = commands[list_index].name) {
61 if (!strncmp(name, text, len)) {
70 /* Auto-completer function */
71 char **ctdlsh_completion(const char *text, int start, int end) {
72 char **matches = (char **) NULL;
75 matches = rl_completion_matches(text, command_generator);
78 rl_bind_key('\t', rl_abort);
85 void do_main_loop(int server_socket) {
89 char server_reply[1024];
95 /* Do an INFO command and learn the hostname for the prompt */
96 sock_puts(server_socket, "INFO");
97 sock_getln(server_socket, buf, sizeof buf);
100 while(sock_getln(server_socket, buf, sizeof buf), strcmp(buf, "000")) {
102 sprintf(prompt, "\n%s> ", buf);
108 /* Tell libreadline how we will help with auto-completion of commands */
109 rl_attempted_completion_function = ctdlsh_completion;
111 /* Here we go ... main command loop */
112 while ((ret != cmdret_exit) && (cmd = readline(prompt))) {
114 if ((cmd) && (*cmd)) {
117 for (i=0; commands[i].func != NULL; ++i) {
118 if (!strncasecmp(cmd, commands[i].name, strlen(commands[i].name))) {
119 ret = (*commands[i].func) (server_socket, cmd);
131 * If you don't know what main() does by now you probably shouldn't be reading this code.
133 int main(int argc, char **argv)
135 int server_socket = 0;
138 char *ctdldir = CTDLDIR;
140 printf("\nCitadel administration shell v" PACKAGE_VERSION " (c) 2009-2012 by citadel.org\n"
141 "This is open source software made available to you under the terms\n"
142 "of the GNU General Public License v3. All other rights reserved.\n"
146 while ((c = getopt (argc, argv, "h:")) != -1) {
153 fprintf(stderr, "Option -%c requires an argument\n", optopt);
156 fprintf(stderr, "Unknown option '-%c'\n", optopt);
157 fprintf(stderr, "usage: %s [-h citadel_dir]\n", argv[0]);
163 printf("Trying %s...\n", ctdldir);
164 sprintf(buf, "%s/citadel-admin.socket", ctdldir);
165 server_socket = uds_connectsock(buf);
166 if (server_socket < 0) {
170 sock_getln(server_socket, buf, sizeof buf);
172 do_main_loop(server_socket);
175 sock_puts(server_socket, "QUIT");
176 sock_getln(server_socket, buf, sizeof buf);
178 close(server_socket);