poking around in the ctdlsh source because citadel proper is in deep freeze :)
[citadel] / ctdlsh / src / main.c
1 /*
2  * (c) 2009-2011 by Art Cancro and citadel.org
3  * This program is released under the terms of the GNU General Public License v3.
4  */
5
6 #include <config.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include <stdio.h>
10 #include <fcntl.h>
11 #include <errno.h>
12 #include <readline/readline.h>
13 #include "ctdlsh.h"
14
15 #define CTDLDIR "/appl/citadel"
16
17
18
19 int com_quit(char *cmdbuf) {
20         abort();
21 }
22
23
24
25
26 /*
27  * Commands understood by ctdlsh
28  */
29 typedef struct {
30         char *name;
31         rl_icpfunc_t *func;
32         char *doc;
33 } COMMAND;
34
35 COMMAND commands[] = {
36         {       "quit",         com_quit,       "Quit using ctdlsh"     },
37         {       "exit",         com_quit,       "Quit using ctdlsh"     },
38         {       NULL,           NULL,           NULL                    }
39 };
40
41
42 int discover_ipgm_secret(char *dirname) {
43         int fd;
44         struct partial_config ccc;
45         char configfile[1024];
46
47         sprintf(configfile, "%s/citadel.config", dirname);
48         fd = open(configfile, O_RDONLY);
49         if (fd < 0) {
50                 fprintf(stderr, "%s: %s\n", configfile, strerror(errno));
51                 return(-1);
52         }
53
54         if (read(fd, &ccc, sizeof(struct partial_config)) != sizeof(struct partial_config)) {
55                 fprintf(stderr, "%s: %s\n", configfile, strerror(errno));
56                 return(-1);
57         }
58         if (close(fd) != 0) {
59                 fprintf(stderr, "%s: %s\n", configfile, strerror(errno));
60                 return(-1);
61         }
62         return(ccc.c_ipgm_secret);
63 }
64
65
66 void do_main_loop(int server_socket) {
67         char *cmd = NULL;
68         char prompt[1024];
69         char buf[1024];
70         char server_reply[1024];
71         int i;
72
73         strcpy(prompt, "> ");
74
75         /* Do an INFO command and learn the hostname for the prompt */
76         sock_puts(server_socket, "INFO");
77         sock_getln(server_socket, buf, sizeof buf);
78         if (buf[0] == '1') {
79                 i = 0;
80                 while(sock_getln(server_socket, buf, sizeof buf), strcmp(buf, "000")) {
81                         if (i == 1) {
82                                 sprintf(prompt, "\n%s> ", buf);
83                         }
84                         ++i;
85                 }
86         }
87
88         /* Here we go ... main command loop */
89         while (cmd = readline(prompt)) {
90
91                 if ((cmd) && (*cmd)) {
92                         add_history(cmd);
93
94                         sock_puts(server_socket, cmd);
95                         sock_getln(server_socket, server_reply, sizeof server_reply);
96                         printf("%s\n", server_reply);
97
98                         if ((server_reply[0] == '4') || (server_reply[0] == '8')) {
99                                 /* we might consider putting something here */
100                                 sock_puts(server_socket, "000");
101                         }
102
103                         if ((server_reply[0] == '1') || (server_reply[0] == '8')) {
104                                 while(sock_getln(server_socket, buf, sizeof buf), strcmp(buf, "000")) {
105                                         printf("%s\n", buf);
106                                 }
107                         }
108
109                 }
110
111                 free(cmd);
112         }
113 }
114
115 int main(int argc, char **argv)
116 {
117         int server_socket = 0;
118         char buf[1024];
119         int ipgm_secret = (-1);
120         int c;
121         char *ctdldir = CTDLDIR;
122
123         printf("\nCitadel administration shell v" PACKAGE_VERSION "\n");
124         printf("(c) 2009-2011 citadel.org GPLv3\n");
125
126         opterr = 0;
127         while ((c = getopt (argc, argv, "h:")) != -1) {
128                 switch(c) {
129                 case 'h':
130                         ctdldir = optarg;
131                         break;
132                 case '?':
133                         if (optopt == 'h') {
134                                 fprintf(stderr, "Option -%c requires an argument\n", optopt);
135                         }
136                         else {
137                                 fprintf(stderr, "Unknown option '-%c'\n", optopt);
138                                 fprintf(stderr, "usage: %s [-h citadel_dir]\n", argv[0]);
139                         }
140                         exit(1);
141                 }
142         }
143
144         ipgm_secret = discover_ipgm_secret(ctdldir);
145         if (ipgm_secret < 0) {
146                 exit(1);
147         }
148
149         printf("Trying %s...\n", ctdldir);
150         sprintf(buf, "%s/citadel.socket", ctdldir);
151         server_socket = uds_connectsock(buf);
152         if (server_socket < 0) {
153                 exit(1);
154         }
155
156         sock_getln(server_socket, buf, sizeof buf);
157         printf("%s\n", buf);
158
159         sock_printf(server_socket, "IPGM %d\n", ipgm_secret);
160         sock_getln(server_socket, buf, sizeof buf);
161         printf("%s\n", buf);
162
163         if (buf[0] == '2') {
164                 do_main_loop(server_socket);
165         }
166
167         sock_puts(server_socket, "QUIT");
168         sock_getln(server_socket, buf, sizeof buf);
169         printf("%s\n", buf);
170         close(server_socket);
171         exit(0);
172 }