aboutsummaryrefslogtreecommitdiff
path: root/src/eclat.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-04-20 10:39:19 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2013-04-20 10:39:19 +0300
commit67dce06bb26798e2b11ee0883bdc7e08d7edb663 (patch)
tree3f3655179dded2bbdd16c411d3f0558fe4515bf9 /src/eclat.c
parent347387193da605922ed98742dbc7fa3f67a908f4 (diff)
downloadeclat-67dce06bb26798e2b11ee0883bdc7e08d7edb663.tar.gz
eclat-67dce06bb26798e2b11ee0883bdc7e08d7edb663.tar.bz2
Major rewrite. Provide short names for each command.
Diffstat (limited to 'src/eclat.c')
-rw-r--r--src/eclat.c235
1 files changed, 168 insertions, 67 deletions
diff --git a/src/eclat.c b/src/eclat.c
index ef2f348..13b8e74 100644
--- a/src/eclat.c
+++ b/src/eclat.c
@@ -196,89 +196,81 @@ node_ident_cmp(struct grecs_node const *a, struct grecs_node const *b)
return strcmp(a->ident, b->ident);
}
+void listcmd(char *fmt);
+
#include "cmdline.h"
#define CMD_MOD 0x01
#define CMD_DESTR 0x02
#define CMD_NOQRY 0x04
-struct command {
- const char *ident;
- const char *tag;
- eclat_command_handler_t handler;
- int flags;
- enum eclat_confirm_mode confirm;
- char *fmt;
- struct grecs_locus locus;
-};
-
-struct command cmdtab[] = {
- { "start-instances", "StartInstances", eclat_start_instance,
+struct eclat_command cmdtab[] = {
+ { "start", "start-instances", "StartInstances", eclat_start_instance,
CMD_MOD },
- { "stop-instances", "StopInstances", eclat_stop_instance,
+ { "stop", "stop-instances", "StopInstances", eclat_stop_instance,
CMD_MOD },
- { "reboot-instances", "RebootInstances", eclat_reboot_instance,
+ { "reboot", "reboot-instances", "RebootInstances", eclat_reboot_instance,
CMD_MOD },
- { "describe-addresses", "DescribeAddresses",
+ { "lsaddr", "describe-addresses", "DescribeAddresses",
eclat_describe_addresses },
- { "describe-tags", "DescribeTags", eclat_describe_tags },
- { "describe-instance-attribute", "DescribeInstanceAttribute",
+ { "lstag", "describe-tags", "DescribeTags", eclat_describe_tags },
+ { "lsiattr", "describe-instance-attribute", "DescribeInstanceAttribute",
eclat_describe_instance_attribute },
- { "describe-instance-status", "DescribeInstanceStatus",
+ { "lsistat", "describe-instance-status", "DescribeInstanceStatus",
eclat_describe_instance_status },
- { "describe-instances", "DescribeInstances",
+ { "lsinst", "describe-instances", "DescribeInstances",
eclat_describe_instances },
- { "describe-volumes", "DescribeVolumes",
+ { "lsvol", "describe-volumes", "DescribeVolumes",
eclat_describe_volumes },
- { "allocate-address", "AllocateAddress",
+ { "allocaddr", "allocate-address", "AllocateAddress",
eclat_allocate_address, CMD_MOD },
- { "release-address", "ReleaseAddress",
+ { "freeaddr", "release-address", "ReleaseAddress",
eclat_release_address, CMD_MOD|CMD_DESTR },
- { "associate-address", "AssociateAddress",
+ { "assocaddr", "associate-address", "AssociateAddress",
eclat_associate_address, CMD_MOD },
- { "disassociate-address", "DisassociateAddress",
+ { "disasaddr", "disassociate-address", "DisassociateAddress",
eclat_disassociate_address, CMD_MOD },
- { "create-tags", "CreateTags",
+ { "mktag", "create-tags", "CreateTags",
eclat_create_tags, CMD_MOD },
- { "delete-tags", "DeleteTags",
+ { "rmtag", "delete-tags", "DeleteTags",
eclat_delete_tags, CMD_MOD|CMD_DESTR },
- { "get-console-output", "GetConsoleOutput",
+ { "conmesg", "get-console-output", "GetConsoleOutput",
eclat_get_console_output },
- { "describe-security-groups", "DescribeSecurityGroups",
+ { "lssg", "describe-security-groups", "DescribeSecurityGroups",
eclat_describe_security_groups },
- { "create-snapshot", "CreateSnapshot",
+ { "mksnap", "create-snapshot", "CreateSnapshot",
eclat_create_snapshot },
- { "describe-snapshots", "DescribeSnapshots",
+ { "lssnap", "describe-snapshots", "DescribeSnapshots",
eclat_describe_snapshots },
- { "describe-snapshot-attribute", "DescribeSnapshotAttribute",
+ { "lssattr", "describe-snapshot-attribute", "DescribeSnapshotAttribute",
eclat_describe_snapshot_attribute },
- { "modify-snapshot-attribute", "ModifySnapshotAttribute",
+ { "setsattr", "modify-snapshot-attribute", "ModifySnapshotAttribute",
eclat_modify_snapshot_attribute, CMD_MOD },
- { "reset-snapshot-attribute", "ResetSnapshotAttribute",
+ { "clrsattr", "reset-snapshot-attribute", "ResetSnapshotAttribute",
eclat_reset_snapshot_attribute, CMD_MOD|CMD_DESTR },
- { "delete-snapshot", "DeleteSnapshot",
+ { "rmsnap", "delete-snapshot", "DeleteSnapshot",
eclat_delete_snapshot, CMD_MOD|CMD_DESTR },
- { "describe-avaialbility-zones", "DescribeAvaialbilityZones",
+ { "lszon", "describe-availability-zones", "DescribeAvailabilityZones",
eclat_describe_avaialbility_zones },
- { "describe-regions", "DescribeRegions",
+ { "lsreg", "describe-regions", "DescribeRegions",
eclat_describe_regions },
- { "create-volume", "CreateVolume",
+ { "mkvol", "create-volume", "CreateVolume",
eclat_create_volume, CMD_MOD },
- { "delete-volume", "DeleteVolume",
+ { "rmvol", "delete-volume", "DeleteVolume",
eclat_delete_volume, CMD_MOD|CMD_DESTR },
- { "attach-volume", "AttachVolume",
+ { "atvol", "attach-volume", "AttachVolume",
eclat_attach_volume, CMD_MOD },
- { "detach-volume", "DetachVolume",
+ { "devol", "detach-volume", "DetachVolume",
eclat_detach_volume, CMD_MOD|CMD_DESTR },
- { "modify-instance-attribute", "ModifyInstanceAttribute",
+ { "setiattr", "modify-instance-attribute", "ModifyInstanceAttribute",
eclat_modify_instance_attribute, CMD_MOD },
- { "describe-images", "DescribeImages",
+ { "lsimg", "describe-images", "DescribeImages",
eclat_describe_images },
- { "run-instances", "RunInstances",
+ { "mkinst", "run-instances", "RunInstances",
eclat_run_instances, CMD_MOD },
- { "create-image", "CreateImage",
+ { "mkimg", "create-image", "CreateImage",
eclat_create_image, CMD_MOD },
- { "deregister-image", "DeregisterImage",
+ { "deimg", "deregister-image", "DeregisterImage",
eclat_deregister_image, CMD_MOD|CMD_DESTR }
};
size_t cmdcnt = sizeof(cmdtab) / sizeof(cmdtab[0]);
@@ -286,8 +278,8 @@ size_t cmdcnt = sizeof(cmdtab) / sizeof(cmdtab[0]);
static int
cmdcmp(const void *a, const void *b)
{
- struct command const *cmda = a;
- struct command const *cmdb = b;
+ struct eclat_command const *cmda = a;
+ struct eclat_command const *cmdb = b;
return strcmp(cmda->ident, cmdb->ident);
}
@@ -297,14 +289,115 @@ sortcmds()
qsort(cmdtab, cmdcnt, sizeof(cmdtab[0]), cmdcmp);
}
+/* Format:
+
+ %[pfx:][sfx][ni]
+
+ For example, to format the table of available commands for doc/eclat.1:
+
+ eclat -l '\t\\fB%n\\fR\t\\fB%i\\fR\n'
+
+ To format a "see also" list of commands (ibidem):
+
+ eclat -l '%.BR eclat-: (1)n,\n'
+*/
+
+int
+parsespec(char *start, char **endp, char *fchr, char *s[], int l[])
+{
+ char *p;
+ int n = 0;
+
+ ++start;
+ s[0] = start;
+ s[1] = NULL;
+ l[0] = l[1] = 0;
+ for (p = start; *p; p++) {
+ if (*p == ':' || strchr(fchr, *p)) {
+ if (n > 1)
+ return -1;
+ l[n++] = p - start;
+ if (*p != ':') {
+ *endp = p + 1;
+ return *p;
+ }
+ if (n == 1)
+ s[n] = start = p + 1;
+ }
+ }
+ return -1;
+}
+
void
-listcmd()
+fmtstr(const char *str, int len)
{
- struct command *cp;
+ while (len--) {
+ int c = *str++;
+ if (c == '\\') {
+ if (len) {
+ len--;
+ c = wordsplit_c_unquote_char(*str++);
+ }
+ }
+ fputc(c, stdout);
+ }
+}
- printf("Available commands:\n");
+void
+listcmd(char *fmt)
+{
+ struct eclat_command *cp;
+
+ for (cp = cmdtab; cp < cmdtab + cmdcnt; cp++) {
+ char *p = fmt;
+ char *start = fmt;
+ char *end;
+ char *s[2];
+ int l[2];
+ const char *str;
+
+ while (*p) {
+ if (*p == '%') {
+ switch (parsespec(p, &end, "ni", s, l)) {
+ case 'n':
+ str = cp->name;
+ break;
+ case 'i':
+ str = cp->ident;
+ break;
+ default:
+ p++;
+ continue;
+ }
+
+ if (p != start)
+ fmtstr(start, p - start);
+ fmtstr(s[0], l[0]);
+ printf("%s", str);
+ fmtstr(s[1], l[1]);
+ start = p = end;
+ } else {
+ p++;
+ }
+ }
+ if (p != start)
+ fmtstr(start, p - start);
+ }
+}
+
+void
+listcmdhook()
+{
+ struct eclat_command *cp;
+
+ printf("Available commands\n");
+ printf("Eclat name EC2 Name\n");
+ printf("-----------+---------\n");
for (cp = cmdtab; cp < cmdtab + cmdcnt; cp++)
- printf(" %s\n", cp->ident);
+ if (cp->name)
+ printf(" %-10s %s\n", cp->name, cp->ident);
+ else
+ printf(" %10s %s\n", "", cp->ident);
printf("\nRun \"%s COMMAND --help\" to get help on a particular command.\n",
program_name);
@@ -312,12 +405,13 @@ listcmd()
putchar('\n');
}
+
#define NO_MATCH 0
#define EXACT_MATCH 1
#define PARTIAL_MATCH 2
static int
-name_matches(const char *p, const char *q)
+ident_matches(const char *p, const char *q)
{
int match = EXACT_MATCH;
@@ -339,13 +433,15 @@ name_matches(const char *p, const char *q)
return NO_MATCH;
}
-struct command *
+struct eclat_command *
find_command_name(const char *name)
{
- struct command *cp, *match = NULL;
+ struct eclat_command *cp, *match = NULL;
for (cp = cmdtab; cp < cmdtab + cmdcnt; cp++) {
- switch (name_matches(cp->ident, name)) {
+ if (strcmp(cp->name, name) == 0)
+ return cp;
+ switch (ident_matches(cp->ident, name)) {
case NO_MATCH:
break;
case EXACT_MATCH:
@@ -359,7 +455,7 @@ find_command_name(const char *name)
err(" %s", match->ident);
err(" %s", cp->ident);
while (++cp < cmdtab + cmdcnt)
- if (name_matches(cp->ident, name) !=
+ if (ident_matches(cp->ident, name) !=
NO_MATCH)
err(" %s", cp->ident);
exit(EX_USAGE);
@@ -372,17 +468,21 @@ find_command_name(const char *name)
static void
print_matching_commands(const char *pat)
{
- struct command *cp;
+ struct eclat_command *cp;
+ size_t patlen = strlen (pat);
- for (cp = cmdtab; cp < cmdtab + cmdcnt; cp++)
- if (name_matches(cp->ident, pat) != NO_MATCH)
+ for (cp = cmdtab; cp < cmdtab + cmdcnt; cp++) {
+ if (cp->name && strlen (cp->name) >= patlen && memcmp (cp->name, pat, patlen) == 0)
+ printf("%s\n", cp->name);
+ if (ident_matches(cp->ident, pat) != NO_MATCH)
printf("%s\n", cp->ident);
+ }
}
-struct command *
+struct eclat_command *
find_command_tag(const char *tag)
{
- struct command *cp;
+ struct eclat_command *cp;
for (cp = cmdtab; cp < cmdtab + cmdcnt; cp++) {
if (eclat_actcmp(cp->tag, tag) == 0)
@@ -395,7 +495,7 @@ void
set_command_confirmation(const char *name, enum eclat_confirm_mode cfmode,
grecs_locus_t *locus)
{
- struct command *cp;
+ struct eclat_command *cp;
int flag = 0;
if (strcmp(name, "all") == 0)
@@ -421,7 +521,7 @@ set_command_confirmation(const char *name, enum eclat_confirm_mode cfmode,
void
set_command_format(const char *name, const char *format, grecs_locus_t *locus)
{
- struct command *cp = find_command_tag(name);
+ struct eclat_command *cp = find_command_tag(name);
if (!cp) {
grecs_error(locus, 0, "unknown command");
@@ -571,7 +671,7 @@ find_format(const char *name)
}
static forlan_eval_env_t
-read_format(struct command *cmd)
+read_format(struct eclat_command *cmd)
{
forlan_eval_env_t env = NULL;
@@ -647,11 +747,11 @@ main(int argc, char **argv)
eclat_partial_tree_t part;
struct grecs_node *xmltree;
forlan_eval_env_t env = NULL;
- struct command *command = NULL;
+ struct eclat_command *command = NULL;
eclat_command_env_t cmdenv;
set_program_name(argv[0]);
- proginfo.print_help_hook = listcmd;
+ proginfo.print_help_hook = listcmdhook;
debug_init();
forlan_init();
eclat_map_init();
@@ -672,7 +772,7 @@ main(int argc, char **argv)
if (match_command_mode) {
if (argc > 1)
die(EX_USAGE, "wrong number of arguments");
- print_matching_commands(argc == 1 ? argv[0] : "-");
+ print_matching_commands(argc == 1 ? argv[0] : "");
return 0;
}
@@ -786,6 +886,7 @@ main(int argc, char **argv)
/* Prepare environment */
memset(&cmdenv, 0, sizeof(cmdenv));
+ cmdenv.cmd = command;
cmdenv.curl = curl;
if (!(command->flags & CMD_NOQRY)) {

Return to:

Send suggestions and report system problems to the System administrator.