+ logf(LOG_WARN, "Serious programmer's lapse or bug");
+ abort();
+ }
+ if ((res && process_response(assoc, req, res) < 0) || fd < 0)
+ {
+ logf(LOG_LOG, "Fatal error when talking to backend");
+ cs_close(assoc->client_link);
+ destroy_association(assoc);
+ iochan_destroy(assoc->client_chan);
+ iochan_destroy(i);
+ return;
+ }
+ else if (!res) /* no result yet - try again later */
+ {
+ logf(LOG_DEBUG, " no result yet");
+ iochan_setfd(i, fd); /* in case fd has changed */
+ }
+}
+
+/*
+ * Encode response, and transfer the request structure to the outgoing queue.
+ */
+static int process_response(association *assoc, request *req, Z_APDU *res)
+{
+ odr_setbuf(assoc->encode, req->response, req->size_response, 1);
+ if (!z_APDU(assoc->encode, &res, 0))
+ {
+ logf(LOG_WARN, "ODR error when encoding response: %s",
+ odr_errlist[odr_geterror(assoc->decode)]);
+ return -1;
+ }
+ req->response = odr_getbuf(assoc->encode, &req->len_response,
+ &req->size_response);
+ odr_setbuf(assoc->encode, 0, 0, 0); /* don't free if we abort later */
+ odr_reset(assoc->encode);
+ if (assoc->print && !z_APDU(assoc->print, &res, 0))
+ {
+ logf(LOG_WARN, "ODR print error: %s",
+ odr_errlist[odr_geterror(assoc->print)]);
+ odr_reset(assoc->print);