/* * Copyright (c) 1995, 1996 Gunther Schadow. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "pg_config.h" IDENT("@(#) ANYmsg-server.cc (Gunther Schadow) 12/19/96"); #include "ANYmsg.h" #include "ACKmsg.h" #include "UniMesg.h" #include "logfile.h" #include "exception.h" #include "xios.h" #include "ParseTrace.h" #include "hl7/parsetrace.h" #include "illp-session.h" #include "sockinet.h" #include #include "HL7hostent.h" void ANYmsg::init_services() { _services = new service_t[UniMesIdCode::size]; _allowed.clear(); for(int i = 0; i <= UniMesIdCode::size; i++) _services[i] = NULL; } void ANYmsg::register_service(UniMesIdCode::Value umid, service_t serv) { if(_services == NULL) init_services(); allow(umid); _services[umid - UniMesIdCode::first] = serv; } static void send_error_message(class iosockinet *io, class MSHseg&, const char *msg, const char *App, const char *Fac); void ANYmsg::serve(const char *service, const char *App, const char *Fac, bool exactMatch) { connect_id_t connect_id; class iosockinet *io = accept_illp(service, &connect_id); if(receive_message(io, *this, App, Fac) == SUCCESS) { HL7hostent h; if((h.getent((*io)->peerhost(), connect_id, (const char *)_msg->MesHea.SenApp, (const char *)_msg->MesHea.SenFac, App, Fac) == SUCCESS) && h.getAllowed().test((int)UniMesId(_msg->MesHea.MesType)) && ( !exactMatch || App==NULL || _msg->MesHea.RecApp == App ) && ( !exactMatch || Fac==NULL || _msg->MesHea.RecFac == Fac )) { LOGNOTICE("%s^%s from %s, %s, %s, %s, %s, %s", (const char*)_msg->MesHea.MesType.MesId, (const char*)_msg->MesHea.MesType.EventType, (*io)->peerhost(), connect_id, (const char *)_msg->MesHea.SenApp, (const char *)_msg->MesHea.SenFac, App, Fac); if(::send_message(io, *((*_services[type()])(*_msg))) == SUCCESS) exit(0); else { LOGWARNING("error exit"); exit(1); } } else { STtyp TextMes("service "); TextMes += _msg->MesHea.MesType.MesId; if(_msg->MesHea.MesType.EventType.ispresent()) { TextMes += "_"; TextMes += _msg->MesHea.MesType.EventType; } TextMes += " denied"; send_error_message(io, _msg->MesHea, (const char*)TextMes, App, Fac); LOGWARNING("%s for %s, %s, %s, %s, %s, %s", (const char*)TextMes, (*io)->peerhost(), connect_id, (const char *)_msg->MesHea.SenApp, (const char *)_msg->MesHea.SenFac, App, Fac); exit(1); } } else { MSHseg msh; if(msh.input(*io)) { STtyp TextMes("unsupported message type: "); TextMes += msh.MesType.MesId; if(msh.MesType.EventType.ispresent()) { TextMes += "_"; TextMes += msh.MesType.EventType; } send_error_message(io, msh, (const char *)TextMes, App, Fac); LOGWARNING("error exit"); exit(1); } else { send_error_message(io, msh, "couldn't read MSH segment", App, Fac); LOGWARNING("error exit"); exit(1); } } } static void send_error_message(class iosockinet *io, class MSHseg &msh, const char *msg, const char *App, const char *Fac) { ACKmsg ack; ack.MesHea.RecApp = msh.SenApp; ack.MesHea.RecFac = msh.SenFac; ack.MesHea.MesConTrolId = msh.MesConTrolId; ack.MesHea.SenApp = App; ack.MesHea.SenFac = Fac; stamp(ack.MesHea.DateTimeOfMes); char xanbuf[20]; sprintf(xanbuf,"RES%05u", (u_int)getpid()); ack.MesHea.MesConTrolId = xanbuf; ack.MesHea.ProId = ProIdCode::Pro; #ifdef HL7V21 ack.MesHea.VerId = 2.1; #else ack.MesHea.VerId = VerIdCode::_2_2val; #endif ack.MesAck.Ack = AckCode::AppRej; ack.MesAck.TextMes = msg; ack.Error = parseErrorSegment; ack.commit(); ack.output(*io); io->flush(); }