aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-05-04 23:01:13 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2013-05-04 23:09:30 +0300
commit9ead52193e7edb563ec58ef1a15ee9291b418c8e (patch)
tree4990815b2bc4fc93c2d0ef72d1038ffaf32f9a83
parente59f4da93d617eab8a5c0f85681aed1351011a03 (diff)
downloadeclat-9ead52193e7edb563ec58ef1a15ee9291b418c8e.tar.gz
eclat-9ead52193e7edb563ec58ef1a15ee9291b418c8e.tar.bz2
Implement EC2 map.
EC2 map allows to use AWS services as eclap maps. For example, one may use an EC2 tag to map resource names to resource IDs, etc. * src/ec2map.c: New file. * src/io.c: New file. * src/Makefile.am (eclat_SOURCES): Add new files. * src/eclat.c (dump,eclat_trace_fun) (dumpxml,write_callback): Move to io.c (main): Register ec2 map. Use eclat_io framework. * src/eclat.h (eclat_io): New struct. (eclat_io_init, eclat_io_free) (eclat_io_shutdown, eclat_io_finish): New functions. (eclat_map_drv_ec2): New extern.
-rw-r--r--src/Makefile.am2
-rw-r--r--src/ec2map.c230
-rw-r--r--src/eclat.c191
-rw-r--r--src/eclat.h13
-rw-r--r--src/io.c255
5 files changed, 510 insertions, 181 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 6b796b1..a402157 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -28,10 +28,12 @@ eclat_SOURCES=\
deimg.c\
devol.c\
disasaddr.c\
+ ec2map.c\
eclat.c\
eclat.h\
genericcl.c\
getconout.c\
+ io.c\
lsaddr.c\
lsattr.c\
lsiattr.c\
diff --git a/src/ec2map.c b/src/ec2map.c
new file mode 100644
index 0000000..6eb7e8b
--- /dev/null
+++ b/src/ec2map.c
@@ -0,0 +1,230 @@
+/* This file is part of Eclat.
+ Copyright (C) 2012, 2013 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"
+#include <errno.h>
+
+/*
+ map "SnapshotId" {
+ type ec2;
+ action DescribeImages;
+ arguments ("Owner.1=self",
+ "Filter.1.Name=tag:Name",
+ "Filter.1.Value.1=${key});
+ return ".DescribeImagesResponse.imagesSet.item.imageId";
+ }
+*/
+
+struct ec2_map {
+ char *action;
+ struct grecs_list *args;
+ char *ret;
+ struct eclat_io *io;
+};
+
+static struct grecs_keyword ec2_map_kw[] = {
+ { "type", "'ec2", "Set map type",
+ grecs_type_null },
+ { "key", "<arg: string>", "key expression",
+ grecs_type_null },
+ { "action", NULL, "EC2 action",
+ grecs_type_string, GRECS_DFLT, NULL,
+ offsetof(struct ec2_map, action) },
+ { "return", NULL, "return element",
+ grecs_type_string, GRECS_DFLT, NULL,
+ offsetof(struct ec2_map, ret) },
+ { "arguments", NULL, "EC2 action",
+ grecs_type_string, GRECS_LIST, NULL,
+ offsetof(struct ec2_map, args) },
+ { NULL }
+};
+
+static void
+ec2_map_free(int dbg, void *data)
+{
+ struct ec2_map *map = data;
+ eclat_io_free(map->io);
+ free(map->action);
+ free(map->ret);
+ grecs_list_free(map->args);
+ free(map);
+}
+
+static void
+ec2_map_confhelp()
+{
+ static struct grecs_keyword ec2_map_top[] = {
+ { "map", "name: string",
+ "Configuration for a EC2 map",
+ grecs_type_section, GRECS_INAC, NULL, 0, NULL, NULL,
+ ec2_map_kw },
+ { NULL }
+ };
+ grecs_print_statement_array(ec2_map_top, 1, 0, stdout);
+}
+
+static int
+ec2_map_config(int dbg, struct grecs_node *node, void *data)
+{
+ int i;
+ int ec = 0;
+ struct ec2_map *map, **return_map = data;
+
+ map = grecs_zalloc(sizeof(*map));
+ for (i = 0; ec2_map_kw[i].ident; i++)
+ ec2_map_kw[i].varptr = map;
+ if (grecs_tree_process(node->down, ec2_map_kw)) {
+ ec2_map_free(dbg, map);
+ return eclat_map_failure;
+ }
+ if (!map->action) {
+ grecs_error(&node->locus, 0, "no action statement");
+ ec++;
+ }
+ if (!map->ret) {
+ grecs_error(&node->locus, 0, "no return statement");
+ ec++;
+ }
+ if (!map->args) {
+ grecs_error(&node->locus, 0, "no arguments statement");
+ ec++;
+ }
+ if (ec) {
+ ec2_map_free(dbg, map);
+ return eclat_map_failure;
+ }
+
+ *return_map = map;
+ return eclat_map_ok;
+}
+
+static int
+ec2_map_open(int dbg, void *data)
+{
+ struct ec2_map *map = data;
+
+ map->io = eclat_io_init(0);
+ if (!map->io) {
+ err("cannot open EC2 database");
+ return eclat_map_failure;
+ }
+ return eclat_map_ok;
+}
+
+static int
+ec2_map_close(int dbg, void *data)
+{
+ struct ec2_map *map = data;
+
+ eclat_io_free(map->io);
+ map->io = NULL;
+ return 0;
+}
+
+static int
+ec2_map_get(int dbg, int dir, void *data, const char *key, char **return_value)
+{
+ struct ec2_map *map = data;
+ struct ec2_query *q;
+ struct grecs_list_entry *ep;
+ struct wordsplit ws;
+ int wsflags;
+ char *env[3];
+ struct grecs_node *tree, *node;
+ int rc;
+
+ q = eclat_query_create(use_ssl ? EC2_QF_HTTPS : 0, endpoint, "/");
+ eclat_query_add_param(q, "Action", map->action);
+
+ env[0] = "key";
+ env[1] = key;
+ env[2] = NULL;
+
+ ws.ws_env = env;
+ ws.ws_error = err;
+ wsflags = WRDSF_NOSPLIT | WRDSF_NOCMD |
+ WRDSF_ENV | WRDSF_ENV_KV | WRDSF_WARNUNDEF | WRDSF_ERROR;
+
+ rc = 0;
+ for (ep = map->args->head; ep; ep = ep->next) {
+ char *p;
+
+ if (wordsplit((char *)ep->data, &ws, wsflags)) {
+ rc = 1;
+ break;
+ }
+ wsflags |= WRDSF_REUSE;
+ p = strchr(ws.ws_wordv[0], '=');
+ if (p) {
+ *p++ = 0;
+ eclat_query_add_param(q, ws.ws_wordv[0], p);
+ } else
+ eclat_query_add_param(q, ws.ws_wordv[0], "");
+ }
+
+ if (wsflags & WRDSF_REUSE)
+ wordsplit_free(&ws);
+
+ if (rc) {
+ eclat_query_free(q);
+ return eclat_map_failure;
+ }
+
+ rc = eclat_send_query(map->io->curl, q);
+
+ if (rc)
+ return eclat_map_failure;
+
+ tree = eclat_io_finish(map->io);
+
+
+ node = grecs_find_node(tree, map->ret);
+
+ if (debug_category[dbg].level > 1) {
+ debug(dbg, 2, ("Got node:"));
+ grecs_print_node(node, GRECS_NODE_FLAG_DEFAULT, stderr);
+ fputc('\n', stderr);
+ }
+
+ rc = eclat_map_not_found;
+ if (node) {
+ if (node->type == grecs_node_stmt &&
+ node->v.value->type == GRECS_TYPE_STRING) {
+ *return_value = grecs_strdup(node->v.value->v.string);
+ rc = eclat_map_ok;
+ } else {
+ rc = eclat_map_failure;
+ }
+ }
+
+ grecs_tree_free(tree);
+
+ return rc;
+}
+
+struct eclat_map_drv eclat_map_drv_ec2 = {
+ "ec2",
+ ec2_map_config,
+ ec2_map_open,
+ ec2_map_close,
+ ec2_map_get,
+ ec2_map_free,
+ ec2_map_confhelp
+};
+
+
+
+
diff --git a/src/eclat.c b/src/eclat.c
index c00c795..7048fe5 100644
--- a/src/eclat.c
+++ b/src/eclat.c
@@ -60,137 +60,6 @@ debug_init()
}
-static void
-dump(const char *text, FILE *stream, unsigned char *ptr, size_t size)
-{
- size_t i;
- size_t c;
- unsigned int width = 0x10;
- int hex = debug_level(ECLAT_DEBCAT_CURL) > 2;
-
- if (!hex)
- /* without the hex output, we can fit more on screen */
- width = 0x40;
-
- fprintf(stream, "%s, %zd bytes (0x%zx)\n", text, size, size);
-
- for (i = 0; i < size; i += width) {
- fprintf(stream, "%04zx: ", i);
-
- if (hex) {
- for (c = 0; c < width; c++)
- if (i+c < size)
- fprintf(stream, "%02x ", ptr[i+c]);
- else
- fputs(" ", stream);
- }
-
- for(c = 0; (c < width) && (i+c < size); c++) {
- /* check for CRLf; if found, skip past and start a
- new line of output */
- if (!hex && (i + c + 1 < size) &&
- ptr[i+c] == '\r' && ptr[i+c+1] == '\n') {
- i += (c + 2 -width);
- break;
- }
- fprintf(stream, "%c",
- isprint(ptr[i+c]) ? ptr[i+c] : '.');
- /* check again for CRLF, to avoid an extra \n if
- it's at width */
- if (!hex && (i + c + 2 < size) &&
- ptr[i+c+1] == '\r' && ptr[i+c+2] == '\n') {
- i += (c + 3 - width);
- break;
- }
- }
- fputc('\n', stream); /* newline */
- }
- fflush(stream);
-}
-
-static int
-eclat_trace_fun(CURL *handle, curl_infotype type,
- char *data, size_t size,
- void *userp)
-{
-/* struct data *config = (struct data *)userp;*/
- const char *text;
-
- switch (type) {
- case CURLINFO_TEXT:
- fprintf(stderr, "== Info: %s", data);
- default: /* in case a new one is introduced to shock us */
- return 0;
-
- case CURLINFO_HEADER_OUT:
- text = "=> Send header";
- break;
- case CURLINFO_DATA_OUT:
- text = "=> Send data";
- break;
- case CURLINFO_SSL_DATA_OUT:
- text = "=> Send SSL data";
- break;
- case CURLINFO_HEADER_IN:
- text = "<= Recv header";
- break;
- case CURLINFO_DATA_IN:
- text = "<= Recv data";
- break;
- case CURLINFO_SSL_DATA_IN:
- text = "<= Recv SSL data";
- break;
- }
-
- dump(text, stderr, (unsigned char *)data, size);
- return 0;
-}
-
-static void
-dumpxml(void *ptr, size_t realsize)
-{
- static int open_failed = 0;
-
- if (open_failed)
- return;
- if (!xml_dump_file) {
- xml_dump_file = fopen(XML_DUMP_FILE_NAME, "w");
- if (!xml_dump_file) {
- err("cannot open dump file %s: %s",
- XML_DUMP_FILE_NAME, strerror(errno));
- open_failed = 1;
- return;
- }
- }
- fwrite(ptr, realsize, 1, xml_dump_file);
-}
-
-static size_t
-write_callback(void *ptr, size_t size, size_t nmemb, void *data)
-{
- size_t realsize = size * nmemb;
- XML_Parser parser = data;
- enum XML_Status status;
- int line = XML_GetCurrentLineNumber(parser);
- int column = XML_GetCurrentColumnNumber(parser);
-
- if (debug_level(ECLAT_DEBCAT_MAIN) >= 10)
- dumpxml(ptr, realsize);
-
- status = XML_Parse(parser, ptr, realsize, 0);
- if (status == XML_STATUS_ERROR) {
- enum XML_Error error = XML_GetErrorCode(parser);
-
- line = XML_GetCurrentLineNumber(parser);
- column = XML_GetCurrentColumnNumber(parser);
-
- /* FIXME: better diagnostics. */
- die(EX_SOFTWARE, "XML parse error at %d:%d: %s",
- line, column, XML_ErrorString(error));
- }
- return realsize;
-}
-
static int
node_ident_cmp(struct grecs_node const *a, struct grecs_node const *b)
{
@@ -492,8 +361,8 @@ print_matching_commands(const char *pat)
size_t patlen = strlen (pat);
for (cp = cmdtab; cp < cmdtab + cmdcnt; cp++) {
- if (cp->name && strlen (cp->name) >= patlen &&
- memcmp (cp->name, pat, patlen) == 0)
+ if (cp->name && strlen(cp->name) >= patlen &&
+ memcmp(cp->name, pat, patlen) == 0)
printf("%s\n", cp->name);
if (cp->ident && ident_matches(cp->ident, pat) != NO_MATCH)
printf("%s\n", cp->ident);
@@ -785,9 +654,7 @@ main(int argc, char **argv)
{
int rc;
struct grecs_node *tree;
- CURL *curl;
- XML_Parser parser;
- eclat_partial_tree_t part;
+ struct eclat_io *io;
struct grecs_node *xmltree;
forlan_eval_env_t env = NULL;
struct eclat_command *command = NULL;
@@ -808,6 +675,7 @@ main(int argc, char **argv)
#ifdef WITH_LDAP
eclat_map_drv_register(&eclat_map_drv_ldap);
#endif
+ eclat_map_drv_register(&eclat_map_drv_ec2);
sortcmds();
config_init();
parse_options(&argc, &argv);
@@ -887,45 +755,8 @@ main(int argc, char **argv)
"cannot find authentication credentials");
}
debug(ECLAT_DEBCAT_MAIN, 1, ("using access key %s", access_key));
-
- curl = curl_easy_init();
- if (!curl)
- die(EX_UNAVAILABLE, "curl_easy_init failed");
-
- if (debug_level(ECLAT_DEBCAT_CURL)) {
- curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
- if (debug_level(ECLAT_DEBCAT_CURL) > 1)
- curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
- eclat_trace_fun);
- }
-
- /* Create XML parser */
- parser = XML_ParserCreate("UTF-8");
- if (!parser)
- die(EX_SOFTWARE, "cannot create XML parser");
-
- XML_SetElementHandler(parser,
- eclat_partial_tree_start_handler,
- eclat_partial_tree_end_handler);
- XML_SetCharacterDataHandler(parser,
- eclat_partial_tree_data_handler);
- part = eclat_partial_tree_create();
- XML_SetUserData(parser, part);
-
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, parser);
- if (use_ssl) {
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,
- (long) ssl_verify_peer);
- if (ssl_verify_peer) {
- if (ssl_ca_file)
- curl_easy_setopt(curl, CURLOPT_CAINFO,
- ssl_ca_file);
- if (ssl_ca_path)
- curl_easy_setopt(curl, CURLOPT_CAPATH,
- ssl_ca_path);
- }
- }
+
+ io = eclat_io_init(1);
if (confirm_mode == eclat_confirm_unspecified)
confirm_mode = command->confirm;
@@ -933,19 +764,17 @@ main(int argc, char **argv)
/* Prepare environment */
memset(&cmdenv, 0, sizeof(cmdenv));
cmdenv.cmd = command;
- cmdenv.curl = curl;
-
+ cmdenv.curl = io->curl;
+
rc = eclat_do_command(&cmdenv, command, argc, argv);
if (rc)
exit(rc);
- curl_easy_cleanup(curl);
- XML_Parse(parser, "", 0, 1);
+ xmltree = eclat_io_finish(io);
+
if (xml_dump_file)
fclose(xml_dump_file);
- xmltree = eclat_partial_tree_finish(part);
-
if (sort_option)
grecs_tree_sort(xmltree, node_ident_cmp);
diff --git a/src/eclat.h b/src/eclat.h
index 72691ca..3ece7fd 100644
--- a/src/eclat.h
+++ b/src/eclat.h
@@ -87,7 +87,19 @@ struct eclat_command {
struct eclat_command *find_command_name(const char *name);
int eclat_do_command(eclat_command_env_t *env, struct eclat_command *command,
int argc, char **argv);
+
+struct eclat_io {
+ XML_Parser parser;
+ eclat_partial_tree_t part;
+ CURL *curl;
+};
+
+struct eclat_io *eclat_io_init(int errfatal);
+void eclat_io_free(struct eclat_io *io);
+void eclat_io_shutdown(struct eclat_io *io);
+struct grecs_node *eclat_io_finish(struct eclat_io *io);
+
int eclat_start_instance(eclat_command_env_t *env, int argc, char **argv);
int eclat_stop_instance(eclat_command_env_t *env, int argc, char **argv);
int eclat_reboot_instance(eclat_command_env_t *env, int argc, char **argv);
@@ -196,3 +208,4 @@ extern struct grecs_proginfo *generic_proginfo;
void set_command_confirmation(const char *name, enum eclat_confirm_mode cfmode,
grecs_locus_t *locus);
+extern struct eclat_map_drv eclat_map_drv_ec2;
diff --git a/src/io.c b/src/io.c
new file mode 100644
index 0000000..26c3ffe
--- /dev/null
+++ b/src/io.c
@@ -0,0 +1,255 @@
+/* This file is part of Eclat.
+ Copyright (C) 2012, 2013 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"
+
+extern FILE *xml_dump_file;
+
+
+static void
+dump(const char *text, FILE *stream, unsigned char *ptr, size_t size)
+{
+ size_t i;
+ size_t c;
+ unsigned int width = 0x10;
+ int hex = debug_level(ECLAT_DEBCAT_CURL) > 2;
+
+ if (!hex)
+ /* without the hex output, we can fit more on screen */
+ width = 0x40;
+
+ fprintf(stream, "%s, %zd bytes (0x%zx)\n", text, size, size);
+
+ for (i = 0; i < size; i += width) {
+ fprintf(stream, "%04zx: ", i);
+
+ if (hex) {
+ for (c = 0; c < width; c++)
+ if (i+c < size)
+ fprintf(stream, "%02x ", ptr[i+c]);
+ else
+ fputs(" ", stream);
+ }
+
+ for(c = 0; (c < width) && (i+c < size); c++) {
+ /* check for CRLf; if found, skip past and start a
+ new line of output */
+ if (!hex && (i + c + 1 < size) &&
+ ptr[i+c] == '\r' && ptr[i+c+1] == '\n') {
+ i += (c + 2 -width);
+ break;
+ }
+ fprintf(stream, "%c",
+ isprint(ptr[i+c]) ? ptr[i+c] : '.');
+ /* check again for CRLF, to avoid an extra \n if
+ it's at width */
+ if (!hex && (i + c + 2 < size) &&
+ ptr[i+c+1] == '\r' && ptr[i+c+2] == '\n') {
+ i += (c + 3 - width);
+ break;
+ }
+ }
+ fputc('\n', stream); /* newline */
+ }
+ fflush(stream);
+}
+
+static int
+eclat_trace_fun(CURL *handle, curl_infotype type,
+ char *data, size_t size,
+ void *userp)
+{
+/* struct data *config = (struct data *)userp;*/
+ const char *text;
+
+ switch (type) {
+ case CURLINFO_TEXT:
+ fprintf(stderr, "== Info: %s", data);
+ default: /* in case a new one is introduced to shock us */
+ return 0;
+
+ case CURLINFO_HEADER_OUT:
+ text = "=> Send header";
+ break;
+ case CURLINFO_DATA_OUT:
+ text = "=> Send data";
+ break;
+ case CURLINFO_SSL_DATA_OUT:
+ text = "=> Send SSL data";
+ break;
+ case CURLINFO_HEADER_IN:
+ text = "<= Recv header";
+ break;
+ case CURLINFO_DATA_IN:
+ text = "<= Recv data";
+ break;
+ case CURLINFO_SSL_DATA_IN:
+ text = "<= Recv SSL data";
+ break;
+ }
+
+ dump(text, stderr, (unsigned char *)data, size);
+ return 0;
+}
+
+static void
+dumpxml(void *ptr, size_t realsize)
+{
+ static int open_failed = 0;
+
+ if (open_failed)
+ return;
+ if (!xml_dump_file) {
+ xml_dump_file = fopen(XML_DUMP_FILE_NAME, "w");
+ if (!xml_dump_file) {
+ err("cannot open dump file %s: %s",
+ XML_DUMP_FILE_NAME, strerror(errno));
+ open_failed = 1;
+ return;
+ }
+ }
+ fwrite(ptr, realsize, 1, xml_dump_file);
+}
+
+static size_t
+write_callback(void *ptr, size_t size, size_t nmemb, void *data)
+{
+ size_t realsize = size * nmemb;
+ XML_Parser parser = data;
+ enum XML_Status status;
+ int line = XML_GetCurrentLineNumber(parser);
+ int column = XML_GetCurrentColumnNumber(parser);
+
+ if (debug_level(ECLAT_DEBCAT_MAIN) >= 10)
+ dumpxml(ptr, realsize);
+
+ status = XML_Parse(parser, ptr, realsize, 0);
+ if (status == XML_STATUS_ERROR) {
+ enum XML_Error error = XML_GetErrorCode(parser);
+
+ line = XML_GetCurrentLineNumber(parser);
+ column = XML_GetCurrentColumnNumber(parser);
+
+ /* FIXME: better diagnostics. */
+ die(EX_SOFTWARE, "XML parse error at %d:%d: %s",
+ line, column, XML_ErrorString(error));
+ }
+ return realsize;
+}
+
+static int
+eclat_io_setup(struct eclat_io *io, int errfatal)
+{
+ io->curl = curl_easy_init();
+ if (!io->curl) {
+ if (errfatal)
+ die(EX_UNAVAILABLE, "curl_easy_init failed");
+ else {
+ err("curl_easy_init failed");
+ return 1;
+ }
+ }
+
+ if (debug_level(ECLAT_DEBCAT_CURL)) {
+ curl_easy_setopt(io->curl, CURLOPT_VERBOSE, 1L);
+ if (debug_level(ECLAT_DEBCAT_CURL) > 1)
+ curl_easy_setopt(io->curl, CURLOPT_DEBUGFUNCTION,
+ eclat_trace_fun);
+ }
+
+ /* Create XML parser */
+ io->parser = XML_ParserCreate("UTF-8");
+ if (!io->parser) {
+ if (errfatal)
+ die(EX_SOFTWARE, "cannot create XML parser");
+ else {
+ err("cannot create XML parser");
+ return 1;
+ }
+ }
+
+ XML_SetElementHandler(io->parser,
+ eclat_partial_tree_start_handler,
+ eclat_partial_tree_end_handler);
+ XML_SetCharacterDataHandler(io->parser,
+ eclat_partial_tree_data_handler);
+ io->part = eclat_partial_tree_create();
+ XML_SetUserData(io->parser, io->part);
+
+ curl_easy_setopt(io->curl, CURLOPT_WRITEFUNCTION, write_callback);
+ curl_easy_setopt(io->curl, CURLOPT_WRITEDATA, io->parser);
+ if (use_ssl) {
+ curl_easy_setopt(io->curl, CURLOPT_SSL_VERIFYPEER,
+ (long) ssl_verify_peer);
+ if (ssl_verify_peer) {
+ if (ssl_ca_file)
+ curl_easy_setopt(io->curl, CURLOPT_CAINFO,
+ ssl_ca_file);
+ if (ssl_ca_path)
+ curl_easy_setopt(io->curl, CURLOPT_CAPATH,
+ ssl_ca_path);
+ }
+ }
+ return 0;
+}
+
+void
+eclat_io_free(struct eclat_io *io)
+{
+ if (!io)
+ return;
+ eclat_io_shutdown(io);
+ if (io->part)
+ eclat_partial_tree_destroy(io->part);
+ if (io->parser)
+ XML_ParserFree(io->parser);
+ free(io);
+}
+
+struct eclat_io *
+eclat_io_init(int onerr)
+{
+ struct eclat_io *io;
+
+ io = grecs_zalloc(sizeof(*io));
+ if (eclat_io_setup(io, onerr)) {
+ eclat_io_free(io);
+ return NULL;
+ }
+ return io;
+}
+
+void
+eclat_io_shutdown(struct eclat_io *io)
+{
+ if (io->curl) {
+ curl_easy_cleanup(io->curl);
+ io->curl = NULL;
+ }
+}
+
+struct grecs_node *
+eclat_io_finish(struct eclat_io *io)
+{
+ struct grecs_node *p;
+
+ eclat_io_shutdown(io);
+ XML_Parse(io->parser, "", 0, 1);
+ p = eclat_partial_tree_finish(io->part);
+ io->part = NULL;
+ return p;
+}
+

Return to:

Send suggestions and report system problems to the System administrator.