/* 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"
#include
#include
int translation_enabled;
char *custom_map;
void
translate_ids(int argc, char **argv, const char *mapname)
{
int i;
struct eclat_map *map;
char *val;
char *q, *realname;
int dir;
int rc;
if (!translation_enabled || argc == 0)
return;
if (custom_map)
mapname = custom_map;
dir = eclat_map_name_split(mapname, &realname, &q);
if (dir == -1)
die(EX_USAGE, "bad qualifier: %s", q);
map = eclat_map_lookup(realname);
if (!map) {
debug(ECLAT_DEBCAT_MAIN, 1,
("no such map: %s", realname));
return;
}
if (eclat_map_open(map) != eclat_map_ok)
die(EX_UNAVAILABLE, "failed to open map %s", realname);
free(realname);
for (i = 0; i < argc; i++) {
if (!strchr(argv[i], '=')) {
switch (rc = eclat_map_get(map, dir, argv[i], &val)) {
case eclat_map_ok:
argv[i] = val;
break;
case eclat_map_not_found:
debug(ECLAT_DEBCAT_MAIN, 1,
("%s not found in map %s",
argv[i], mapname));
break;
default:
die(EX_UNAVAILABLE, "cannot translate %s: %s",
argv[i], eclat_map_strerror(rc));
}
}
}
}
char *
eclat_stpcpy(char *p, char *q)
{
while (*p = *q++)
++p;
return p;
}
#define RESOURCE_ID_PFX "resource-id="
#define RESOURCE_ID_LEN (sizeof(RESOURCE_ID_PFX) - 1)
void
translate_resource_ids(int argc, char **argv)
{
int i, j, rc, ecnt;
size_t len;
struct eclat_map *map;
char *val, *p;
struct wordsplit ws;
int wsflags = WRDSF_DEFFLAGS|WRDSF_DELIM;
if (!translation_enabled || argc == 0)
return;
ws.ws_delim = ",";
for (i = 0; i < argc; i++) {
if (strncmp(argv[i], RESOURCE_ID_PFX, RESOURCE_ID_LEN))
continue;
if (wordsplit(argv[i] + RESOURCE_ID_LEN, &ws, wsflags))
die(EX_SOFTWARE,
"error expanding argument %s: %s",
argv[i] + RESOURCE_ID_LEN,
wordsplit_strerror(&ws));
wsflags |= WRDSF_REUSE;
for (j = 0, ecnt = 0; j < ws.ws_wordc; j++) {
if (!(p = strchr(ws.ws_wordv[j], ':')))
continue;
*p++ = 0;
map = eclat_map_lookup(ws.ws_wordv[j]);
if (!map)
die(EX_UNAVAILABLE, "no such map: %s",
ws.ws_wordv[j]);
if (eclat_map_open(map) != eclat_map_ok)
die(EX_UNAVAILABLE,
"failed to open map %s", ws.ws_wordv[j]);
rc = eclat_map_get(map, MAP_DIR, p, &val);
if (rc != eclat_map_ok) {
die(EX_UNAVAILABLE,
"cannot translate %s using map %s: %s",
p, ws.ws_wordv[j], eclat_map_strerror(rc));
}
free(ws.ws_wordv[j]);
ws.ws_wordv[j] = val;
ecnt++;
}
if (ecnt == 0)
continue;
len = RESOURCE_ID_LEN + ws.ws_wordc - 1;
for (j = 0; j < ws.ws_wordc; j++)
len += strlen(ws.ws_wordv[j]);
val = grecs_malloc(len + 1);
strcpy(val, RESOURCE_ID_PFX);
p = val + RESOURCE_ID_LEN;
for (j = 0; j < ws.ws_wordc; j++) {
if (j)
*p++ = ',';
p = eclat_stpcpy(p, ws.ws_wordv[j]);
}
argv[i] = val;
}
if (wsflags & WRDSF_REUSE)
wordsplit_free(&ws);
}
int
get_scr_cols()
{
struct winsize ws;
ws.ws_col = ws.ws_row = 0;
if ((ioctl(1, TIOCGWINSZ, (char *) &ws) < 0) || ws.ws_col == 0) {
const char *p = getenv ("COLUMNS");
if (p)
ws.ws_col = strtol(p, NULL, 10);
}
return ws.ws_col ? ws.ws_col : 80;
}
void
describe_query_update(eclat_command_env_t *env, int argc, char **argv,
const char *uparm, int n_in, int *n_out)
{
int i, j, k;
struct ec2_query *q = env->query;
char *bufptr = NULL;
size_t bufsize = 0;
struct wordsplit ws;
int wsflags;
int upn = 0;
ws.ws_delim = ",";
wsflags = WRDSF_DEFFLAGS | WRDSF_DELIM;
for (i = 0, j = n_in; i < argc; i++) {
char *p = strchr(argv[i], '=');
if (!p) {
if (uparm) {
grecs_asprintf(&bufptr, &bufsize,
"%s.%d", uparm, upn++);
eclat_query_add_param(q, bufptr, argv[i]);
continue;
}
die(EX_USAGE, "maformed filter: %s", argv[i]);
}
*p++ = 0;
grecs_asprintf(&bufptr, &bufsize, "Filter.%d.Name", j);
eclat_query_add_param(q, bufptr, argv[i]);
if (wordsplit(p, &ws, wsflags))
die(EX_SOFTWARE, "wordsplit failed at \"%s\": %s",
p, wordsplit_strerror(&ws));
wsflags |= WRDSF_REUSE;
for (k = 0; k < ws.ws_wordc; k++) {
grecs_asprintf(&bufptr, &bufsize, "Filter.%d.Value.%d",
j, k+1);
eclat_query_add_param(q, bufptr, ws.ws_wordv[k]);
}
++j;
}
if (wsflags & WRDSF_REUSE)
wordsplit_free(&ws);
free(bufptr);
if (n_out)
*n_out = j;
}
void
describe_query_create(eclat_command_env_t *env, int argc, char **argv,
const char *uparm)
{
describe_query_update(env, argc, argv, uparm, 1, NULL);
}
int
eclat_send_query(CURL *curl, struct ec2_query *q)
{
char *url;
CURLcode res;
int rc = 0;
eclat_query_add_param(q, "AWSAccessKeyId", access_key);
eclat_query_sign(q, secret_key, signature_version);
url = eclat_query_to_url(q, NULL);
debug(ECLAT_DEBCAT_MAIN, 1, ("using URL: %s", url));
curl_easy_setopt(curl, CURLOPT_URL, url);
free(url);
eclat_query_free(q);
if (dry_run_mode)
debug(ECLAT_DEBCAT_MAIN, 1, ("not sending request"));
else {
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
err("CURL: %s", curl_easy_strerror(res));
rc = 1;
}
}
return rc;
}
int
eclat_actcmp(const char *a, const char *b)
{
int rc = 0;
enum { cmp_init, cmp_norm, cmp_upca, cmp_upcb } state = cmp_init;
while (rc == 0) {
if (!*a)
return *b ? - *b : 0;
if (!*b)
return *a ? *a : 0;
if (*a == '-') {
a++;
if (state == cmp_norm)
state = cmp_upca;
else
state = cmp_norm;
} else if (*b == '-') {
b++;
if (state == cmp_norm)
state = cmp_upcb;
else
state = cmp_norm;
} else {
switch (state) {
case cmp_init:
rc = toupper(*a) - toupper(*b);
break;
case cmp_norm:
rc = *a - *b;
break;
case cmp_upca:
rc = toupper(*a) - *b;
break;
case cmp_upcb:
rc = *a - toupper(*b);
break;
}
a++;
b++;
state = cmp_norm;
}
}
return rc;
}
char **available_attrs;
void
list_attrs(FILE *fp)
{
size_t ncols = get_scr_cols();
int i, col, len;
char *delim = "";
fprintf(fp, "Available attributes are:\n");
col = 0;
for (i = 0; available_attrs[i]; i++) {
len = strlen(delim) + strlen(available_attrs[i]);
if (col + len > ncols) {
fprintf(fp, ",\n%s", available_attrs[i]);
col = strlen(available_attrs[i]);
} else
col += fprintf(fp, "%s%s", delim, available_attrs[i]);
delim = ", ";
}
fputc('\n', fp);
fputc('\n', fp);
}