From 8d25ce1f541d2e90c6c5ffd21d2b496a41028441 Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Mon, 18 Jun 2012 22:36:01 -0400 Subject: [PATCH] pwmc: add --prefix option to the .read command. Can be used for example to specify an element path: pwm> .read --prefix "some\telement\tpath\t" /path/to/data STORE Easier than having to store the element path in the file. --- src/pwmc.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 75 insertions(+), 8 deletions(-) diff --git a/src/pwmc.c b/src/pwmc.c index e56b2202..e68bb66c 100644 --- a/src/pwmc.c +++ b/src/pwmc.c @@ -629,8 +629,14 @@ static gpg_error_t set_inquire(int fd, const char *line, if (line) { char *s = escape(line); + if (!s) { + pwmd_free(inq.line); + return GPG_ERR_ENOMEM; + } + if (strlen(s) >= ASSUAN_LINELENGTH) { pwmd_free(inq.line); + pwmd_free(s); return GPG_ERR_LINE_TOO_LONG; } @@ -697,20 +703,80 @@ static char *parse_arg(const char *src, char *dst, size_t len) *p++ = *s; *p = 0; - p = dst; - return p; + return dst; +} + +static char *parse_opt(char **line, const char *opt, gpg_error_t *rc) +{ + static char result[ASSUAN_LINELENGTH] = {0}, *r = result; + size_t len = 0; + char *s = strstr(*line, opt); + + *rc = 0; + result[0] = 0; + r = result; + + if (s) { + int quote = 0; + size_t rlen = strlen(opt); + char *p = s+rlen; + int lastc = 0; + + while (*p && *p == ' ') { + rlen++; + p++; + } + + for (; *p && len < sizeof(result)-1; p++, rlen++) { + if (isspace(*p) && !quote) + break; + + if (*p == '\"' && lastc != '\\') { + quote = !quote; + lastc = *p; + continue; + } + + *r++ = lastc = *p; + len++; + } + + *r = 0; + + if (len >= sizeof(result)-1) + *rc = GPG_ERR_LINE_TOO_LONG; + else { + p = s+rlen; + + while (*p && *p == ' ') + p++; + + *line = p; + } + } + + return result; } static gpg_error_t read_command(const char *line, char **result, size_t *len) { - const char *p = line; int fd; - gpg_error_t rc = GPG_ERR_SYNTAX; + gpg_error_t rc = 0; char filebuf[ASSUAN_LINELENGTH]; char *filename = NULL; struct inquire_s *inq = NULL; + char *p = (char *)line; + const char *prefix = parse_opt(&p, "--prefix", &rc); + + if (rc) + return rc; + + rc = GPG_ERR_SYNTAX; + + if (p && *p) { + while (*p && isspace(*p)) + p++; - if (p && *p && *++p) { filename = parse_arg(p, filebuf, sizeof(filebuf)); if (filename && *filename) { p += strlen(filename)+1; @@ -724,7 +790,8 @@ static gpg_error_t read_command(const char *line, char **result, size_t *len) } if (rc) { - fprintf(stderr, N_("Usage: .read [args]\n")); + fprintf(stderr, N_("Usage: .read [--prefix ] [args]\n")); + fprintf(stderr, N_("Use '\\' to escape special characters in the --prefix (\\t = TAB, \\\" = \")\n")); return rc; } @@ -732,7 +799,7 @@ static gpg_error_t read_command(const char *line, char **result, size_t *len) if (fd == -1) return gpg_error_from_syserror(); - rc = set_inquire(fd, NULL, &inq); + rc = set_inquire(fd, prefix && *prefix ? prefix : NULL, &inq); if (rc) { close(fd); return rc; @@ -808,7 +875,7 @@ static gpg_error_t help_command(const char *line) " .open \n" " open the specified filename losing any changes to the current one\n" "\n" - " .read [args]\n" + " .read [--prefix ] [args]\n" " obtain data from the specified filename for an inquire command\n" "\n" " .set help | []\n" -- 2.11.4.GIT