+/*
+ * This is where PDUs from the client are read and the further
+ * processing is initiated. Flow of control moves down through the
+ * various process_* functions below, until the encoded result comes back up
+ * to the output handler in here.
+ *
+ * h : the I/O channel that has an outstanding event.
+ * event : the current outstanding event.
+ */
+void ir_session(IOCHAN h, int event)
+{
+ int res;
+ association *assoc = (association *)iochan_getdata(h);
+ COMSTACK conn = assoc->client_link;
+ request *req;
+
+ assert(h && conn && assoc);
+ if (event == EVENT_TIMEOUT)
+ {
+ if (assoc->state != ASSOC_UP)
+ {
+ yaz_log(log_session, "Timeout. Closing connection");
+ /* do we need to lod this at all */
+ cs_close(conn);
+ destroy_association(assoc);
+ iochan_destroy(h);
+ }
+ else
+ {
+ yaz_log(log_sessiondetail, "Timeout. Sending Z39.50 Close");
+ do_close(assoc, Z_Close_lackOfActivity, 0);
+ }
+ return;
+ }
+ if (event & assoc->cs_accept_mask)
+ {
+ if (!cs_accept(conn))
+ {
+ yaz_log(YLOG_WARN, "accept failed");
+ destroy_association(assoc);
+ iochan_destroy(h);
+ return;
+ }
+ iochan_clearflag(h, EVENT_OUTPUT);
+ if (conn->io_pending)
+ { /* cs_accept didn't complete */
+ assoc->cs_accept_mask =
+ ((conn->io_pending & CS_WANT_WRITE) ? EVENT_OUTPUT : 0) |
+ ((conn->io_pending & CS_WANT_READ) ? EVENT_INPUT : 0);
+
+ iochan_setflag(h, assoc->cs_accept_mask);
+ }
+ else
+ { /* cs_accept completed. Prepare for reading (cs_get) */
+ assoc->cs_accept_mask = 0;
+ assoc->cs_get_mask = EVENT_INPUT;
+ iochan_setflag(h, assoc->cs_get_mask);
+ }
+ return;
+ }
+ if (event & assoc->cs_get_mask) /* input */
+ {
+ if (!ir_read(h, event))
+ return;