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 { "quit", cmd_quit, "Quit using ctdlsh" },
27 { "exit", cmd_quit, "Quit using ctdlsh" },
28 { "date", cmd_datetime, "Print the server's date and time" },
29 { "time", cmd_datetime, "Print the server's date and time" },
30 { "passwd", cmd_passwd, "Set or change an account password" },
31 { "shutdown", cmd_shutdown, "Shut down the Citadel server" },
36 int cmd_help(int sock, char *cmdbuf) {
39 for (i=0; commands[i].func != NULL; ++i) {
40 printf("%-10s %s\n", commands[i].name, commands[i].doc);
45 /* Auto-completer function */
46 char *command_generator(const char *text, int state) {
47 static int list_index;
56 while (name = commands[list_index].name) {
59 if (!strncmp(name, text, len)) {
68 /* Auto-completer function */
69 char **ctdlsh_completion(const char *text, int start, int end) {
70 char **matches = (char **) NULL;
73 matches = rl_completion_matches(text, command_generator);
76 rl_bind_key('\t', rl_abort);
83 void do_main_loop(int server_socket) {
87 char server_reply[1024];
93 /* Do an INFO command and learn the hostname for the prompt */
94 sock_puts(server_socket, "INFO");
95 sock_getln(server_socket, buf, sizeof buf);
98 while(sock_getln(server_socket, buf, sizeof buf), strcmp(buf, "000")) {
100 sprintf(prompt, "\n%s> ", buf);
106 /* Tell libreadline how we will help with auto-completion of commands */
107 rl_attempted_completion_function = ctdlsh_completion;
109 /* Here we go ... main command loop */
110 while ((ret != cmdret_exit) && (cmd = readline(prompt))) {
112 if ((cmd) && (*cmd)) {
115 for (i=0; commands[i].func != NULL; ++i) {
116 if (!strncasecmp(cmd, commands[i].name, strlen(commands[i].name))) {
117 ret = (*commands[i].func) (server_socket, cmd);
129 * If you don't know what main() does by now you probably shouldn't be reading this code.
131 int main(int argc, char **argv)
133 int server_socket = 0;
136 char *ctdldir = CTDLDIR;
138 printf("\nCitadel administration shell v" PACKAGE_VERSION " (c) 2009-2012 by citadel.org\n"
139 "This is open source software made available to you under the terms\n"
140 "of the GNU General Public License v3. All other rights reserved.\n"
144 while ((c = getopt (argc, argv, "h:")) != -1) {
151 fprintf(stderr, "Option -%c requires an argument\n", optopt);
154 fprintf(stderr, "Unknown option '-%c'\n", optopt);
155 fprintf(stderr, "usage: %s [-h citadel_dir]\n", argv[0]);
161 printf("Trying %s...\n", ctdldir);
162 sprintf(buf, "%s/citadel-admin.socket", ctdldir);
163 server_socket = uds_connectsock(buf);
164 if (server_socket < 0) {
168 sock_getln(server_socket, buf, sizeof buf);
170 do_main_loop(server_socket);
173 sock_puts(server_socket, "QUIT");
174 sock_getln(server_socket, buf, sizeof buf);
176 close(server_socket);