1 /*
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * File Name: suggsrv.c
27 *
28 * Author: Yuri Sadykov
29 *
30 * Version Creation Date: 08/14/95
31 *
32 * $Revision: 6.1 $
33 *
34 * File Description:
35 * Implementation of Suggest server. Here it is only server specific
36 * part, mainly related with reading of requests from a client and writing
37 * responces. The implementaion of the processing of data is in suggest.c
38 * and adjust.c
39 *
40 * Modifications:
41 * --------------------------------------------------------------------------
42 * Date Name Description of modification
43 * ------- ---------- -----------------------------------------------------
44 *
45 * ==========================================================================
46 *
47 *
48 * RCS Modification History:
49 * $Log: suggsrv.c,v $
50 * Revision 6.1 2004/04/01 13:43:07 lavr
51 * Spell "occurred", "occurrence", and "occurring"
52 *
53 * Revision 6.0 1997/08/25 18:40:59 madden
54 * Revision changed to 6.0
55 *
56 * Revision 1.6 1996/07/09 21:40:29 epstein
57 * add kludge Nlm_Main() to allow program to be built with shared libs
58 *
59 * Revision 1.5 1995/12/12 18:52:54 kans
60 * now uses functions in suggslp.c
61 *
62 * Revision 1.4 1995/11/27 21:03:40 sad
63 * Fixed error related with initializing global structure;
64 *
65 * Fixed error while writing interval's fields from and to, which had
66 * values less then required;
67 *
68 * Added writing strand values in output intervals;
69 *
70 * Now all intervals with the same product are within single feature;
71 *
72 */
73
74 #include <ncbinet.h>
75 #include <seqport.h>
76 #include <suggslp.h>
77 #include <suggen.h>
78
79 /*****************************************************************************
80 * External function prototipes
81 */
82
83 /*****************************************************************************
84 * Function prototipes
85 */
86 static Boolean
87 ServeClient(AsnIoPtr pAsnIn, AsnIoPtr pAsnOut);
88
89 static SuggestErrorPtr
90 GetLastSuggestError(void);
91
92 static MsgAnswer LIBCALLBACK
93 SuggestMessageHook(MsgKey msgKey, ErrSev errSev,
94 const char *pchCaption, const char *pchMessage);
95
96 static void
97 SetSuggestMessageHook(void);
98
99 static void
100 RestoreMessageHook(void);
101
102 static SuggestErrorPtr
103 GetLastSuggestError(void);
104
105 static void
106 ClearSuggestError(void);
107
108 /*============================================================================*\
109 * Function:
110 * main
111 *
112 * Purpose:
113 * Entry point. This function is for suggest if it is built as a server.
114 *
115 * Parameters:
116 * Only one option to the application is acceptable "-d" which means that
117 * the application must running without network capability and input and output
118 * of data are through the local files. It's very convinient for debugging.
119 *
120 * Return:
121 * Error code
122 \*----------------------------------------------------------------------------*/
123 int
main(int argc,char * argv[])124 main(int argc, char *argv[])
125 {
126 int iArg;
127 int iReadTimeout;
128 Boolean bDebug = FALSE;
129 AsnIoPtr pAsnIoIn;
130 AsnIoPtr pAsnIoOut;
131 Char achBuff[100];
132 NI_HandPtr pHand;
133
134 if (argc > 1) {
135 iArg = 1;
136 if (StrCmp(argv[1], "-d") == 0) {
137 iArg++;
138 bDebug = TRUE;
139 }
140 }
141
142 if (bDebug) {
143 /* For debugging of the server only.
144 * Read and write local files only, no communication
145 * with clients.
146 */
147 pAsnIoIn = AsnIoOpen("suggsrv.in", "r");
148 pAsnIoOut = AsnIoOpen("suggsrv.out", "w");
149 } else {
150 /* Send acknowledgment--all right
151 */
152 NI_ServerACK();
153
154 /* Create connection with client, i.e. input and output
155 */
156 pHand = NI_OpenASNIO();
157
158 /* this read-timeout is effectively an idle timeout for
159 * the server process; the process will terminate upon
160 * read-timeout
161 */
162 GetAppParam("NCBI", "NET_SRV", "SERV_INACT_TIMER",
163 "10", achBuff, sizeof(achBuff));
164 iReadTimeout = atoi(achBuff) * 60; /* param is minutes */
165 MsgSetReadTimeout(pHand, iReadTimeout);
166 pAsnIoIn = pHand->raip;
167 pAsnIoOut = pHand->waip;
168 }
169
170 suggestOut.bServer = TRUE;
171
172 /* Serve a client
173 */
174 while (ServeClient(pAsnIoIn, pAsnIoOut))
175 ;
176
177 AsnIoClose(pAsnIoIn);
178 AsnIoClose(pAsnIoOut);
179 }
180
181 /*****************************************************************************\
182 * Function:
183 * ServeClient
184 *
185 * Purpose:
186 * Reads one request from a client and sends to it the result of
187 * processing.
188 *
189 * Parameter:
190 * pAsnIoIn - input file from which the request are read;
191 * pAsnIoOut - output file to which
192 *
193 * Return:
194 * FALSE if nothing more to process or error occurred and farther
195 * processing is not possible, otherwise TRUE.
196 *
197 \*****************************************************************************/
198 static Boolean
ServeClient(AsnIoPtr pAsnIn,AsnIoPtr pAsnOut)199 ServeClient(AsnIoPtr pAsnIn, AsnIoPtr pAsnOut)
200 {
201 short iErrAct;
202 ErrDesc err;
203 Boolean bOnceMore = TRUE;
204 Uint2 errLevel;
205 SuggestErrorPtr pSError;
206 SuggestRequestPtr pReq;
207 SuggestResponsePtr pResp;
208 SuggestIntervalsPtr pSIntervals;
209
210 /* Encountering EOF on reading is a "normal" occurrence,
211 * and does not merit an error message
212 */
213 ErrGetOpts(&iErrAct, NULL);
214 ErrSetOpts(ERR_IGNORE, 0);
215 ErrFetch(&err); /* clear any pending error, which can be ignored */
216
217 pReq = SuggestRequestAsnRead (pAsnIn, NULL);
218
219 if (ErrFetch(&err)) {
220 ErrPostEx(SEV_ERROR, 1, 1, "Error encountered on AsnReadId %d", err);
221
222 return FALSE;
223 }
224
225 ErrSetOpts(iErrAct, 0);
226
227 if (pReq == NULL) {
228 ErrPostEx(SEV_ERROR, 1, 1, "Null AsnReadId");
229
230 return FALSE;
231 }
232
233 switch (pReq->choice) {
234 case SuggestRequest_init: /* Initializing */
235 pResp = ValNodeNew(NULL);
236 SetSuggestMessageHook();
237 if (InitSuggest()) {
238 /* Init successful, send OK.
239 */
240 pResp->choice = SuggestResponse_init;
241 pResp->data.ptrvalue = NULL;
242 } else {
243 /* Error while init, send error
244 */
245 pResp->choice = SuggestResponse_error;
246 pResp->data.ptrvalue = (Pointer)GetLastSuggestError();
247 bOnceMore = FALSE; /* Cancel farther processing */
248 }
249 SuggestResponseAsnWrite(pResp, pAsnOut, NULL);
250 RestoreMessageHook();
251 pResp->data.ptrvalue = NULL; /* It's not necessary to free
252 * SuggestError structure.
253 */
254 SuggestResponseFree(pResp);
255 pReq->data.ptrvalue = NULL;
256 break;
257
258 case SuggestRequest_intervals: /* What this server does */
259 pSIntervals = pReq->data.ptrvalue;
260
261 pResp = ValNodeNew(NULL);
262 SetSuggestMessageHook();
263
264 /* The main task of this application, process the data
265 */
266 SuggestClientService (pSIntervals);
267
268 /* Check for error while the processing
269 */
270 pSError = GetLastSuggestError();
271 errLevel = pSError->level;
272
273 if (errLevel == Suggest_error_level_error ||
274 errLevel == Suggest_error_level_fatal)
275 {
276 /* Fatal error occurs, send error message to athe client
277 * and flags that the application must exit
278 */
279 pResp->choice = SuggestResponse_error;
280 pResp->data.ptrvalue = GetLastSuggestError();
281 if (errLevel == Suggest_error_level_fatal)
282 bOnceMore = FALSE;
283
284 /**** SeqAnnotFree(suggestOut.out.pSeqAnnot); */
285 } else {
286 pResp->choice = SuggestResponse_intervals;
287 pResp->data.ptrvalue = suggestOut.out.pSeqAnnot;
288 }
289
290 SuggestResponseAsnWrite(pResp, pAsnOut, NULL);
291 RestoreMessageHook();
292 SuggestResponseFree(pResp);
293 suggestOut.out.pSeqAnnot = NULL;
294 break;
295
296 case SuggestRequest_fini: /* Deinitializing */
297 pResp = ValNodeNew(NULL);
298 pResp->choice = SuggestResponse_fini;
299 pResp->data.ptrvalue = NULL;
300 SuggestResponseAsnWrite(pResp, pAsnOut, NULL);
301 SuggestResponseFree(pResp);
302 pReq->data.ptrvalue = NULL;
303 bOnceMore = FALSE;
304 break;
305
306 default:
307 /* All request types must be processed.
308 * No default processing.
309 */
310 ASSERT(FALSE);
311 }
312
313 AsnIoReset(pAsnOut);
314 SuggestRequestFree(pReq); /* free read request */
315
316 return bOnceMore;
317 }
318
319 static MsgAnswer LIBCALLBACK
SuggestMessageHook(MsgKey msgKey,ErrSev errSev,const char * pchCaption,const char * pchMessage)320 SuggestMessageHook(MsgKey msgKey, ErrSev errSev,
321 const char *pchCaption, const char *pchMessage)
322 {
323 switch (errSev) {
324 case MSG_ERROR:
325 suggestError.level = Suggest_error_level_error;
326 break;
327
328 case MSG_FATAL:
329 suggestError.level = Suggest_error_level_fatal;
330 break;
331 }
332
333 if (suggestError.msg != NULL)
334 MemFree(suggestError.msg);
335
336 suggestError.msg = StringSave(pchMessage);
337
338 return ANS_NONE;
339 }
340
341 /*============================================================================*\
342 * Function:
343 * SetSuggesstMessageHook
344 *
345 * Purpose:
346 * Sets hook function for intercepting all calls to Message
347 *
348 * Parameters:
349 * None
350 *
351 * Return:
352 * None
353 *
354 \*----------------------------------------------------------------------------*/
355 static void
SetSuggestMessageHook(void)356 SetSuggestMessageHook(void)
357 {
358 fOldMsgHook = SetMessageHook(SuggestMessageHook);
359 ClearSuggestError();
360 }
361
362 /*============================================================================*\
363 * Function:
364 * RestoreMessageHook
365 *
366 * Purpose:
367 * Resotore old hook function.
368 *
369 * Parameters:
370 * none
371 *
372 * Return:
373 * none
374 *
375 \*----------------------------------------------------------------------------*/
376 static void
RestoreMessageHook(void)377 RestoreMessageHook(void)
378 {
379 fOldMsgHook = SetMessageHook(fOldMsgHook);
380 ClearSuggestError();
381 }
382
383 /*============================================================================*\
384 * Function:
385 * GetLastSuggestError
386 *
387 * Purpose:
388 *
389 *
390 * Parameters:
391 * none
392 *
393 * Return:
394 * pointer to SuggestError structure, which contains information about
395 * last error.
396 *
397 \*----------------------------------------------------------------------------*/
398 static SuggestErrorPtr
GetLastSuggestError(void)399 GetLastSuggestError(void)
400 {
401 return &suggestError;
402 }
403
404 /*============================================================================*\
405 * Function:
406 * ClearSuggestError
407 *
408 * Purpose:
409 * Sets last error to a state which corresponds to no error.
410 *
411 * Parameters:
412 * none
413 *
414 * Return:
415 * none
416 *
417 \*----------------------------------------------------------------------------*/
418 static void
ClearSuggestError(void)419 ClearSuggestError(void)
420 {
421 suggestError.level = Suggest_error_level_none;
422 if (suggestError.msg != NULL)
423 MemFree(suggestError.msg);
424
425 suggestError.msg = NULL;
426 }
427
428 Int2
Nlm_Main(void)429 Nlm_Main(void)
430 {
431 fprintf(stderr,"Kludge main executed in file %s", __FILE__);
432 exit (1);
433 }
434