aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Makefile.am7
-rw-r--r--lib/filemap.c140
-rw-r--r--lib/libeclat.h42
-rw-r--r--lib/map.c335
-rw-r--r--src/accfile.c1
-rw-r--r--src/asscaddr.c1
-rw-r--r--src/cmdline.opt6
-rw-r--r--src/config.c11
-rw-r--r--src/dscrinstattr.c1
-rw-r--r--src/dscrinsts.c1
-rw-r--r--src/dscrinststat.c3
-rw-r--r--src/dscrsecgrps.c8
-rw-r--r--src/eclat.c4
-rw-r--r--src/eclat.h2
-rw-r--r--src/getconout.c1
-rw-r--r--src/startinst.c1
-rw-r--r--src/util.c30
17 files changed, 589 insertions, 5 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 50b28a5..e7b9d20 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -16,6 +16,9 @@
noinst_LIBRARIES=libeclat.a
+maps = \
+ filemap.c
+
libeclat_a_SOURCES=\
base64.c\
diag.c\
@@ -26,6 +29,7 @@ libeclat_a_SOURCES=\
forlanlex.l\
hmac_sha1.c\
libeclat.h\
+ map.c\
q2url.c\
qaddparm.c\
qcreat.c\
@@ -35,7 +39,8 @@ libeclat_a_SOURCES=\
sha1.c\
sha1.h\
urlencode.c\
- xmltree.c
+ xmltree.c\
+ $(maps)
AM_LDFLAGS = $(CURL_LIBS)
INCLUDES = -I$(top_srcdir)/grecs/src/ $(CURL_CFLAGS)
diff --git a/lib/filemap.c b/lib/filemap.c
new file mode 100644
index 0000000..bced0d4
--- /dev/null
+++ b/lib/filemap.c
@@ -0,0 +1,140 @@
+/* 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 "libeclat.h"
+#include <errno.h>
+
+struct filemap {
+ char *name;
+ FILE *fp;
+ struct grecs_locus locus;
+};
+
+static int
+filemap_config(int dbg, struct grecs_node *node, void *data)
+{
+ struct filemap *filemap, **return_filemap = data;
+ const char *filename;
+ struct grecs_node *p;
+
+ if (eclat_get_string_node(node, "file", 0, &p))
+ return eclat_map_failure;
+ filemap = grecs_malloc(sizeof(*filemap));
+ filemap->name = grecs_strdup(p->v.value->v.string);
+ filemap->locus = p->locus;
+ *return_filemap = filemap;
+ return eclat_map_ok;
+}
+
+static void
+filemap_free(int dbg, void *data)
+{
+ struct filemap *filemap = data;
+ free(filemap->name);
+ free(filemap);
+}
+
+static int
+filemap_open(int dbg, void *data)
+{
+ struct filemap *filemap = data;
+
+ filemap->fp = fopen(filemap->name, "r");
+ if (!filemap->fp) {
+ grecs_error(&filemap->locus, errno, "cannot open file");
+ return eclat_map_failure;
+ }
+ return eclat_map_ok;
+}
+
+
+static int
+filemap_close(int dbg, void *data)
+{
+ struct filemap *filemap = data;
+ fclose(filemap->fp);
+ return eclat_map_ok;
+}
+
+static void
+skipline(FILE *fp)
+{
+ int c;
+
+ while ((c = getc(fp)) != EOF && c != '\n')
+ ;
+}
+
+static int
+filemap_get(int dbg, void *data, const char *key, char **return_value)
+{
+ struct filemap *filemap = data;
+ FILE *fp = filemap->fp;
+ int line = 0;
+ int rc, c;
+ const char *p;
+
+ rewind(fp);
+ while ((c = getc(fp)) != EOF) {
+ line++;
+ while (c != EOF && (c == ' ' || c == '\t'))
+ c = getc(fp);
+ if (c == '\n')
+ continue;
+ if (c == '#') {
+ skipline(fp);
+ continue;
+ }
+ if (c == EOF)
+ break;
+
+ for (p = key; c != EOF && c != ':' && *p == c; p++)
+ c = getc(fp);
+ if (c == EOF)
+ break;
+ if (c == '\n')
+ continue;
+ if (c == ':')
+ break;
+ skipline(fp);
+ }
+
+ if (c == ':') {
+ struct grecs_txtacc *acc;
+
+ debug(dbg, 2, ("%s:%d: found key", filemap->name, line));
+ acc = grecs_txtacc_create();
+ while ((c = getc(fp)) != EOF && c != '\n')
+ grecs_txtacc_grow_char(acc, c);
+ grecs_txtacc_grow_char(acc, 0);
+ *return_value = grecs_txtacc_finish(acc, 1);
+ grecs_txtacc_free(acc);
+ rc = eclat_map_ok;
+ } else
+ rc = eclat_map_not_found;
+
+ return rc;
+}
+
+struct eclat_map_drv eclat_map_drv_file = {
+ "file",
+ filemap_config,
+ filemap_open,
+ filemap_close,
+ filemap_get,
+ filemap_free
+};
+
diff --git a/lib/libeclat.h b/lib/libeclat.h
index 5f37cc9..1f16d5d 100644
--- a/lib/libeclat.h
+++ b/lib/libeclat.h
@@ -101,6 +101,48 @@ void eclat_partial_tree_data_handler(void *data, const XML_Char *s, int len);
void eclat_partial_tree_start_handler(void *data, const XML_Char *name,
const XML_Char **atts);
void eclat_partial_tree_end_handler(void *data, const XML_Char *name);
+
+#define ECLAT_MAP_OPEN 0x01
+
+struct eclat_map_drv {
+ const char *name;
+ int (*map_config)(int, struct grecs_node *, void *);
+ int (*map_open)(int, void *);
+ int (*map_close)(int, void *);
+ int (*map_get)(int, void *, const char *, char **);
+ void (*map_free)(int, void *);
+};
+struct eclat_map {
+ char *name;
+ char *keytrans;
+ struct eclat_map_drv *drv;
+ void *data;
+ int flags;
+};
+
+enum eclat_map_status {
+ eclat_map_ok,
+ eclat_map_failure,
+ eclat_map_not_found
+};
+void eclat_map_init(void);
+struct eclat_map *eclat_map_lookup(const char *name);
+int eclat_map_config(struct grecs_node *node, struct eclat_map **return_map);
+void eclat_map_free(struct eclat_map *map);
+int eclat_map_open(struct eclat_map *map);
+int eclat_map_close(struct eclat_map *map);
+int eclat_map_get(struct eclat_map *map, const char *key, char **value);
+const char *eclat_map_strerror(int rc);
+int eclat_map_drv_register(struct eclat_map_drv *drv);
+void eclat_map_foreach(int (*fun)(struct eclat_map *, void *), void *data);
+void eclat_map_free_all(void);
+
+int eclat_get_string_node(struct grecs_node *node, const char *name,
+ int optional,
+ struct grecs_node **pret);
+
+extern struct eclat_map_drv eclat_map_drv_file;
+
diff --git a/lib/map.c b/lib/map.c
new file mode 100644
index 0000000..5a8d2fd
--- /dev/null
+++ b/lib/map.c
@@ -0,0 +1,335 @@
+/* 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 "libeclat.h"
+#include "wordsplit.h"
+#include <sysexits.h>
+#include <string.h>
+
+static int map_dbg = -1;
+static struct grecs_symtab *openmap_symtab, *mapdrv_symtab;
+
+void
+eclat_map_init()
+{
+ map_dbg = debug_register("map");
+}
+
+int
+eclat_get_string_node(struct grecs_node *node, const char *name,
+ int optional,
+ struct grecs_node **pret)
+{
+ struct grecs_node *p = grecs_find_node(node->down, name);
+
+ if (!p) {
+ if (optional)
+ return eclat_map_not_found;
+ grecs_error(&node->locus, 0,
+ "no \"%s\" statement found", name);
+ return eclat_map_failure;
+ }
+
+ if (p->type != grecs_node_stmt) {
+ grecs_error(&p->locus, 0, "must be simple statement");
+ return eclat_map_failure;
+ }
+
+ if (p->v.value->type != GRECS_TYPE_STRING) {
+ grecs_error(&p->locus, 0, "must be scalar");
+ return eclat_map_failure;
+ }
+
+ *pret = p;
+ return eclat_map_ok;
+}
+
+static int
+drv_copy(void *a, void *b)
+{
+ struct eclat_map_drv *drva = a;
+ struct eclat_map_drv *drvb = b;
+
+ *drva = *drvb;
+ drva->name = strdup(drvb->name);
+ return drva->name == NULL;
+}
+
+int
+eclat_map_drv_register(struct eclat_map_drv *drv)
+{
+ struct eclat_map_drv *p;
+ int install;
+
+ if (!mapdrv_symtab) {
+ mapdrv_symtab = grecs_symtab_create(sizeof(*drv),
+ NULL,
+ NULL,
+ drv_copy,
+ NULL,
+ NULL);
+ if (!mapdrv_symtab)
+ grecs_alloc_die();
+ }
+ install = 1;
+ if (!grecs_symtab_lookup_or_install(mapdrv_symtab, drv, &install))
+ die(EX_SOFTWARE, "cannot install map");
+ return install ? eclat_map_ok : eclat_map_failure;
+}
+
+struct eclat_map *
+eclat_map_lookup(const char *name)
+{
+ struct eclat_map key;
+
+ if (!openmap_symtab)
+ return NULL;
+ key.name = (char*) name;
+ return grecs_symtab_lookup_or_install(openmap_symtab, &key, NULL);
+}
+
+static void
+map_free(void *p)
+{
+ struct eclat_map *map = p;
+ if (map->flags & ECLAT_MAP_OPEN)
+ eclat_map_close(map);
+ if (map->data && map->drv->map_free)
+ map->drv->map_free(map_dbg, map->data);
+ free(map->name);
+ free(map->keytrans);
+ free(map);
+}
+
+int
+eclat_map_config(struct grecs_node *node, struct eclat_map **return_map)
+{
+ char *mapname;
+ struct grecs_node *p;
+ struct eclat_map key, *map;
+ struct eclat_map_drv dkey, *drv;
+ int install, rc;
+
+ if (node->v.value->type != GRECS_TYPE_STRING) {
+ grecs_error(&p->locus, 0, "value must be scalar");
+ return eclat_map_failure;
+ }
+
+ mapname = node->v.value->v.string;
+
+ if (debug_level(map_dbg) > 1)
+ diag(&node->locus, "debug", "configuring map \"%s\"",
+ mapname);
+ map = eclat_map_lookup(mapname);
+ if (map) {
+ debug(map_dbg, 1,
+ ("map \"%s\" already configured", mapname));
+ *return_map = map;
+ return eclat_map_ok;
+ }
+
+ if (eclat_get_string_node(node, "type", 0, &p))
+ return eclat_map_failure;
+
+ dkey.name = p->v.value->v.string;
+ if (!mapdrv_symtab) {
+ grecs_error(&p->locus, 0, "no drivers compiled");
+ return eclat_map_failure;
+ }
+
+ drv = grecs_symtab_lookup_or_install(mapdrv_symtab, &dkey, NULL);
+ if (!drv) {
+ grecs_error(&p->locus, 0, "no driver for this type");
+ return eclat_map_failure;
+ }
+
+ if (!openmap_symtab) {
+ openmap_symtab = grecs_symtab_create(sizeof(key),
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ map_free);
+ if (!openmap_symtab)
+ grecs_alloc_die();
+ }
+ install = 1;
+ key.name = (char*) mapname;
+ map = grecs_symtab_lookup_or_install(openmap_symtab, &key, &install);
+ if (!map)
+ die(EX_SOFTWARE, "cannot install map");
+ map->drv = drv;
+
+ rc = drv->map_config(map_dbg, node, &map->data);
+ if (rc != eclat_map_ok) {
+ grecs_error(&node->locus, 0, "map configration failed");
+ eclat_map_free(map);
+ return eclat_map_failure;
+ }
+
+ if (eclat_get_string_node(node, "key", 1, &p) == 0)
+ map->keytrans = grecs_strdup(p->v.value->v.string);
+
+ debug(map_dbg, 1, ("map \"%s\" configured", mapname));
+
+ *return_map = map;
+ return eclat_map_ok;
+}
+
+void
+eclat_map_free(struct eclat_map *map)
+{
+ grecs_symtab_remove(openmap_symtab, map);
+}
+
+int
+eclat_map_open(struct eclat_map *map)
+{
+ debug(map_dbg, 1, ("opening map \"%s\"", map->name));
+
+ if (map->flags & ECLAT_MAP_OPEN) {
+ debug(map_dbg, 1, ("map \"%s\" already open", map->name));
+ return eclat_map_ok;
+ }
+
+ if (map->drv->map_open(map_dbg, map->data)) {
+ err("failed to open map %s", map->name);
+ return eclat_map_failure;
+ }
+
+ debug(map_dbg, 1, ("map \"%s\" opened successfully", map->name));
+ map->flags |= ECLAT_MAP_OPEN;
+ return eclat_map_ok;
+}
+
+int
+eclat_map_close(struct eclat_map *map)
+{
+ int rc = eclat_map_ok;
+
+ debug(map_dbg, 1, ("closing map \"%s\"", map->name));
+ if (!(map->flags & ECLAT_MAP_OPEN)) {
+ debug(map_dbg, 1, ("map \"%s\" not open", map->name));
+ return eclat_map_ok;
+ }
+ if (map->drv->map_close)
+ rc = map->drv->map_close(map_dbg, map->data);
+
+ if (rc == eclat_map_ok) {
+ debug(map_dbg, 1,
+ ("map \"%s\" closed successfully", map->name));
+ map->flags &= ~ECLAT_MAP_OPEN;
+ } else
+ err("failed to close map %s", map->name);
+
+ return rc;
+}
+
+int
+eclat_map_get(struct eclat_map *map, const char *key, char **value)
+{
+ int rc;
+ struct wordsplit ws;
+
+ debug(map_dbg, 1,
+ ("looking up \"%s\" in map \"%s\"", key, map->name));
+ if (!(map->flags & ECLAT_MAP_OPEN)) {
+ debug(map_dbg, 1, ("map \"%s\" not open", map->name));
+ return eclat_map_failure;
+ }
+
+ if (map->keytrans) {
+ const char *kve[5];
+ kve[0] = "key";
+ kve[1] = key;
+ kve[2] = "map";
+ kve[3] = map->name;
+ kve[4] = NULL;
+
+ ws.ws_env = kve;
+
+ if (wordsplit(map->keytrans, &ws,
+ WRDSF_NOSPLIT | WRDSF_NOCMD |
+ WRDSF_ENV | WRDSF_ENV_KV))
+ die(EX_SOFTWARE, "error transforming key: %s",
+ wordsplit_strerror(&ws));
+ debug(map_dbg, 1,
+ ("transformed key \"%s\" => \"%s\"",
+ key, ws.ws_wordv[0]));
+ key = ws.ws_wordv[0];
+ }
+
+ rc = map->drv->map_get(map_dbg, map->data, key, value);
+
+ if (map->keytrans)
+ wordsplit_free(&ws);
+
+ debug(map_dbg, 1, ("result: \"%s\"", eclat_map_strerror(rc)));
+ if (rc == eclat_map_ok)
+ debug(map_dbg, 2, ("found value: \"%s\"", *value));
+ return rc;
+}
+
+const char *
+eclat_map_strerror(int rc)
+{
+ switch (rc) {
+ case eclat_map_ok:
+ return "success";
+ case eclat_map_failure:
+ return "failure";
+ case eclat_map_not_found:
+ return "not found";
+ }
+ return "unknown error";
+}
+
+struct foreach_closure {
+ int (*fun)(struct eclat_map *, void *);
+ void *data;
+};
+
+static int
+map_foreach(void *item, void *data)
+{
+ struct eclat_map *map = item;
+ struct foreach_closure *cp = data;
+
+ return cp->fun(map, cp->data);
+}
+
+void
+eclat_map_foreach(int (*fun)(struct eclat_map *, void *), void *data)
+{
+ struct foreach_closure cl;
+
+ if (!openmap_symtab)
+ return;
+
+ cl.fun = fun;
+ cl.data = data;
+ grecs_symtab_enumerate(openmap_symtab, map_foreach, &cl);
+}
+
+void
+eclat_map_free_all()
+{
+ if (openmap_symtab) {
+ grecs_symtab_free(openmap_symtab);
+ openmap_symtab = NULL;
+ }
+}
+
diff --git a/src/accfile.c b/src/accfile.c
index 07c9c2e..3aa9bdb 100644
--- a/src/accfile.c
+++ b/src/accfile.c
@@ -121,6 +121,7 @@ access_file_lookup(const char *filename,
grecs_txtacc_grow_char(acc, c);
grecs_txtacc_grow_char(acc, 0);
*secret_key_ptr = grecs_txtacc_finish(acc, 1);
+ grecs_txtacc_free(acc);
rc = 0;
} else
rc = 1;
diff --git a/src/asscaddr.c b/src/asscaddr.c
index a5ba86e..ea4488d 100644
--- a/src/asscaddr.c
+++ b/src/asscaddr.c
@@ -36,6 +36,7 @@ eclat_associate_address(CURL *curl, int argc, char **argv)
q = eclat_query_create(use_ssl ? EC2_QF_HTTPS : 0, endpoint, "/");
eclat_query_add_param(q, "Action", "AssociateAddress");
+ translate_ids(1, argv, "InstanceId");
eclat_query_add_param(q, "InstanceId", argv[0]);
if (vpc) {
eclat_query_add_param(q, "AllocationId", argv[1]);
diff --git a/src/cmdline.opt b/src/cmdline.opt
index c19f628..94330ff 100644
--- a/src/cmdline.opt
+++ b/src/cmdline.opt
@@ -132,6 +132,12 @@ BEGIN
sort_option = 1;
END
+OPTION(translate,x,,
+ [<translate resource IDs>])
+BEGIN
+ translate_option = 1;
+END
+
GROUP(Preprocessor control)
OPTION(include-directory,I,DIR,
diff --git a/src/config.c b/src/config.c
index 69835b9..7271b36 100644
--- a/src/config.c
+++ b/src/config.c
@@ -169,6 +169,8 @@ static struct grecs_keyword eclat_kw[] = {
grecs_type_string, GRECS_MULT, NULL, 0, cb_define_format },
{ "format-file", "file", "Read format from <file>",
grecs_type_string, GRECS_DFLT, &format_file },
+ { "map", "name: string", "Configure a map",
+ grecs_type_section, GRECS_INAC },
{ NULL }
};
@@ -207,6 +209,15 @@ config_finish(struct grecs_node *tree)
{
struct grecs_node *node;
+ for (node = tree; node; node = node->next) {
+ struct eclat_map *map;
+
+ node = grecs_find_node(node, "map");
+ if (!node)
+ break;
+ eclat_map_config(node, &map);
+ }
+
grecs_tree_reduce(tree, eclat_kw, GRECS_AGGR);
if (debug_level(ECLAT_DEBCAT_CONF)) {
grecs_print_node(tree, GRECS_NODE_FLAG_DEFAULT, stderr);
diff --git a/src/dscrinstattr.c b/src/dscrinstattr.c
index 543e456..7193bda 100644
--- a/src/dscrinstattr.c
+++ b/src/dscrinstattr.c
@@ -67,6 +67,7 @@ eclat_describe_instance_attribute(CURL *curl, int argc, char **argv)
argc, argv, &i);
argv += i;
argc -= i;
+ translate_ids(argc, argv, "InstanceId");
if (argc != 2)
die(EX_USAGE, "wrong number of arguments");
diff --git a/src/dscrinsts.c b/src/dscrinsts.c
index 145c50d..865c2ce 100644
--- a/src/dscrinsts.c
+++ b/src/dscrinsts.c
@@ -147,6 +147,7 @@ eclat_describe_instances(CURL *curl, int argc, char **argv)
parse_options(argc, argv, &i);
argv += i;
argc -= i;
+ translate_ids(argc, argv, "InstanceId");
q = describe_query_create(curl, "DescribeInstances", argc, argv,
"InstanceId");
diff --git a/src/dscrinststat.c b/src/dscrinststat.c
index 241e9ed..67e761a 100644
--- a/src/dscrinststat.c
+++ b/src/dscrinststat.c
@@ -27,7 +27,8 @@ eclat_describe_instance_status(CURL *curl, int argc, char **argv)
parse_options(argc, argv, &i);
argv += i;
argc -= i;
-
+ translate_ids(argc, argv, "InstanceId");
+
q = describe_query_create(curl, "DescribeInstanceStatus", argc, argv,
"InstanceId");
diff --git a/src/dscrsecgrps.c b/src/dscrsecgrps.c
index 7049ddb..238c569 100644
--- a/src/dscrsecgrps.c
+++ b/src/dscrsecgrps.c
@@ -23,13 +23,15 @@ eclat_describe_security_groups(CURL *curl, int argc, char **argv)
{
int i;
struct ec2_query *q;
-
+ const char *resid = name_option ? "GroupName" : "GroupId";
+
parse_options(argc, argv, &i);
argv += i;
argc -= i;
-
+ translate_ids(argc, argv, resid);
+
q = describe_query_create(curl, "DescribeSecurityGroups", argc, argv,
- name_option ? "GroupName" : "GroupId");
+ resid);
return eclat_send_query(curl, q);
}
diff --git a/src/eclat.c b/src/eclat.c
index f229e77..704ac56 100644
--- a/src/eclat.c
+++ b/src/eclat.c
@@ -592,6 +592,8 @@ main(int argc, char **argv)
proginfo.print_help_hook = listcmd;
debug_init();
forlan_init();
+ eclat_map_init();
+ eclat_map_drv_register(&eclat_map_drv_file);
config_init();
parse_options(argc, argv, &index);
@@ -706,5 +708,7 @@ main(int argc, char **argv)
fputc('\n', stdout);
}
+ eclat_map_free_all();
+
exit(rc);
}
diff --git a/src/eclat.h b/src/eclat.h
index a82a28a..f371ea2 100644
--- a/src/eclat.h
+++ b/src/eclat.h
@@ -45,6 +45,7 @@ extern char *access_file_name;
extern char *access_key;
extern char *secret_key;
extern char *format_file;
+extern int translate_option;
typedef int (*config_finish_hook_t) (void*);
@@ -100,6 +101,7 @@ struct filter_descr *available_filters;
void list_filters(FILE *fp);
int get_scr_cols(void);
+void translate_ids(int argc, char **argv, const char *mapname);
int get_access_creds(const char *id, char **access_key_ptr,
char **secret_key_ptr);
diff --git a/src/getconout.c b/src/getconout.c
index a5aab97..5ea5044 100644
--- a/src/getconout.c
+++ b/src/getconout.c
@@ -34,6 +34,7 @@ eclat_get_console_output(CURL *curl, int argc, char **argv)
die(EX_USAGE, "not enough arguments");
else if (i > 1)
die(EX_USAGE, "only one argument is allowed");
+ translate_ids(argc, argv, "InstanceId");
q = describe_query_create(curl, "GetConsoleOutput", argc, argv,
"InstanceId");
diff --git a/src/startinst.c b/src/startinst.c
index d284694..3c34526 100644
--- a/src/startinst.c
+++ b/src/startinst.c
@@ -35,6 +35,7 @@ start_stop_instance(CURL *curl, const char *action, int argc, char **argv)
if (argc == 0)
die(EX_USAGE, "no instance ids");
+ translate_ids(argc, argv, "InstanceId");
q = eclat_query_create(use_ssl ? EC2_QF_HTTPS : 0, endpoint, "/");
eclat_query_add_param(q, "Action", action);
diff --git a/src/util.c b/src/util.c
index 79b7576..a6357c4 100644
--- a/src/util.c
+++ b/src/util.c
@@ -18,6 +18,36 @@
#include <termios.h>
#include <sys/ioctl.h>
+int translate_option;
+
+void
+translate_ids(int argc, char **argv, const char *mapname)
+{
+ int i;
+ struct eclat_map *map;
+ char *val;
+
+ if (!translate_option)
+ return;
+ map = eclat_map_lookup(mapname);
+ if (!map)
+ die(EX_UNAVAILABLE, "no such map: %s", mapname);
+
+ if (eclat_map_open(map) != eclat_map_ok)
+ exit(EX_UNAVAILABLE);
+
+ for (i = 0; i < argc; i++) {
+ if (!strchr(argv[i], '=')) {
+ int rc = eclat_map_get(map, argv[i], &val);
+ if (rc != eclat_map_ok) {
+ die(EX_UNAVAILABLE, "cannot translate %s: %s",
+ argv[i], eclat_map_strerror(rc));
+ }
+ argv[i] = val;
+ }
+ }
+}
+
int
get_scr_cols()
{

Return to:

Send suggestions and report system problems to the System administrator.