void _assuan_inquire_release (assuan_context_t ctx) { if (ctx->in_inquire) { if (ctx->inquire_membuf) { free_membuf (ctx->inquire_membuf); free (ctx->inquire_membuf); } ctx->in_inquire = 0; } }
/** * assuan_inquire_ext: * @ctx: An assuan context * @keyword: The keyword used for the inquire * @maxlen: If not 0, the size limit of the inquired data. * @cb: A callback handler which is invoked after the operation completed. * @cb_data: A user-provided value passed to the callback handler. * * A Server may use this to Send an inquire. r_buffer, r_length and * maxlen may all be NULL/0 to indicate that no real data is expected. * When this function returns, * * Return value: 0 on success or an ASSUAN error code **/ assuan_error_t assuan_inquire_ext (assuan_context_t ctx, const char *keyword, size_t maxlen, int (*cb) (void *cb_data, int rc, unsigned char *buf, size_t len), void *cb_data) { assuan_error_t rc; struct membuf *mb = NULL; char cmdbuf[LINELENGTH-10]; /* (10 = strlen ("INQUIRE ")+CR,LF) */ if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf))) return _assuan_error (ASSUAN_Invalid_Value); if (!ctx->is_server) return _assuan_error (ASSUAN_Not_A_Server); if (ctx->in_inquire) return _assuan_error (ASSUAN_Nested_Commands); mb = malloc (sizeof (struct membuf)); if (!mb) return _assuan_error (ASSUAN_Out_Of_Core); init_membuf (mb, maxlen ? maxlen : 1024, maxlen); strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword); rc = assuan_write_line (ctx, cmdbuf); if (rc) { free_membuf (mb); free (mb); return rc; } ctx->in_inquire = 1; /* Set up the continuation. */ ctx->inquire_cb = cb; ctx->inquire_cb_data = cb_data; ctx->inquire_membuf = mb; return 0; }
/** * assuan_inquire_ext: * @ctx: An assuan context * @keyword: The keyword used for the inquire * @maxlen: If not 0, the size limit of the inquired data. * @cb: A callback handler which is invoked after the operation completed. * @cb_data: A user-provided value passed to the callback handler. * * A Server may use this to Send an inquire. r_buffer, r_length and * maxlen may all be NULL/0 to indicate that no real data is expected. * When this function returns, * * Return value: 0 on success or an ASSUAN error code **/ gpg_error_t assuan_inquire_ext (assuan_context_t ctx, const char *keyword, size_t maxlen, gpg_error_t (*cb) (void *cb_data, gpg_error_t rc, unsigned char *buf, size_t len), void *cb_data) { gpg_error_t rc; struct membuf *mb = NULL; char cmdbuf[LINELENGTH-10]; /* (10 = strlen ("INQUIRE ")+CR,LF) */ if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf))) return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE); if (!ctx->is_server) return _assuan_error (ctx, GPG_ERR_ASS_NOT_A_SERVER); if (ctx->in_inquire) return _assuan_error (ctx, GPG_ERR_ASS_NESTED_COMMANDS); mb = malloc (sizeof (struct membuf)); if (!mb) return _assuan_error (ctx, gpg_err_code_from_syserror ()); init_membuf (ctx, mb, maxlen ? maxlen : 1024, maxlen); strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword); rc = assuan_write_line (ctx, cmdbuf); if (rc) { free_membuf (ctx, mb); free (mb); return rc; } ctx->in_inquire = 1; /* Set up the continuation. */ ctx->inquire_cb = cb; ctx->inquire_cb_data = cb_data; ctx->inquire_membuf = mb; return 0; }
int _assuan_inquire_ext_cb (assuan_context_t ctx) { int rc; unsigned char *line; int linelen; struct membuf *mb; unsigned char *p; line = (unsigned char *) ctx->inbound.line; linelen = ctx->inbound.linelen; mb = ctx->inquire_membuf; if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N') { rc = _assuan_error (ASSUAN_Canceled); goto leave; } if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D' && (!line[3] || line[3] == ' ')) { rc = 0; goto leave; } if (line[0] != 'D' || line[1] != ' ' || mb == NULL) { rc = _assuan_error (ASSUAN_Unexpected_Command); goto leave; } if (linelen < 3) return 0; line += 2; linelen -= 2; p = line; while (linelen) { for (;linelen && *p != '%'; linelen--, p++) ; put_membuf (mb, line, p-line); if (linelen > 2) { /* handle escaping */ unsigned char tmp[1]; p++; *tmp = xtoi_2 (p); p += 2; linelen -= 3; put_membuf (mb, tmp, 1); } line = p; } if (mb->too_large) { rc = _assuan_error (ASSUAN_Too_Much_Data); goto leave; } return 0; leave: { size_t buf_len = 0; unsigned char *buf = NULL; if (mb) { buf = get_membuf (mb, &buf_len); if (!buf) rc = _assuan_error (ASSUAN_Out_Of_Core); free_membuf (mb); free (mb); ctx->inquire_membuf = NULL; } ctx->in_inquire = 0; rc = (ctx->inquire_cb) (ctx->inquire_cb_data, rc, buf, buf_len); } return rc; }
/** * assuan_inquire: * @ctx: An assuan context * @keyword: The keyword used for the inquire * @r_buffer: Returns an allocated buffer * @r_length: Returns the length of this buffer * @maxlen: If not 0, the size limit of the inquired data. * * A Server may use this to Send an inquire. r_buffer, r_length and * maxlen may all be NULL/0 to indicate that no real data is expected. * * Return value: 0 on success or an ASSUAN error code **/ assuan_error_t assuan_inquire (assuan_context_t ctx, const char *keyword, unsigned char **r_buffer, size_t *r_length, size_t maxlen) { assuan_error_t rc; struct membuf mb; char cmdbuf[LINELENGTH-10]; /* (10 = strlen ("INQUIRE ")+CR,LF) */ unsigned char *line, *p; int linelen; int nodataexpected; if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf))) return _assuan_error (ASSUAN_Invalid_Value); nodataexpected = !r_buffer && !r_length && !maxlen; if (!nodataexpected && (!r_buffer || !r_length)) return _assuan_error (ASSUAN_Invalid_Value); if (!ctx->is_server) return _assuan_error (ASSUAN_Not_A_Server); if (ctx->in_inquire) return _assuan_error (ASSUAN_Nested_Commands); ctx->in_inquire = 1; if (nodataexpected) memset (&mb, 0, sizeof mb); /* avoid compiler warnings */ else init_membuf (&mb, maxlen? maxlen:1024, maxlen); strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword); rc = assuan_write_line (ctx, cmdbuf); if (rc) goto leave; for (;;) { do { do rc = _assuan_read_line (ctx); while (_assuan_error_is_eagain (rc)); if (rc) goto leave; line = (unsigned char *) ctx->inbound.line; linelen = ctx->inbound.linelen; } while (*line == '#' || !linelen); if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D' && (!line[3] || line[3] == ' ')) break; /* END command received*/ if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N') { rc = _assuan_error (ASSUAN_Canceled); goto leave; } if (line[0] != 'D' || line[1] != ' ' || nodataexpected) { rc = _assuan_error (ASSUAN_Unexpected_Command); goto leave; } if (linelen < 3) continue; line += 2; linelen -= 2; p = line; while (linelen) { for (;linelen && *p != '%'; linelen--, p++) ; put_membuf (&mb, line, p-line); if (linelen > 2) { /* handle escaping */ unsigned char tmp[1]; p++; *tmp = xtoi_2 (p); p += 2; linelen -= 3; put_membuf (&mb, tmp, 1); } line = p; } if (mb.too_large) { rc = _assuan_error (ASSUAN_Too_Much_Data); goto leave; } } if (!nodataexpected) { *r_buffer = get_membuf (&mb, r_length); if (!*r_buffer) rc = _assuan_error (ASSUAN_Out_Of_Core); } leave: if (!nodataexpected) free_membuf (&mb); ctx->in_inquire = 0; return rc; }
gpg_error_t _assuan_inquire_ext_cb (assuan_context_t ctx) { gpg_error_t rc; unsigned char *line; int linelen; struct membuf *mb; unsigned char *p; line = (unsigned char *) ctx->inbound.line; linelen = ctx->inbound.linelen; mb = ctx->inquire_membuf; if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N') { rc = _assuan_error (ctx, GPG_ERR_ASS_CANCELED); goto leave; } if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D' && (!line[3] || line[3] == ' ')) { rc = 0; goto leave; } if (line[0] != 'D' || line[1] != ' ' || mb == NULL) { rc = _assuan_error (ctx, GPG_ERR_ASS_UNEXPECTED_CMD); goto leave; } if (linelen < 3) return 0; line += 2; linelen -= 2; p = line; while (linelen) { for (;linelen && *p != '%'; linelen--, p++) ; put_membuf (ctx, mb, line, p-line); if (linelen > 2) { /* handle escaping */ unsigned char tmp[1]; p++; *tmp = xtoi_2 (p); p += 2; linelen -= 3; put_membuf (ctx, mb, tmp, 1); } line = p; } if (mb->too_large) { rc = _assuan_error (ctx, GPG_ERR_ASS_TOO_MUCH_DATA); goto leave; } return 0; leave: { size_t buf_len = 0; unsigned char *buf = NULL; if (mb) { buf = get_membuf (ctx, mb, &buf_len); if (!buf) rc = _assuan_error (ctx, gpg_err_code_from_syserror ()); free_membuf (ctx, mb); free (mb); ctx->inquire_membuf = NULL; } ctx->in_inquire = 0; rc = (ctx->inquire_cb) (ctx->inquire_cb_data, rc, buf, buf_len); } return rc; }
/** * assuan_inquire: * @ctx: An assuan context * @keyword: The keyword used for the inquire * @r_buffer: Returns an allocated buffer * @r_length: Returns the length of this buffer * @maxlen: If not 0, the size limit of the inquired data. * * A Server may use this to Send an inquire. r_buffer, r_length and * maxlen may all be NULL/0 to indicate that no real data is expected. * * Return value: 0 on success or an ASSUAN error code **/ gpg_error_t assuan_inquire (assuan_context_t ctx, const char *keyword, unsigned char **r_buffer, size_t *r_length, size_t maxlen) { gpg_error_t rc; struct membuf mb; char cmdbuf[LINELENGTH-10]; /* (10 = strlen ("INQUIRE ")+CR,LF) */ unsigned char *line, *p; int linelen; int nodataexpected; if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf))) return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE); nodataexpected = !r_buffer && !r_length && !maxlen; if (!nodataexpected && (!r_buffer || !r_length)) return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE); if (!ctx->is_server) return _assuan_error (ctx, GPG_ERR_ASS_NOT_A_SERVER); if (ctx->in_inquire) return _assuan_error (ctx, GPG_ERR_ASS_NESTED_COMMANDS); ctx->in_inquire = 1; if (nodataexpected) memset (&mb, 0, sizeof mb); /* avoid compiler warnings */ else init_membuf (ctx, &mb, maxlen? maxlen:1024, maxlen); strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword); rc = assuan_write_line (ctx, cmdbuf); if (rc) goto leave; for (;;) { do { do rc = _assuan_read_line (ctx); while (_assuan_error_is_eagain (ctx, rc)); if (rc) goto leave; line = (unsigned char *) ctx->inbound.line; linelen = ctx->inbound.linelen; } while (*line == '#' || !linelen); if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D' && (!line[3] || line[3] == ' ')) break; /* END command received*/ if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N') { rc = _assuan_error (ctx, GPG_ERR_ASS_CANCELED); goto leave; } if (line[0] != 'D' || line[1] != ' ' || nodataexpected) { rc = _assuan_error (ctx, GPG_ERR_ASS_UNEXPECTED_CMD); goto leave; } if (linelen < 3) continue; line += 2; linelen -= 2; p = line; while (linelen) { for (;linelen && *p != '%'; linelen--, p++) ; put_membuf (ctx, &mb, line, p-line); if (linelen > 2) { /* handle escaping */ unsigned char tmp[1]; p++; *tmp = xtoi_2 (p); p += 2; linelen -= 3; put_membuf (ctx, &mb, tmp, 1); } line = p; } if (mb.too_large) { rc = _assuan_error (ctx, GPG_ERR_ASS_TOO_MUCH_DATA); goto leave; } } if (!nodataexpected) { *r_buffer = get_membuf (ctx, &mb, r_length); if (!*r_buffer) rc = _assuan_error (ctx, gpg_err_code_from_syserror ()); } leave: if (!nodataexpected) free_membuf (ctx, &mb); ctx->in_inquire = 0; return rc; }