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 { "who", cmd_who, "Display a list of online users" },
32 { "shutdown", cmd_shutdown, "Shut down the Citadel server" },
37 int cmd_help(int sock, char *cmdbuf) {
40 for (i=0; commands[i].func != NULL; ++i) {
41 printf("%-10s %s\n", commands[i].name, commands[i].doc);
46 /* Auto-completer function */
47 char *command_generator(const char *text, int state) {
48 static int list_index;
57 while (name = commands[list_index].name) {
60 if (!strncmp(name, text, len)) {
69 /* Auto-completer function */
70 char **ctdlsh_completion(const char *text, int start, int end) {
71 char **matches = (char **) NULL;
74 matches = rl_completion_matches(text, command_generator);
77 rl_bind_key('\t', rl_abort);
84 void do_main_loop(int server_socket) {
88 char server_reply[1024];
94 /* Do an INFO command and learn the hostname for the prompt */
95 sock_puts(server_socket, "INFO");
96 sock_getln(server_socket, buf, sizeof buf);
99 while(sock_getln(server_socket, buf, sizeof buf), strcmp(buf, "000")) {
101 sprintf(prompt, "\n%s> ", buf);
107 /* Tell libreadline how we will help with auto-completion of commands */
108 rl_attempted_completion_function = ctdlsh_completion;
110 /* Here we go ... main command loop */
111 while ((ret != cmdret_exit) && (cmd = readline(prompt))) {
113 if ((cmd) && (*cmd)) {
116 for (i=0; commands[i].func != NULL; ++i) {
117 if (!strncasecmp(cmd, commands[i].name, strlen(commands[i].name))) {
118 ret = (*commands[i].func) (server_socket, cmd);
130 * If you don't know what main() does by now you probably shouldn't be reading this code.
132 int main(int argc, char **argv)
134 int server_socket = 0;
137 char *ctdldir = CTDLDIR;
139 printf("\nCitadel administration shell v" PACKAGE_VERSION " (c) 2009-2012 by citadel.org\n"
140 "This is open source software made available to you under the terms\n"
141 "of the GNU General Public License v3. All other rights reserved.\n"
145 while ((c = getopt (argc, argv, "h:")) != -1) {
152 fprintf(stderr, "Option -%c requires an argument\n", optopt);
155 fprintf(stderr, "Unknown option '-%c'\n", optopt);
156 fprintf(stderr, "usage: %s [-h citadel_dir]\n", argv[0]);
162 printf("Trying %s...\n", ctdldir);
163 sprintf(buf, "%s/citadel-admin.socket", ctdldir);
164 server_socket = uds_connectsock(buf);
165 if (server_socket < 0) {
169 sock_getln(server_socket, buf, sizeof buf);
171 do_main_loop(server_socket);
174 sock_puts(server_socket, "QUIT");
175 sock_getln(server_socket, buf, sizeof buf);
177 close(server_socket);