/* This file is part of Eclat. Copyright (C) 2012-2014 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 . */ #include "eclat.h" static char *attrs[] = { "InstanceType.Value", "Kernel.Value", "Ramdisk.Value", "UserData.Value", "DisableApiTermination.Value", "InstanceInitiatedShutdownBehavior.Value", "BlockDeviceMapping.ebs", "SourceDestCheck.Value", "GroupId.%d", "EbsOptimized", NULL }; static char * canonattrname(const char *arg, size_t *plen) { size_t len = strlen(arg); int i; for (i = 0; attrs[i]; i++) { size_t alen = strcspn(attrs[i], "."); if (alen == len && strncasecmp(arg, attrs[i], len) == 0) { *plen = len; return attrs[i]; } } return NULL; } static void list_mod_attrs(FILE *fp) { size_t ncols = get_scr_cols(); int i, col, len, alen; char *delim = ""; fprintf(fp, "Available attributes are:\n"); col = 0; for (i = 0; attrs[i]; i++) { alen = strcspn(attrs[i], "."); len = strlen(delim) + alen; if (col + len > ncols) { fprintf(fp, ",\n%*.*s", alen, alen, attrs[i]); col = strlen(attrs[i]); } else col += fprintf(fp, "%s%*.*s", delim, alen, alen, attrs[i]); delim = ", "; } fputc('\n', fp); fputc('\n', fp); } int eclat_modify_instance_attribute(eclat_command_env_t *env, int argc, char **argv) { int i; struct ec2_query *q = env->query; const char *canonattr; size_t canonlen; char *bufptr = NULL; size_t bufsize = 0; generic_proginfo->args_doc = "INST-ID ATTR VALUE [VALUE...]"; generic_proginfo->print_help_hook = list_mod_attrs; generic_parse_options(env->cmd, "modify the attribute of an instance", argc, argv, &i); argv += i; argc -= i; if (argc < 3) die(EX_USAGE, "wrong number of arguments"); translate_ids(1, argv, MAP_INSTANCE); eclat_query_add_param(q, "InstanceId", argv[0]); canonattr = canonattrname(argv[1], &canonlen); if (!canonattr) die(EX_USAGE, "unrecognized attribute: %s", argv[1]); if (canonattr[canonlen] == '.' && strcmp(canonattr+canonlen+1, "%d") == 0) { for (i = 2; i < argc; i++) { grecs_asprintf(&bufptr, &bufsize, canonattr, i - 1); eclat_query_add_param(q, bufptr, argv[i]); } } else if (canonattr[canonlen] == '.' && strcmp(canonattr+canonlen, ".ebs") == 0) { for (i = 2; i < argc; i++) { char *p = strchr(argv[i], '='); if (!p) die(EX_USAGE, "DeleteOnTermination must be supplied in %s", argv[i]); *p++ = 0; grecs_asprintf(&bufptr, &bufsize, "%*.*s.%d.DeviceName", canonlen, canonlen, canonattr, i - 1); eclat_query_add_param(q, bufptr, argv[i]); grecs_asprintf(&bufptr, &bufsize, "%*.*s.%d.Ebs.DeleteOnTermination", canonlen, canonlen, canonattr, i - 1); if (strcmp(p, "false") && strcmp(p, "true")) die(EX_USAGE, "not a valid boolean in %s", argv[i]); eclat_query_add_param(q, bufptr, p); } } else if (argc != 3) die(EX_USAGE, "wrong number of arguments"); else eclat_query_add_param(q, canonattr, argv[2]); free(bufptr); return 0; }