diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-04-20 10:39:19 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-04-20 10:39:19 +0300 |
commit | 67dce06bb26798e2b11ee0883bdc7e08d7edb663 (patch) | |
tree | 3f3655179dded2bbdd16c411d3f0558fe4515bf9 /src/eclat.c | |
parent | 347387193da605922ed98742dbc7fa3f67a908f4 (diff) | |
download | eclat-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.c | 235 |
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)) { |