📄 seshigh.c
字号:
iochan_settimeout(assoc->client_chan, statserv_getcontrol()->idle_timeout * 60); res = process_initRequest(assoc, req); break; case Z_APDU_searchRequest: res = process_searchRequest(assoc, req, &fd); break; case Z_APDU_presentRequest: res = process_presentRequest(assoc, req, &fd); break; case Z_APDU_scanRequest: if (assoc->init->bend_scan) res = process_scanRequest(assoc, req, &fd); else { *msg = "Cannot handle Scan APDU"; return -1; } break; case Z_APDU_extendedServicesRequest: if (assoc->init->bend_esrequest) res = process_ESRequest(assoc, req, &fd); else { *msg = "Cannot handle Extended Services APDU"; return -1; } break; case Z_APDU_sortRequest: if (assoc->init->bend_sort) res = process_sortRequest(assoc, req, &fd); else { *msg = "Cannot handle Sort APDU"; return -1; } break; case Z_APDU_close: process_close(assoc, req); return 0; case Z_APDU_deleteResultSetRequest: if (assoc->init->bend_delete) res = process_deleteRequest(assoc, req, &fd); else { *msg = "Cannot handle Delete APDU"; return -1; } break; case Z_APDU_segmentRequest: if (assoc->init->bend_segment) { res = process_segmentRequest (assoc, req); } else { *msg = "Cannot handle Segment APDU"; return -1; } break; default: *msg = "Bad APDU received"; return -1; } if (res) { yaz_log(LOG_DEBUG, " result immediately available"); retval = process_z_response(assoc, req, res); } else if (fd < 0) { yaz_log(LOG_DEBUG, " result unavailble"); retval = 0; } else /* no result yet - one will be provided later */ { IOCHAN chan; /* Set up an I/O handler for the fd supplied by the backend */ yaz_log(LOG_DEBUG, " establishing handler for result"); req->state = REQUEST_PENDING; if (!(chan = iochan_create(fd, backend_response, EVENT_INPUT))) abort(); iochan_setdata(chan, assoc); retval = 0; } return retval;}/* * Handle message from the backend. */void backend_response(IOCHAN i, int event){ association *assoc = (association *)iochan_getdata(i); request *req = request_head(&assoc->incoming); Z_APDU *res; int fd; yaz_log(LOG_DEBUG, "backend_response"); assert(assoc && req && req->state != REQUEST_IDLE); /* determine what it is we're waiting for */ switch (req->apdu_request->which) { case Z_APDU_searchRequest: res = response_searchRequest(assoc, req, 0, &fd); break;#if 0 case Z_APDU_presentRequest: res = response_presentRequest(assoc, req, 0, &fd); break; case Z_APDU_scanRequest: res = response_scanRequest(assoc, req, 0, &fd); break;#endif default: yaz_log(LOG_WARN, "Serious programmer's lapse or bug"); abort(); } if ((res && process_z_response(assoc, req, res) < 0) || fd < 0) { yaz_log(LOG_LOG, "Fatal error when talking to backend"); do_close(assoc, Z_Close_systemProblem, 0); iochan_destroy(i); return; } else if (!res) /* no result yet - try again later */ { yaz_log(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_gdu_response(association *assoc, request *req, Z_GDU *res){ odr_setbuf(assoc->encode, req->response, req->size_response, 1); if (assoc->print && !z_GDU(assoc->print, &res, 0, 0)) { yaz_log(LOG_WARN, "ODR print error: %s", odr_errmsg(odr_geterror(assoc->print))); odr_reset(assoc->print); } if (!z_GDU(assoc->encode, &res, 0, 0)) { yaz_log(LOG_WARN, "ODR error when decoding PDU: %s [element %s]", odr_errmsg(odr_geterror(assoc->decode)), odr_getelement(assoc->decode)); return -1; } req->response = odr_getbuf(assoc->encode, &req->len_response, &req->size_response); odr_setbuf(assoc->encode, 0, 0, 0); /* don'txfree if we abort later */ odr_reset(assoc->encode); req->state = REQUEST_IDLE; request_enq(&assoc->outgoing, req); /* turn the work over to the ir_session handler */ iochan_setflag(assoc->client_chan, EVENT_OUTPUT); assoc->cs_put_mask = EVENT_OUTPUT; /* Is there more work to be done? give that to the input handler too */#if 1 if (request_head(&assoc->incoming)) { yaz_log (LOG_DEBUG, "more work to be done"); iochan_setevent(assoc->client_chan, EVENT_WORK); }#endif return 0;}/* * Encode response, and transfer the request structure to the outgoing queue. */static int process_z_response(association *assoc, request *req, Z_APDU *res){ Z_GDU *gres = (Z_GDU *) odr_malloc(assoc->encode, sizeof(*res)); gres->which = Z_GDU_Z3950; gres->u.z3950 = res; return process_gdu_response(assoc, req, gres);}/* * Handle init request. * At the moment, we don't check the options * anywhere else in the code - we just try not to do anything that would * break a naive client. We'll toss 'em into the association block when * we need them there. */static Z_APDU *process_initRequest(association *assoc, request *reqb){ statserv_options_block *cb = statserv_getcontrol(); Z_InitRequest *req = reqb->apdu_request->u.initRequest; Z_APDU *apdu = zget_APDU(assoc->encode, Z_APDU_initResponse); Z_InitResponse *resp = apdu->u.initResponse; bend_initresult *binitres; char options[140]; yaz_log(LOG_LOG, "Got initRequest"); if (req->implementationId) yaz_log(LOG_LOG, "Id: %s", req->implementationId); if (req->implementationName) yaz_log(LOG_LOG, "Name: %s", req->implementationName); if (req->implementationVersion) yaz_log(LOG_LOG, "Version: %s", req->implementationVersion); assoc_init_reset(assoc); assoc->init->auth = req->idAuthentication; assoc->init->referenceId = req->referenceId; if (ODR_MASK_GET(req->options, Z_Options_negotiationModel)) { Z_CharSetandLanguageNegotiation *negotiation = yaz_get_charneg_record (req->otherInfo); if (negotiation->which == Z_CharSetandLanguageNegotiation_proposal) assoc->init->charneg_request = negotiation; } if (!(binitres = (*cb->bend_init)(assoc->init))) { yaz_log(LOG_WARN, "Bad response from backend."); return 0; } assoc->backend = binitres->handle; if ((assoc->init->bend_sort)) yaz_log (LOG_DEBUG, "Sort handler installed"); if ((assoc->init->bend_search)) yaz_log (LOG_DEBUG, "Search handler installed"); if ((assoc->init->bend_present)) yaz_log (LOG_DEBUG, "Present handler installed"); if ((assoc->init->bend_esrequest)) yaz_log (LOG_DEBUG, "ESRequest handler installed"); if ((assoc->init->bend_delete)) yaz_log (LOG_DEBUG, "Delete handler installed"); if ((assoc->init->bend_scan)) yaz_log (LOG_DEBUG, "Scan handler installed"); if ((assoc->init->bend_segment)) yaz_log (LOG_DEBUG, "Segment handler installed"); resp->referenceId = req->referenceId; *options = '\0'; /* let's tell the client what we can do */ if (ODR_MASK_GET(req->options, Z_Options_search)) { ODR_MASK_SET(resp->options, Z_Options_search); strcat(options, "srch"); } if (ODR_MASK_GET(req->options, Z_Options_present)) { ODR_MASK_SET(resp->options, Z_Options_present); strcat(options, " prst"); } if (ODR_MASK_GET(req->options, Z_Options_delSet) && assoc->init->bend_delete) { ODR_MASK_SET(resp->options, Z_Options_delSet); strcat(options, " del"); } if (ODR_MASK_GET(req->options, Z_Options_extendedServices) && assoc->init->bend_esrequest) { ODR_MASK_SET(resp->options, Z_Options_extendedServices); strcat (options, " extendedServices"); } if (ODR_MASK_GET(req->options, Z_Options_namedResultSets)) { ODR_MASK_SET(resp->options, Z_Options_namedResultSets); strcat(options, " namedresults"); } if (ODR_MASK_GET(req->options, Z_Options_scan) && assoc->init->bend_scan) { ODR_MASK_SET(resp->options, Z_Options_scan); strcat(options, " scan"); } if (ODR_MASK_GET(req->options, Z_Options_concurrentOperations)) { ODR_MASK_SET(resp->options, Z_Options_concurrentOperations); strcat(options, " concurrop"); } if (ODR_MASK_GET(req->options, Z_Options_sort) && assoc->init->bend_sort) { ODR_MASK_SET(resp->options, Z_Options_sort); strcat(options, " sort"); } if (ODR_MASK_GET(req->options, Z_Options_negotiationModel) && assoc->init->charneg_response) { Z_OtherInformation **p; Z_OtherInformationUnit *p0; yaz_oi_APDU(apdu, &p); if ((p0=yaz_oi_update(p, assoc->encode, NULL, 0, 0))) { ODR_MASK_SET(resp->options, Z_Options_negotiationModel); p0->which = Z_OtherInfo_externallyDefinedInfo; p0->information.externallyDefinedInfo = assoc->init->charneg_response; } ODR_MASK_SET(resp->options, Z_Options_negotiationModel); strcat(options, " negotiation"); } if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_1)) { ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_1); assoc->version = 2; /* 1 & 2 are equivalent */ } if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_2)) { ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_2); assoc->version = 2; } if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_3)) { ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_3); assoc->version = 3; } yaz_log(LOG_LOG, "Negotiated to v%d: %s", assoc->version, options); assoc->maximumRecordSize = *req->maximumRecordSize; if (assoc->maximumRecordSize > control_block->maxrecordsize) assoc->maximumRecordSize = control_block->maxrecordsize; assoc->preferredMessageSize = *req->preferredMessageSize; if (assoc->preferredMessageSize > assoc->maximumRecordSize) assoc->preferredMessageSize = assoc->maximumRecordSize; resp->preferredMessageSize = &assoc->preferredMessageSize; resp->maximumRecordSize = &assoc->maximumRecordSize; resp->implementationName = "GFS/YAZ"; if (assoc->init->implementation_id) { char *nv = (char *) odr_malloc (assoc->encode, strlen(assoc->init->implementation_id) + 10 + strlen(resp->implementationId)); sprintf (nv, "%s / %s", resp->implementationId, assoc->init->implementation_id); resp->implementationId = nv; } if (assoc->init->implementation_name) { char *nv = (char *) odr_malloc (assoc->encode, strlen(assoc->init->implementation_name) + 10 + strlen(resp->implementationName)); sprintf (nv, "%s / %s", resp->implementationName, assoc->init->implementation_name); resp->implementationName = nv; } if (assoc->init->implementation_version) { char *nv = (char *) odr_malloc (assoc->encode, strlen(assoc->init->implementation_version) + 10 + strlen(resp->implementationVersion)); sprintf (nv, "YAZ %s / %s", resp->implementationVersion, assoc->init->implementation_version); resp->implementationVersion = nv; } if (binitres->errcode) { yaz_log(LOG_LOG, "Connection rejected by backend."); *resp->result = 0; assoc->state = ASSOC_DEAD; } else assoc->state = ASSOC_UP; return apdu;}/* * These functions should be merged. */static void set_addinfo (Z_DefaultDiagFormat *dr, char *addinfo, ODR odr){ dr->which = Z_DefaultDiagFormat_v2Addinfo; dr->u.v2Addinfo = odr_strdup (odr, addinfo ? addinfo : "");}/* * nonsurrogate diagnostic record. */static Z_Records *diagrec(association *assoc, int error, char *addinfo){ Z_Records *rec = (Z_Records *) odr_malloc (assoc->encode, sizeof(*rec)); int *err = odr_intdup(assoc->encode, error); Z_DiagRec *drec = (Z_DiagRec *) odr_malloc (assoc->encode, sizeof(*drec)); Z_DefaultDiagFormat *dr = (Z_DefaultDiagFormat *) odr_malloc (assoc->encode, sizeof(*dr)); yaz_log(LOG_LOG, "[%d] %s %s%s", error, diagbib1_str(error), addinfo ? " -- " : "", addinfo ? addinfo : ""); rec->which = Z_Records_NSD; rec->u.nonSurrogateDiagnostic = dr; dr->diagnosticSetId = yaz_oidval_to_z3950oid (assoc->encode, CLASS_DIAGSET, VAL_BIB1); dr->condition = err; set_addinfo (dr, addinfo, assoc->encode); return rec;}/* * surrogate diagnostic.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -