diff options
Diffstat (limited to 'lib/envmap.c')
-rw-r--r-- | lib/envmap.c | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/lib/envmap.c b/lib/envmap.c new file mode 100644 index 0000000..2e3f8aa --- /dev/null +++ b/lib/envmap.c @@ -0,0 +1,154 @@ +/* This file is part of Eclat. + Copyright (C) 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 <config.h> +#include <string.h> +#include <ctype.h> +#include <sysexits.h> +#include "libeclat.h" +#include "wordsplit.h" +#include "grecs.h" + +static int +isnumstr(const char *p) +{ + for (; *p; p++) + if (!isdigit(*p)) + return 0; + return 1; +} + +void +eclat_encode_devmap(struct ec2_query *q, struct grecs_list *list) +{ + int i; + char *bufptr = NULL; + size_t bufsize = 0; + struct grecs_list_entry *ep; + + if (!list) + return; + for (i = 1, ep = list->head; ep; ep = ep->next, i++) { + char *dev = ep->data; + char *p = strchr(dev, '='); + + if (!p) + die(EX_USAGE, "malformed device mapping: %s", dev); + *p++ = 0; + + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d.DeviceName", + i); + eclat_query_add_param(q, bufptr, dev); + + if (strcmp(p, "none") == 0) { + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d.NoDevice", + i); + eclat_query_add_param(q, bufptr, NULL); + } else if (strncmp(p, "ephemeral", 9) == 0) { + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d.VirtualName", + i); + eclat_query_add_param(q, bufptr, p); + } else { + struct wordsplit ws; + + /* [snapshot-id]:[volume-size]:[true|false]:[standard|io1[:iops]] */ + ws.ws_delim = ":"; + if (wordsplit(p, &ws, + WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM)) + die(EX_SOFTWARE, + "failed to split string %s: %s", + p, + wordsplit_strerror(&ws)); + if (ws.ws_wordc == 1) { + if (strncmp(ws.ws_wordv[0], "snap-", 5) == 0) { + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d." + "Ebs.SnapshotId", + i); + } else if (isnumstr(ws.ws_wordv[0])) { + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d." + "Ebs.VolumeSize", + i); + } else + die(EX_USAGE, + "unrecognized word \"%s\", " + "expected either a snapshot ID, " + "or disk size", + ws.ws_wordv[0]); + eclat_query_add_param(q, bufptr, + ws.ws_wordv[0]); + } else { + if (ws.ws_wordv[0]) { + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d." + "Ebs.SnapshotId", + i); + eclat_query_add_param(q, bufptr, + ws.ws_wordv[0]); + } + + if (ws.ws_wordv[1]) { + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d." + "Ebs.VolumeSize", + i); + eclat_query_add_param(q, bufptr, + ws.ws_wordv[1]); + } + } + + switch (ws.ws_wordc) { + default: + die(EX_USAGE, + "too many parts in device mapping \"%s\"", + p); + case 5: + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d.Ebs.Iops", + i); + eclat_query_add_param(q, bufptr, + ws.ws_wordv[4]); + /* fall through */ + case 4: + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d.Ebs.VolumeType", + i); + eclat_query_add_param(q, bufptr, + ws.ws_wordv[3]); + /* fall through */ + case 3: + if (strcmp(ws.ws_wordv[2], "false") && + strcmp(ws.ws_wordv[2], "true")) + die(EX_USAGE, + "expected \"true\" or \"false\", " + "but found \"%s\"", + ws.ws_wordv[2]); + grecs_asprintf(&bufptr, &bufsize, + "BlockDeviceMapping.%d." + "Ebs.DeleteOnTermination", + i); + eclat_query_add_param(q, bufptr, + ws.ws_wordv[2]); + } + wordsplit_free(&ws); + } + } + free(bufptr); +} |