aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/engine-gpgsm.c142
1 files changed, 74 insertions, 68 deletions
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index 206d3e4b..302c1a8e 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -696,6 +696,7 @@ gpgsm_assuan_simple_command (engine_gpgsm_t gpgsm, const char *cmd,
struct io_select_fd_s fds[2];
struct io_cb_data iocb_data;
int nfds = 0;
+ int done = 0;
iocb_data.handler_value = gpgsm->diag_cb.data;
iocb_data.op_err = 0;
@@ -738,88 +739,93 @@ gpgsm_assuan_simple_command (engine_gpgsm_t gpgsm, const char *cmd,
if (gpgsm->status_cb.fd != -1 && !fds[0].signaled)
continue;
- err = assuan_read_line (ctx, &line, &linelen);
- if (err)
+ do
{
- TRACE (DEBUG_CTX, "gpgsm_assuan_simple_command", gpgsm,
+ err = assuan_read_line (ctx, &line, &linelen);
+ if (err)
+ {
+ TRACE (DEBUG_CTX, "gpgsm_assuan_simple_command", gpgsm,
"error from assuan (%d) getting line: %s",
- err, gpg_strerror (err));
- break;
- }
+ err, gpg_strerror (err));
+ break;
+ }
- if (*line == '#' || !linelen)
- continue;
+ if (*line == '#' || !linelen)
+ continue;
- if (linelen >= 2
- && line[0] == 'O' && line[1] == 'K'
- && (line[2] == '\0' || line[2] == ' '))
- {
- TRACE (DEBUG_CTX, "gpgsm_assuan_simple_command", gpgsm,
- "OK line seen");
- break;
- }
- else if (linelen >= 4
- && line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
- && line[3] == ' ')
- {
- err = atoi (&line[4]);
- TRACE (DEBUG_CTX, "gpgsm_assuan_simple_command", gpgsm,
- "ERR line seen: err=%s, cb_err=%s",
- gpg_strerror (err), cb_err? gpg_strerror (cb_err):"none");
- /* We prefer a callback generated error because that one is
- more related to gpgme and thus probably more important
- than the error returned by the engine. */
- if (cb_err)
+ if (linelen >= 2
+ && line[0] == 'O' && line[1] == 'K'
+ && (line[2] == '\0' || line[2] == ' '))
{
- err = cb_err;
- cb_err = 0;
+ TRACE (DEBUG_CTX, "gpgsm_assuan_simple_command", gpgsm,
+ "OK line seen");
+ done = 1;
+ break;
}
- }
- else if (linelen >= 2
- && line[0] == 'S' && line[1] == ' ')
- {
- /* After an error from a status callback we skip all further
- status lines. */
- TRACE (DEBUG_CTX, "gpgsm_assuan_simple_command", gpgsm,
- "S line seen: line='%s'", line);
- if (!cb_err)
+ else if (linelen >= 4
+ && line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
+ && line[3] == ' ')
{
- char *rest;
- gpgme_status_code_t r;
-
- rest = strchr (line + 2, ' ');
- if (!rest)
- rest = line + linelen; /* set to an empty string */
- else
- *(rest++) = 0;
-
- r = _gpgme_parse_status (line + 2);
- if (gpgsm->status.mon_cb && r != GPGME_STATUS_PROGRESS)
+ err = atoi (&line[4]);
+ TRACE (DEBUG_CTX, "gpgsm_assuan_simple_command", gpgsm,
+ "ERR line seen: err=%s, cb_err=%s",
+ gpg_strerror (err), cb_err? gpg_strerror (cb_err):"none");
+ /* We prefer a callback generated error because that one is
+ more related to gpgme and thus probably more important
+ than the error returned by the engine. */
+ if (cb_err)
{
- /* Note that we call the monitor even if we do
- * not know the status code (r < 0). */
- cb_err = gpgsm->status.mon_cb (gpgsm->status.mon_cb_value,
- line + 2, rest);
+ err = cb_err;
+ cb_err = 0;
}
+ }
+ else if (linelen >= 2
+ && line[0] == 'S' && line[1] == ' ')
+ {
+ /* After an error from a status callback we skip all further
+ status lines. */
+ TRACE (DEBUG_CTX, "gpgsm_assuan_simple_command", gpgsm,
+ "S line seen: line='%s'", line);
+ if (!cb_err)
+ {
+ char *rest;
+ gpgme_status_code_t r;
+
+ rest = strchr (line + 2, ' ');
+ if (!rest)
+ rest = line + linelen; /* set to an empty string */
+ else
+ *(rest++) = 0;
- if (r >= 0 && status_fnc && !cb_err)
- cb_err = status_fnc (status_fnc_value, r, rest);
+ r = _gpgme_parse_status (line + 2);
+ if (gpgsm->status.mon_cb && r != GPGME_STATUS_PROGRESS)
+ {
+ /* Note that we call the monitor even if we do
+ * not know the status code (r < 0). */
+ cb_err = gpgsm->status.mon_cb (gpgsm->status.mon_cb_value,
+ line + 2, rest);
+ }
+
+ if (r >= 0 && status_fnc && !cb_err)
+ cb_err = status_fnc (status_fnc_value, r, rest);
+ TRACE (DEBUG_CTX, "gpgsm_assuan_simple_command", gpgsm,
+ "S line yields cb_err=%s", gpg_strerror (cb_err));
+ }
+ }
+ else
+ {
+ /* Invalid line or INQUIRY. We can't do anything else than
+ to stop. As with ERR we prefer a status callback
+ generated error code, though. */
TRACE (DEBUG_CTX, "gpgsm_assuan_simple_command", gpgsm,
- "S line yields cb_err=%s", gpg_strerror (cb_err));
+ "Invalid line seen: %s", line);
+ err = cb_err ? cb_err : gpg_error (GPG_ERR_GENERAL);
+ cb_err = 0;
}
- }
- else
- {
- /* Invalid line or INQUIRY. We can't do anything else than
- to stop. As with ERR we prefer a status callback
- generated error code, though. */
- TRACE (DEBUG_CTX, "gpgsm_assuan_simple_command", gpgsm,
- "Invalid line seen: %s", line);
- err = cb_err ? cb_err : gpg_error (GPG_ERR_GENERAL);
- cb_err = 0;
}
+ while (!err && assuan_pending_line (ctx));
}
- while (!err);
+ while (!err && !done);
/* We only want the first error from the status handler, thus we
* take the one saved in CB_ERR. */