diff options
author | Werner Koch <[email protected]> | 2010-12-08 09:55:00 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2010-12-08 09:55:00 +0000 |
commit | ce1d166ef700a188dcaf1b616f39f6c5750e4e9d (patch) | |
tree | 581f394d47b49276ddd13d28be2a1ebcb6f73e6a /src/gpgme-tool.c | |
parent | 2010-11-23 Marcus Brinkmann <[email protected]> (diff) | |
download | gpgme-ce1d166ef700a188dcaf1b616f39f6c5750e4e9d.tar.gz gpgme-ce1d166ef700a188dcaf1b616f39f6c5750e4e9d.zip |
Allow multiple patterns for KEYLIST.
Diffstat (limited to 'src/gpgme-tool.c')
-rw-r--r-- | src/gpgme-tool.c | 65 |
1 files changed, 59 insertions, 6 deletions
diff --git a/src/gpgme-tool.c b/src/gpgme-tool.c index 068681f6..e424c381 100644 --- a/src/gpgme-tool.c +++ b/src/gpgme-tool.c @@ -52,6 +52,10 @@ # define GT_GCC_A_PRINTF(f, a) #endif +#define DIM(v) (sizeof(v)/sizeof((v)[0])) +#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ + *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) +#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) @@ -506,6 +510,28 @@ log_error (int status, gpg_error_t errnum, const char *fmt, ...) } +/* Note that it is sufficient to allocate the target string D as long + as the source string S, i.e.: strlen(s)+1;. D == S is allowed. */ +static void +strcpy_escaped_plus (char *d, const char *s) +{ + while (*s) + { + if (*s == '%' && s[1] && s[2]) + { + s++; + *d++ = xtoi_2 (s); + s += 2; + } + else if (*s == '+') + *d++ = ' ', s++; + else + *d++ = *s++; + } + *d = 0; +} + + /* Check whether the option NAME appears in LINE. */ static int has_option (const char *line, const char *name) @@ -2671,14 +2697,22 @@ cmd_delete (assuan_context_t ctx, char *line) } +static const char hlp_keylist[] = + "KEYLIST [--secret-only] [<patterns>]\n" + "\n" + "List all certificates or only those specified by PATTERNS. Each\n" + "pattern shall be a percent-plus escaped certificate specification."; static gpg_error_t cmd_keylist (assuan_context_t ctx, char *line) { +#define MAX_CMD_KEYLIST_PATTERN 20 struct server *server = assuan_get_pointer (ctx); gpg_error_t err; int secret_only = 0; - const char *pattern[2]; + int idx; + const char *pattern[MAX_CMD_KEYLIST_PATTERN+1]; const char optstr[] = "--secret-only"; + char *p; if (!strncasecmp (line, optstr, strlen (optstr))) { @@ -2687,8 +2721,23 @@ cmd_keylist (assuan_context_t ctx, char *line) while (*line && !spacep (line)) line++; } - pattern[0] = line; - pattern[1] = NULL; + + idx = 0; + for (p=line; *p; line = p) + { + while (*p && *p != ' ') + p++; + if (*p) + *p++ = 0; + if (*line) + { + if (idx+1 == DIM (pattern)) + return gpg_error (GPG_ERR_TOO_MANY); + strcpy_escaped_plus (line, line); + pattern[idx++] = line; + } + } + pattern[idx] = NULL; err = gt_keylist_start (server->gt, pattern, secret_only); while (! err) @@ -2706,7 +2755,11 @@ cmd_keylist (assuan_context_t ctx, char *line) char buf[100]; /* FIXME: More data. */ snprintf (buf, sizeof (buf), "key:%s\n", key->subkeys->fpr); - assuan_send_data (ctx, buf, strlen (buf)); + /* Write data and flush so that we see one D line for each + key. This does not change the semantics but is easier to + read by organic eyes. */ + if (!assuan_send_data (ctx, buf, strlen (buf))) + assuan_send_data (ctx, NULL, 0); gpgme_key_unref (key); } } @@ -2895,8 +2948,8 @@ register_commands (assuan_context_t ctx) { "GENKEY", cmd_genkey }, { "DELETE", cmd_delete }, /* TODO: EDIT, CARD_EDIT (with INQUIRE) */ - { "KEYLIST", cmd_keylist }, - { "LISTKEYS", cmd_keylist }, + { "KEYLIST", cmd_keylist, hlp_keylist }, + { "LISTKEYS", cmd_keylist, hlp_keylist }, /* TODO: TRUSTLIST, TRUSTLIST_EXT */ { "GETAUDITLOG", cmd_getauditlog, hlp_getauditlog }, /* TODO: ASSUAN */ |