X-Git-Url: http://git.tuebingen.mpg.de/?p=adu.git;a=blobdiff_plain;f=interactive.c;h=7327ee168eaf264c6830a1ed54052972ff244ce5;hp=a35a82b3867b75bff62ec44fb6da5592954b02cf;hb=78f42703571424f6d409a709fead7377f7a10616;hpb=99eaf79ebdb45f935eb9d8b60cc0889e09d5b6df diff --git a/interactive.c b/interactive.c index a35a82b..7327ee1 100644 --- a/interactive.c +++ b/interactive.c @@ -1,28 +1,49 @@ +/* + * Copyright (C) 2008 Andre Noll + * + * Licensed under the GPL v2. For licencing details see COPYING. + */ + +/** \file interactive.c \brief Commands for interactive mode. */ + #include /* isspace() */ #include "adu.h" #include "format.h" -#include "select.h" +#include "user.h" #include "string.h" +#include "select.cmdline.h" +#include "select.h" #include "error.h" -#include "cmdline.h" +/** + * Describes one valid command for interactive mode. + * + * When invoked in interactive mode, adu reads commands from stdin. There's a + * static array of all such commands. + */ struct interactive_command { + /** The name of the command. */ const char *name; + /** Pointer to The function that is being executed. */ int (*handler)(char *); + /** Help text. */ const char *desc; }; static struct uid_range *admissible_uids; static struct format_info *fi; +/** The set of supported interactive commands. */ #define INTERACTIVE_COMMANDS \ INTERACTIVE_COMMAND(set, "change the current configuration") \ INTERACTIVE_COMMAND(reset, "reset configuration to defaults") \ INTERACTIVE_COMMAND(help, "show list of commands and one-line descriptions") \ - INTERACTIVE_COMMAND(run, "start the query according to the current configuration") + INTERACTIVE_COMMAND(run, "start the query according to the current configuration") \ + INTERACTIVE_COMMAND(source, "read and execute interactive commands from a file") +/** \cond doxygen is not smart enough for this */ #define INTERACTIVE_COMMAND(name, desc) \ static int icom_ ## name (char *line); @@ -41,7 +62,9 @@ struct interactive_command icmds[] = { INTERACTIVE_COMMANDS {.name = NULL} }; +/** \endcond */ +/** Iterate over the list of all interactive commands. */ #define FOR_EACH_COMMAND(c) for (c = icmds; c->name; c++) static int read_input_line(char *line, size_t size) @@ -63,19 +86,30 @@ static int icom_help(__a_unused char *line) return 1; } +/** + * Print the list of commands with short descriptions. + */ void print_interactive_help(void) { - icom_help(NULL); + struct interactive_command *c; + FOR_EACH_COMMAND(c) + fprintf(stdout, "\t%s\t%s\n", c->name, c->desc); } static int icom_reset(__a_unused char *line) { + NOTICE_LOG("resetting configuration to default\n"); + free_format_info(fi); + fi = NULL; + free(admissible_uids); + admissible_uids = NULL; select_cmdline_parser_init(&select_conf); - return 1; + return parse_select_options(NULL, NULL, &admissible_uids, &fi); } static int icom_set(char *line) { + int ret; struct select_cmdline_parser_params params = { .override = 1, .initialize = 0, @@ -88,7 +122,14 @@ static int icom_set(char *line) return 1; } - return parse_select_options(line, ¶ms, &admissible_uids, &fi); + free_format_info(fi); + fi = NULL; + free(admissible_uids); + admissible_uids = NULL; + ret = parse_select_options(line, ¶ms, &admissible_uids, &fi); + if (ret >= 0) + return ret; + return icom_reset(NULL); } static int exec_interactive_command(char *line) @@ -113,6 +154,8 @@ static int exec_interactive_command(char *line) if (!*line) return 1; /* OK, we have a non-empty line */ + if (*line == '#') + return 1; cmd = adu_strdup(line); args = cmd + strcspn(cmd, delim); if (!*args) @@ -120,7 +163,7 @@ static int exec_interactive_command(char *line) else { *args = '\0'; args++; - /* let p point to the next non-whitespace char */ + /* let args point to the next non-whitespace char */ args += strspn(args, delim); if (!*args) args = NULL; @@ -137,12 +180,42 @@ static int exec_interactive_command(char *line) return ret; } +static int icom_source(char *args) +{ + char line[255]; + FILE *src = fopen(args, "r"); + int ret; + + if (!src) + return -ERRNO_TO_ERROR(errno); + while (fgets(line, sizeof(line), src)) { + ret = exec_interactive_command(line); + if (ret < 0) + goto out; + } + ret = 1; +out: + fclose(src); + return ret; +} + +/** + * The main function for interactive mode. + * + * \return Standard. + */ int com_interactive(void) { char line[255]; int ret = 1; select_cmdline_parser_init(&select_conf); + ret = parse_select_options(NULL, NULL, &admissible_uids, &fi); + if (ret< 0) + return ret; + ret = read_uid_file(); + if (ret < 0) + return ret; while (read_input_line(line, sizeof(line)) >= 0) { ret = exec_interactive_command(line); if (ret < 0)