]> git.tuebingen.mpg.de Git - adu.git/blob - interactive.c
295be371b384cd102534914f4c4a0903a89ddab2
[adu.git] / interactive.c
1 #include "adu.h"
2 #include "string.h"
3 #include "error.h"
4 #include "cmdline.h"
5
6 struct interactive_command {
7         const char *name;
8         int (*handler)(char *);
9         const char *desc;
10 };
11
12 static struct uid_range *admissible_uids;
13
14 #define INTERACTIVE_COMMANDS \
15         INTERACTIVE_COMMAND(dump, "dump the current configuration") \
16         INTERACTIVE_COMMAND(set, "change the current configuration") \
17         INTERACTIVE_COMMAND(reset, "reset configuration to defaults") \
18         INTERACTIVE_COMMAND(help, "show list of commands and one-line descriptions") \
19         INTERACTIVE_COMMAND(run, "start the query according to the current options")
20
21
22 #define INTERACTIVE_COMMAND(name, desc) \
23         static int icom_ ## name (char *line);
24
25 INTERACTIVE_COMMANDS
26
27 #undef INTERACTIVE_COMMAND
28
29 #define INTERACTIVE_COMMAND(_name, _desc) \
30         { \
31         .name = #_name, \
32         .handler = icom_ ## _name, \
33         .desc = _desc \
34         },
35
36 struct interactive_command icmds[] = {
37         INTERACTIVE_COMMANDS
38         {.name  = NULL}
39 };
40
41 #define FOR_EACH_COMMAND(c) for (c = icmds; c->name; c++)
42
43 static int read_input_line(char *line, size_t size)
44 {
45         return fgets(line, size, stdin)? 1 : -1;
46 }
47
48 static int icom_run(__a_unused char *line)
49 {
50         return run_select_query(admissible_uids);
51 }
52
53 static int icom_help(__a_unused char *line)
54 {
55         struct interactive_command *c;
56
57         FOR_EACH_COMMAND(c)
58                 fprintf(stdout, "%s\t%s\n", c->name, c->desc);
59         return 1;
60 }
61
62 static int icom_reset(__a_unused char *line)
63 {
64         select_cmdline_parser_init(&select_conf);
65         return 1;
66 }
67
68 static int icom_set(char *line)
69 {
70         struct select_cmdline_parser_params params = {
71                 .override = 1,
72                 .initialize = 0,
73                 .check_required = 1,
74                 .check_ambiguity = 0,
75                 .print_errors = 1
76         };
77         return parse_select_options(line, &params, &admissible_uids);
78 }
79
80 static int icom_dump(__a_unused char *line)
81 {
82         ERROR_LOG("dump: %s\n", select_conf.format_arg);
83         select_cmdline_parser_dump(stdout, &select_conf);
84         return 1;
85 }
86
87 static int exec_interactive_command(char *line)
88 {
89         const char const *delim = "\t\n ";
90         int i;
91         char *cmd = adu_strdup(line + strspn(line, delim));
92         char *p = cmd + strcspn(cmd, delim);
93         int ret = -E_SYNTAX;
94
95         *p = '\0';
96         p++;
97         for (i = 0; icmds[i].name; i++) {
98                 ERROR_LOG("name: %s, cmd: %s.\n", icmds[i].name, cmd);
99                 if (strcmp(icmds[i].name, cmd))
100                         continue;
101                 ERROR_LOG("exec cmd: %s, args: %s\n", cmd, p);
102                 ret = icmds[i].handler(p);
103                 break;
104         }
105         free(cmd);
106         return ret;
107 }
108
109 int com_interactive(void)
110 {
111         char line[255];
112         int ret = 1;
113
114         select_cmdline_parser_init(&select_conf);
115         while (read_input_line(line, sizeof(line)) >= 0) {
116                 size_t len = strlen(line);
117                 if (!len)
118                         continue;
119                 if (line[len - 1] == '\n')
120                         line[len - 1] = '\0';
121                 ret = exec_interactive_command(line);
122                 if (ret < 0)
123                         printf("%s\n", adu_strerror(-ret));
124         }
125         return ret;
126 }