diff options
Diffstat (limited to 'src/eclat.c')
-rw-r--r-- | src/eclat.c | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/src/eclat.c b/src/eclat.c new file mode 100644 index 0000000..3d2572d --- /dev/null +++ b/src/eclat.c @@ -0,0 +1,162 @@ +/* This file is part of Eclat. + Copyright (C) 2012 Sergey Poznyakoff. + + Eclat is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + Eclat is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Eclat. If not, see <http://www.gnu.org/licenses/>. */ + +#include "eclat.h" + +char *conffile = SYSCONFDIR "/eclat.conf" ; +int lint_mode; +int debug_level[ECLAT_DEBCAT_MAX]; +int dry_run_mode; +int preprocess_only = 0; + +char *default_host = "ec2.amazonaws.com"; +int use_ssl; +char *access_key; +char *secret_key; +char *region_name; +enum eclat_command eclat_command; + +char *url_base; + + +struct debug_trans { + const char *name; + size_t length; + int cat; +}; + +static struct debug_trans debug_trans[] = { +#define S(s) #s, sizeof(#s)-1 + { S(main), ECLAT_DEBCAT_MAIN }, + { S(cfgram), ECLAT_DEBCAT_CFGRAM }, + { S(cflex), ECLAT_DEBCAT_CFLEX }, + { S(conf), ECLAT_DEBCAT_CONF }, + { NULL } +}; + +static int +parse_debug_level(const char *arg) +{ + unsigned long cat, lev; + char *p; + + if (isascii(*arg) && isdigit(*arg)) { + cat = strtoul(arg, &p, 10); + if (cat > ECLAT_DEBCAT_MAX) + return -1; + } else { + size_t len = strcspn(arg, "."); + struct debug_trans *dp; + + for (dp = debug_trans; dp->name; dp++) + if (dp->length == len && + memcmp(dp->name, arg, len) == 0) + break; + + if (!dp->name) + return -1; + cat = dp->cat; + p = (char*) arg + len; + } + + if (*p == 0) + lev = 100; + else if (*p != '.') + return -1; + else { + lev = strtoul(p + 1, &p, 10); + if (*p) + return -1; + } + debug_level[cat] = lev; + return 0; +} + +#include "cmdline.h" + +eclat_command_handler_t handler_tab[] = { + NULL, + eclat_start_instance, + eclat_stop_instance +}; + +int +main(int argc, char **argv) +{ + int index, rc; + struct grecs_node *tree; + CURL *curl; + size_t size; + + set_program_name(argv[0]); + config_init(); + parse_options(argc, argv, &index); + + argc -= index; + argv += index; + + grecs_gram_trace(debug_level[ECLAT_DEBCAT_CFGRAM]); + grecs_lex_trace(debug_level[ECLAT_DEBCAT_CFLEX]); + + if (preprocess_only) + exit(grecs_preproc_run(conffile, grecs_preprocessor) ? + EX_CONFIG : 0); + + if (access(conffile, R_OK) == 0) { + tree = grecs_parse(conffile); + if (!tree) + exit(EX_CONFIG); + config_finish(tree); + /* Prevent texttab from being freed by grecs_tree_free. + FIXME: A dirty kludge, needed to preserve file names + in locus structures. A proper solution would be to have + our own texttab for that purpose. */ + tree->v.texttab = NULL; + grecs_tree_free(tree); + } else if (errno == ENOENT) { + warn("no configuration file"); + run_config_finish_hooks(); + } else + die(EX_OSFILE, "cannot access \"%s\": %s", + conffile, strerror(errno)); + + if (lint_mode) + exit(0); + + if (!secret_key) { + if (access_file_lookup(access_key, &access_key, &secret_key)) + die(EX_UNAVAILABLE, + "cannot find authentication credentials"); + } + + if (eclat_command == eclat_command_unspecified) + die(EX_USAGE, "no command given"); + + url_base = NULL; + size = 0; + if (use_ssl) + grecs_asprintf(&url_base, &size, "https://%s", default_host); + else + grecs_asprintf(&url_base, &size, "http://%s", default_host); + + + curl = curl_easy_init(); + if (!curl) + die(EX_UNAVAILABLE, "curl_easy_init failed"); + rc = handler_tab[eclat_command](curl, argc, argv); + curl_easy_cleanup(curl); + exit(rc); +} |