1 /*   netlib.c
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:  netlib.c
27 *
28 * Author:  Epstein
29 *
30 * Version Creation Date:   06/05/92
31 *
32 * $Revision: 6.3 $
33 *
34 * File Description:
35 *       miscellaneous library for network Entrez
36 *
37 * Modifications:
38 * --------------------------------------------------------------------------
39 * Date     Name        Description of modification
40 * -------  ----------  -----------------------------------------------------
41 *
42 * ==========================================================================
43 *
44 *
45 * RCS Modification History:
46 * $Log: netlib.c,v $
47 * Revision 6.3  2012/02/19 03:45:24  lavr
48 * Cleanup of obsolete features
49 *
50 * Revision 6.2  2005/07/25 18:06:48  lavr
51 * Remove deprecated ni_ API references
52 *
53 * Revision 6.1  1998/08/24 21:00:51  kans
54 * fixed -v -fd warnings
55 *
56 * Revision 6.0  1997/08/25 18:35:01  madden
57 * Revision changed to 6.0
58 *
59 * Revision 5.2  1997/07/29 21:24:15  vakatov
60 * [WIN32,DLL]  DLL'zation of "netentr.lib"
61 *
62 * Revision 5.1  1997/06/05 15:51:58  epstein
63 * change name of NetInit function per Eric Hackborn's request
64 *
65 * Revision 5.0  1996/05/28 14:10:21  ostell
66 * Set to revision 5.0
67 *
68  * Revision 4.2  1995/11/27  21:48:31  epstein
69  * add information regarding outgoing connection to detailed-info
70  *
71  * Revision 4.1  1995/10/02  15:28:53  epstein
72  * support range-checking
73  *
74  * Revision 4.0  1995/07/26  13:54:59  ostell
75  * force revision to 4.0
76  *
77  * Revision 1.22  1995/05/17  17:53:17  epstein
78  * add RCS log revision history
79  *
80 */
81 
82 #include <ncbi.h>
83 #include <asn.h>
84 #include <accentr.h>
85 #include <cdconfig.h>
86 #include <ncbinet.h>
87 #include <netentr.h>
88 #include <netpriv.h>
89 #include <objmedli.h>
90 #include <objsset.h>
91 #include <objloc.h>
92 #include <objneten.h>
93 
94 #define STAT_CHUNK 32
95 
96 static Boolean loaded = FALSE;
97 
98 static NetStatPtr PNTR statVector = NULL;
99 static Int2 numStats = 0;
100 static Boolean statsDisabled = FALSE;
101 static Int2 maxCurStats;
102 static Boolean reallyFinal = TRUE;
103 
104 static int num_attached = 0;
105 static char lastDispatcher[60];
106 static NI_HandPtr lastEntrezServ = NULL;
107 static CharPtr statsPtr = NULL;
108 static NI_DispatcherPtr dispatcher = NULL;
109 
110 static AsnTypePtr ENTREZ_TERM_LIST = NULL;
111 static AsnTypePtr ENTREZ_TERM_LIST_E = NULL;
112 static AsnTypePtr ENTREZ_TERM_LIST_E_operator = NULL;
113 static AsnTypePtr ENTREZ_TERM_LIST_E_sp_operand = NULL;
114 static AsnTypePtr ENTREZ_TERM_LIST_E_tot_operand = NULL;
115 static AsnTypePtr ENTREZ_TERM_RESP = NULL;
116 static AsnTypePtr ENTREZ_TERM_RESP_first_page = NULL;
117 static AsnTypePtr ENTREZ_TERM_RESP_info = NULL;
118 static AsnTypePtr ENTREZ_TERM_RESP_info_E = NULL;
119 static AsnTypePtr ENTREZ_TERM_RESP_num_terms = NULL;
120 static AsnTypePtr ENTREZ_TERM_RESP_pages_read = NULL;
121 static AsnTypePtr SPECIAL_OPERAND_fld = NULL;
122 static AsnTypePtr SPECIAL_OPERAND_term = NULL;
123 static AsnTypePtr SPECIAL_OPERAND_type = NULL;
124 static AsnTypePtr SPECIAL_OPERAND_high_range = NULL;
125 static AsnTypePtr TOTAL_OPERAND_fld = NULL;
126 static AsnTypePtr TOTAL_OPERAND_term = NULL;
127 static AsnTypePtr TOTAL_OPERAND_type = NULL;
128 static AsnTypePtr TOTAL_OPERAND_high_range = NULL;
129 
130 static void appendStats PROTO((CharPtr s));
131 static Int2 NEAR statCompare PROTO((NetStatPtr s1, NetStatPtr s2));
132 static void NEAR FreeNetStats PROTO((void));
133 static Boolean SwapOutNet PROTO ((VoidPtr med));
134 
135 
FindAsnType(AsnTypePtr PNTR atp,AsnModulePtr amp,CharPtr str)136 static void NEAR FindAsnType (AsnTypePtr PNTR atp, AsnModulePtr amp, CharPtr str)
137 
138 {
139   if (atp != NULL && (*atp) == NULL) {
140     *atp = AsnTypeFind (amp, str);
141   }
142 }
143 
InitLoad(void)144 static Boolean InitLoad(void)
145 {
146     AsnModulePtr amp;
147     static Boolean loaded = FALSE;
148 
149     if (loaded)
150         return TRUE;
151     if (! NetEntAsnLoad() )
152         return FALSE;
153     amp = AsnAllModPtr();
154 
155     FindAsnType(&ENTREZ_TERM_LIST, amp, "Entrez-term-list");
156     FindAsnType(&ENTREZ_TERM_LIST_E, amp, "Entrez-term-list.E");
157     FindAsnType(&ENTREZ_TERM_LIST_E_operator, amp, "Entrez-term-list.E.operator");
158     FindAsnType(&ENTREZ_TERM_LIST_E_sp_operand, amp, "Entrez-term-list.E.sp-operand");
159     FindAsnType(&ENTREZ_TERM_LIST_E_tot_operand, amp, "Entrez-term-list.E.tot-operand");
160     FindAsnType(&ENTREZ_TERM_RESP, amp, "Entrez-term-resp");
161     FindAsnType(&ENTREZ_TERM_RESP_first_page, amp, "Entrez-term-resp.first-page");
162     FindAsnType(&ENTREZ_TERM_RESP_info, amp, "Entrez-term-resp.info");
163     FindAsnType(&ENTREZ_TERM_RESP_info_E, amp, "Entrez-term-resp.info.E");
164     FindAsnType(&ENTREZ_TERM_RESP_num_terms, amp, "Entrez-term-resp.num-terms");
165     FindAsnType(&ENTREZ_TERM_RESP_pages_read, amp, "Entrez-term-resp.pages-read");
166     FindAsnType(&SPECIAL_OPERAND_fld, amp, "Special-operand.fld");
167     FindAsnType(&SPECIAL_OPERAND_term, amp, "Special-operand.term");
168     FindAsnType(&SPECIAL_OPERAND_type, amp, "Special-operand.type");
169     FindAsnType(&SPECIAL_OPERAND_high_range, amp, "Special-operand.high-range");
170     FindAsnType(&TOTAL_OPERAND_fld, amp, "Total-operand.fld");
171     FindAsnType(&TOTAL_OPERAND_term, amp, "Total-operand.term");
172     FindAsnType(&TOTAL_OPERAND_type, amp, "Total-operand.type");
173     FindAsnType(&TOTAL_OPERAND_high_range, amp, "Total-operand.high-range");
174 
175     loaded = TRUE;
176     return TRUE;
177 }
178 
179 
TermRespNew(void)180 NLM_EXTERN TermRespPtr CDECL TermRespNew(void)
181 {
182     TermRespPtr p;
183 
184     p = (TermRespPtr) MemNew(sizeof(TermResp));
185     p->num_terms = 0;
186     if (p != NULL)
187     {
188         p->termresp = NULL;
189     }
190     return p;
191 }
192 
193 NLM_EXTERN TermRespPtr CDECL
TermRespFree(TermRespPtr p)194 TermRespFree(TermRespPtr p)
195 {
196     if (p == NULL)
197         return NULL;
198     if (p->termresp != NULL)
199     {
200         if (p->termresp->term != NULL)
201             MemFree(p->termresp->term);
202         MemFree (p->termresp);
203     }
204     return ((TermRespPtr) MemFree (p));
205 }
206 
TermRespAsnRead(AsnIoPtr aip,AsnTypePtr orig)207 NLM_EXTERN TermRespPtr CDECL TermRespAsnRead (AsnIoPtr aip, AsnTypePtr orig)
208 {
209     DataVal av;
210     AsnTypePtr atp;
211     int i;
212     TermRespPtr tp;
213     TermPageInfoPtr tpi;
214     AsnModulePtr amp;
215 
216     amp = AsnAllModPtr();
217 
218     if (aip == NULL)
219         return NULL;
220 
221     if (orig == NULL)
222         atp = AsnReadId(aip, amp, ENTREZ_TERM_RESP);
223     else
224         atp = AsnLinkType(orig, ENTREZ_TERM_RESP); /* link in local tree */
225 
226     if (atp == NULL)
227         return NULL;
228 
229     tp = TermRespNew();
230 
231     if (tp == NULL)
232         goto erret;
233 
234     if (AsnReadVal(aip, atp, NULL) <= 0) /* read the start struct */
235         goto erret;
236     if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_RESP_num_terms)
237         goto erret;
238     if (AsnReadVal(aip, atp, &av) < 0)
239         goto erret;
240     tp->num_terms = av.intvalue;
241     tp->first_page = -1;
242 
243     if ((atp = AsnReadId(aip, amp, atp)) == ENTREZ_TERM_RESP_first_page)
244     { /* optional */
245         if (AsnReadVal(aip, atp, &av) < 0)
246             goto erret;
247         tp->first_page = av.intvalue;
248         atp = AsnReadId(aip, amp, atp);
249     }
250 
251     if (atp != ENTREZ_TERM_RESP_pages_read)
252         goto erret;
253     if (AsnReadVal(aip, atp, &av) <= 0)
254         goto erret;
255     tp->num_pages_read = av.intvalue;
256 
257     if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_RESP_info)
258         goto erret;
259     if (AsnReadVal(aip, atp, NULL) <= 0)
260         goto erret;
261     tp->termresp = MemNew(sizeof(struct termresp) * (size_t) tp->num_terms);
262     for (i = 0; i < tp->num_terms; i++)
263     {
264         if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_RESP_info_E)
265             goto erret;
266         if ((tpi = TermPageInfoAsnRead(aip, atp)) == NULL)
267             goto erret;
268         tp->termresp[i].special_count = tpi->spec_count;
269         tp->termresp[i].total_count = tpi->tot_count;
270         tp->termresp[i].term = tpi->term;
271         tpi->term = NULL; /* for clean free */
272         TermPageInfoFree (tpi);
273     }
274 
275     if ((atp = AsnReadId(aip, amp, atp)) != ENTREZ_TERM_RESP_info)
276         goto erret;
277     if (AsnReadVal(aip, atp, NULL) < 0)
278         goto erret;
279 
280     atp = AsnReadId(aip, amp, atp);
281     if (orig == NULL)
282     {
283         if (atp != ENTREZ_TERM_RESP)
284             goto erret;
285     }
286     else { /* check for "close struct" associated with "orig" */
287         if (atp != orig)
288             goto erret;
289     }
290 
291     if (AsnReadVal(aip, atp, NULL) <= 0) /* discard NULL */
292         goto erret;
293 
294 ret:
295     AsnUnlinkType(orig);
296     return tp;
297 
298 erret:
299     tp = TermRespFree (tp);
300     goto ret;
301 }
302 
303 NLM_EXTERN Boolean CDECL
BoolExprAsnWrite(ValNodePtr elst,AsnIoPtr aip,AsnTypePtr orig)304 BoolExprAsnWrite(ValNodePtr elst, AsnIoPtr aip, AsnTypePtr orig)
305 {
306     DataVal av;
307     static int n = 0;
308     TermDataPtr tp;
309     Boolean retval = FALSE;
310     AsnTypePtr atp;
311 
312     if (aip == NULL)
313         return FALSE;
314     atp = AsnLinkType(orig, ENTREZ_TERM_LIST); /* link local tree */
315 
316     if (atp == NULL)
317         return FALSE;
318 
319     if (elst == NULL)
320     {
321         AsnNullValueMsg(aip, atp);
322         goto erret;
323     }
324 
325     if (! AsnStartStruct(aip, atp))
326         goto erret;
327 
328     for (; elst != NULL; elst = elst->next)
329     {
330         AsnWrite (aip, ENTREZ_TERM_LIST_E, NULL);
331         switch (elst->choice) {
332         case SPECIALTERM:
333             tp = (TermDataPtr) elst->data.ptrvalue;
334 
335             AsnStartStruct (aip, ENTREZ_TERM_LIST_E_sp_operand);
336             av.ptrvalue = tp->term;
337             AsnWrite (aip, SPECIAL_OPERAND_term, &av);
338             av.intvalue = tp->field;
339             AsnWrite (aip, SPECIAL_OPERAND_fld, &av);
340             av.intvalue = tp->type;
341             AsnWrite (aip, SPECIAL_OPERAND_type, &av);
342             if ((av.ptrvalue = tp->highRange) != NULL)
343               AsnWrite (aip, SPECIAL_OPERAND_high_range, &av);
344             AsnEndStruct (aip, ENTREZ_TERM_LIST_E_sp_operand);
345             break;
346         case TOTALTERM:
347             tp = (TermDataPtr) elst->data.ptrvalue;
348 
349             AsnStartStruct (aip, ENTREZ_TERM_LIST_E_tot_operand);
350             av.ptrvalue = tp->term;
351             AsnWrite (aip, TOTAL_OPERAND_term, &av);
352             av.intvalue = tp->field;
353             AsnWrite (aip, TOTAL_OPERAND_fld, &av);
354             av.intvalue = tp->type;
355             AsnWrite (aip, TOTAL_OPERAND_type, &av);
356             if ((av.ptrvalue = tp->highRange) != NULL)
357               AsnWrite (aip, TOTAL_OPERAND_high_range, &av);
358             AsnEndStruct (aip, ENTREZ_TERM_LIST_E_tot_operand);
359             break;
360         case LPAREN:
361         case RPAREN:
362         case ANDSYMBL:
363         case ORSYMBL:
364         case BUTNOTSYMBL:
365             av.intvalue = elst->choice;
366             AsnWrite (aip, ENTREZ_TERM_LIST_E_operator, &av);
367             break;
368         default:
369             break;
370         }
371     }
372 
373 
374     if (! AsnEndStruct(aip, atp))
375         goto erret;
376 
377     retval = TRUE;
378 
379 erret:
380     AsnUnlinkType(orig);
381     return retval;
382 }
383 
384 NLM_EXTERN ValNodePtr CDECL
BoolExprAsnRead(AsnIoPtr aip,AsnTypePtr orig)385 BoolExprAsnRead(AsnIoPtr aip, AsnTypePtr orig)
386 {
387     ValNodePtr anp = NULL;
388     ValNodePtr head = NULL;
389     DataVal av;
390     TermDataPtr tp;
391     AsnTypePtr atp;
392     AsnTypePtr startsym;
393     AsnModulePtr amp;
394 
395     InitLoad();
396     amp = AsnAllModPtr();
397 
398     if (aip == NULL)
399         return NULL;
400 
401     if (orig == NULL)
402         atp = AsnReadId(aip, amp, ENTREZ_TERM_LIST);
403     else
404         atp = AsnLinkType(orig, ENTREZ_TERM_LIST); /* link in local tree */
405 
406     if (atp == NULL)
407         return NULL;
408 
409     if (AsnReadVal(aip, atp, NULL) < 0)
410         goto erret;
411 
412     while ((atp = AsnReadId(aip, amp, atp)) == ENTREZ_TERM_LIST_E)
413     {
414         if (AsnReadVal(aip, atp, NULL) < 0)
415             goto erret;
416 
417         atp = AsnReadId(aip, amp, atp);
418 
419         if (atp == ENTREZ_TERM_LIST_E_sp_operand ||
420             atp == ENTREZ_TERM_LIST_E_tot_operand)
421         {
422             startsym = atp; /* save this, to be able to find "close" sym */
423 
424             anp = ValNodeNew(anp);
425             if (head == NULL) /* keep track of head of list */
426                 head = anp;
427 
428             if (atp == ENTREZ_TERM_LIST_E_sp_operand)
429                 anp->choice = SPECIALTERM;
430             else
431                 anp->choice = TOTALTERM;
432 
433             if (AsnReadVal(aip, atp, NULL) < 0)
434                 goto erret;
435 
436             tp = (TermDataPtr) MemNew(sizeof(TermData));
437             anp->data.ptrvalue = (Pointer) tp;
438 
439             if (tp == NULL)
440                 goto erret;
441 
442             if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* term */
443                 goto erret;
444             if (AsnReadVal(aip, atp, &av) < 0)
445                 goto erret;
446             tp->term = av.ptrvalue;
447 
448             if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* fld */
449                 goto erret;
450             if (AsnReadVal(aip, atp, &av) < 0)
451                 goto erret;
452             tp->field = av.intvalue;
453 
454             if ((atp = AsnReadId(aip, amp, atp)) == NULL) /* type */
455                 goto erret;
456             if (AsnReadVal(aip, atp, &av) < 0)
457                 goto erret;
458             tp->type = av.intvalue;
459 
460             atp = AsnReadId(aip, amp, atp);
461             if (atp == SPECIAL_OPERAND_high_range ||
462                 atp == TOTAL_OPERAND_high_range)
463             {
464                 if (AsnReadVal(aip, atp, &av) < 0)
465                     goto erret;
466                 tp->highRange = av.ptrvalue;
467                 atp = AsnReadId(aip, amp, atp);
468             }
469             if (atp != startsym)
470                 goto erret;
471             if (AsnReadVal(aip, atp, NULL) < 0)
472                 goto erret;
473         }
474         else
475         if (atp == ENTREZ_TERM_LIST_E_operator)
476         {
477             if (AsnReadVal(aip, atp, &av) < 0)
478                 goto erret;
479             anp = ValNodeNew(anp);
480             if (head == NULL) /* keep track of head of list */
481                 head = anp;
482             anp->choice = av.intvalue;
483         }
484         else
485             goto erret;
486     }
487 
488     if (orig == NULL)
489     {
490         if (atp != ENTREZ_TERM_LIST)
491             goto erret;
492     }
493     else {
494         if (atp != orig)
495             goto erret;
496     }
497 
498     /* discard last value */
499     if (AsnReadVal(aip, atp, NULL) < 0)
500         goto erret;
501 
502     AsnUnlinkType(orig);
503     return head;
504 
505 erret:
506     ValNodeFree (head);
507     return NULL;
508 }
509 
appendStats(CharPtr s)510 static void appendStats(CharPtr s)
511 {
512     if (s != NULL)
513     {
514         StrCat(statsPtr, "    ");
515         StrCat(statsPtr, s);
516         StrCat(statsPtr, "\n");
517         statsPtr += StringLen(statsPtr);
518     }
519 }
520 
GetClientInfo(CharPtr buf)521 NLM_EXTERN void GetClientInfo (CharPtr buf)
522 {
523     if (buf == NULL)
524         return;
525 
526     StrCpy(buf, "NETWORK ACCESS\n  Last Dispatcher Used: ");
527     StrCat(buf, lastDispatcher);
528     StrCat(buf, "\n");
529     if (dispatcher != NULL)
530     {
531         if (dispatcher->motd != NULL && dispatcher->motd[0] != NULLB)
532         {
533             StrCat(buf, "\n  ");
534             StrCat(buf, dispatcher->motd);
535             StrCat(buf, "\n");
536         }
537         if (dispatcher->adminInfo != NULL && dispatcher->adminInfo[0] != NULLB)
538         {
539             StrCat(buf, "\n  Your Network Entrez administrator is:\n    ");
540             StrCat(buf, dispatcher->adminInfo);
541         }
542     }
543     if (lastEntrezServ != NULL)
544     {
545         StrCat(buf, "\n  Entrez service currently connected to ");
546         StrCat(buf, lastEntrezServ->hostname);
547         StrCat(buf, " server\n");
548         statsPtr = &buf[StringLen(buf)];
549         DumpNetStats(SUBSYS_CLI_ENTREZ, appendStats);
550     }
551 }
552 
statCompare(NetStatPtr s1,NetStatPtr s2)553 static Int2 NEAR statCompare (NetStatPtr s1, NetStatPtr s2)
554 {
555     if (s1 == NULL || s2 == NULL)
556         return 0;
557     if (s1->subsys < s2->subsys)
558         return -1;
559     if (s1->subsys > s2->subsys)
560         return 1;
561     return (Int2) StrCmp(s1->label, s2->label);
562 }
563 
FreeNetStats(void)564 static void NEAR FreeNetStats (void)
565 {
566     NetStatPtr PNTR statptr;
567     Int2 i;
568 
569     for (statptr = statVector, i = 0; i < numStats; i++, statptr++)
570     {
571         MemFree((*statptr)->label);
572         MemFree((*statptr));
573     }
574 
575     MemFree(statVector);
576     statVector = NULL;
577     numStats = 0;
578     statsDisabled = TRUE;
579 }
580 
DumpNetStats(Int2 subsys,StatsCallBack callBack)581 NLM_EXTERN void CDECL DumpNetStats (Int2 subsys, StatsCallBack callBack)
582 {
583     char s[200];
584     int i;
585     NetStatPtr stat;
586     Boolean foundFirst = FALSE;
587     Boolean okSubsys;
588     Int4 total;
589     double mean;
590     double stdev;
591 
592     for (i = 0; i < numStats; i++)
593     {
594         stat = statVector[i];
595         if (stat == NULL)
596             continue;
597 
598         okSubsys = stat->subsys == subsys || subsys == 0;
599         if (!foundFirst)
600         {
601             if (okSubsys)
602                 foundFirst = TRUE;
603             else
604                 continue;
605         }
606         if (foundFirst && !okSubsys)
607             break;
608         total = (Int4) (stat->total + 0.5);
609 
610         switch (stat->flags) {
611         case STAT_MEAN :
612             StrCpy (s, "{");
613             StrCat (s, stat->label);
614             if (stat->n > 0)
615                 mean = stat->total / stat->n;
616             else
617                 mean = 0.0;
618             sprintf (&s[strlen(s)], "} total = %ld, mean = %f", (long) total,
619                      mean);
620             break;
621         case STAT_MEAN | STAT_STDEV :
622             StrCpy (s, "{");
623             StrCat (s, stat->label);
624             if (stat->n > 0)
625                 mean = stat->total / stat->n;
626             else
627                 mean = 0.0;
628             if (stat->n <= 1)
629                 stdev = 0.0;
630             else
631                 stdev = sqrt(stat->sum_of_squares / (stat->n - 1));
632             sprintf (&s[strlen(s)], "} total = %ld, mean = %f, stdev = %f",
633                      (long) total, mean, stdev);
634             break;
635         default :
636             StrCpy (s, stat->label);
637             sprintf (&s[strlen(s)], " = %ld", (long) total);
638             break;
639         }
640         callBack (s);
641     }
642 }
643 
644 
LogNetStats(Int2 subsys,CharPtr label,Int4 dat,NetStatPtr PNTR statHandle,Int2 flags)645 NLM_EXTERN void CDECL LogNetStats (Int2 subsys, CharPtr label, Int4 dat,
646                          NetStatPtr PNTR statHandle, Int2 flags)
647 {
648     Int2 l;
649     Int2 r;
650     Int2 k;
651     Int2 compValue;
652     NetStatPtr newStat;
653     NetStatPtr Stat;
654     double mean;
655     double tempterm;
656 
657     if (statsDisabled)
658         return;
659 
660     if (statHandle == NULL || label == NULL)
661         return;
662 
663     if (*statHandle == NULL)
664     {
665         newStat = (NetStatPtr) MemNew(sizeof(NetStat));
666         newStat->subsys = subsys;
667         newStat->label = StringSave(label);
668         newStat->total = 0;
669         newStat->n = 0;
670         newStat->flags = 0;
671         newStat->sum_of_squares = 0.0;
672         k = 0;
673         if (statVector != NULL)
674         {
675             l = 0;
676             r = numStats - 1;
677             compValue = statCompare(newStat, statVector[k]);
678             while ((l <= r) && compValue != 0)
679             {
680                 k = (l + r) / 2;
681                 if ((compValue = statCompare(newStat, statVector[k])) < 0)
682                     r = k - 1;
683                 else
684                     l = k + 1;
685             }
686             if (compValue == 0)
687             { /* match */
688                 *statHandle = statVector[k];
689                 MemFree(newStat->label);
690                 MemFree(newStat); /* not needed */
691             }
692             else {
693                 while (compValue > 0 && k < numStats)
694                 {
695                     k++;
696                     compValue = statCompare(newStat, statVector[k]);
697                 }
698             }
699         }
700 
701         if (*statHandle == NULL)
702         { /* not found previously */
703             if (statVector == NULL)
704             {
705                 if ((statVector = (NetStatPtr PNTR) MemNew(sizeof(NetStatPtr) *
706                      STAT_CHUNK)) == NULL)
707                 {
708                     MemFree(newStat->label);
709                     MemFree(newStat);
710                     return;
711                 }
712                 maxCurStats = STAT_CHUNK;
713             }
714 
715             /* re-allocate vector if necessary */
716             if (numStats >= maxCurStats - 1)
717             {
718                 maxCurStats += STAT_CHUNK;
719                 if ((statVector = (NetStatPtr PNTR) Realloc(statVector,
720                      sizeof(NetStatPtr) * maxCurStats)) == NULL)
721                 {
722                     MemFree(newStat->label);
723                     MemFree(newStat);
724                     return;
725                 }
726             }
727 
728             /* move everything else up */
729             for (r = numStats - 1; r >= k; r--)
730             {
731                 statVector[r+1] = statVector[r];
732             }
733             statVector[k] = newStat;
734             *statHandle = newStat;
735             numStats++;
736         }
737     }
738 
739     Stat = *statHandle;
740     Stat->n++;
741     Stat->total += dat;
742     Stat->flags |= flags;
743     mean = Stat->total / Stat->n;
744     tempterm = (mean - dat);
745     Stat->sum_of_squares += tempterm * tempterm;
746 }
747 
748 /*******************************************************************************
749 *
750 *    NetEInit()
751 *
752 *    Connect to the network services dispatcher, unless already attached.
753 *******************************************************************************/
754 
NetEInit(void)755 NLM_EXTERN Boolean NetEInit(void)
756 {
757     if (! InitLoad())
758         return FALSE;
759 
760     if (num_attached++ > 0)
761         return TRUE;
762 
763     /* if ( there are no network-media ) then */
764     if (ParseMedia(NULL, MEDIUM_NETWORK) == 0)
765     {
766         num_attached--;
767         return FALSE;
768     }
769 
770     if ((dispatcher = NI_GenericInit(NULL, NULL, TRUE, lastDispatcher, sizeof(lastDispatcher))) != NULL) {
771         return TRUE;
772     }
773 
774     num_attached--;
775     return FALSE;
776 }
777 
778 
779 /*******************************************************************************
780 *
781 *    NetFini()
782 *
783 *    Disconnect from the network services dispatcher, if this is the last
784 *    service user which is detaching.
785 *******************************************************************************/
786 
NetFini(void)787 NLM_EXTERN Boolean CDECL NetFini(void)
788 {
789     if (num_attached > 0)
790         num_attached--;
791 
792     if (num_attached == 0)
793     {
794         NI_EndServices (dispatcher);
795         if (reallyFinal)
796             FreeNetStats();
797     }
798 
799     return TRUE;
800 }
801 
ForceNetInit(void)802 NLM_EXTERN Boolean CDECL ForceNetInit(void)
803 {
804     Boolean retval;
805 
806     reallyFinal = FALSE;
807     num_attached = 0; /* force re-attempt to contact dispatcher */
808     retval =  NetEInit();
809     reallyFinal = TRUE;
810 
811     return retval;
812 }
813 
NetServiceGet(CharPtr channel,CharPtr def_service,ConfCtlProc swapInProc,NI_HandPtr oldSessionHandle)814 extern NI_HandPtr NetServiceGet(CharPtr channel, CharPtr def_service,
815                          ConfCtlProc swapInProc, NI_HandPtr oldSessionHandle)
816 {
817     MediaPtr media;
818     NetMediaInfoPtr nmi;
819     NI_HandPtr firstSessionHandle = NULL;
820     CharPtr param_section;
821 
822     /* coding-trick to make current media match type "channel" */
823     if (! SelectDataSource(channel, "MEDIA", NULL))
824     {
825         return NULL;
826     }
827 
828     do {
829         media = GetCurMedia();
830         if (media == NULL)
831             continue;
832         if (media->media_type != MEDIUM_NETWORK)
833             continue;
834         nmi = (NetMediaInfoPtr) media->media_info;
835 
836         /* if media is already initialized, only attempt to re-obtain service */
837         /* if this media matches the media which failed or timed-out          */
838         if (nmi != NULL && nmi->sessionHandle != oldSessionHandle)
839             continue;
840 
841         if (nmi != NULL)
842         { /* de-allocate old resources */
843             NI_ServiceDisconnect(nmi->sessionHandle);
844             nmi->sessionHandle = NULL;
845         }
846         else { /* allocate structure */
847             nmi = (NetMediaInfoPtr) MemNew(sizeof(NetMediaInfo));
848             media->media_info = (VoidPtr) nmi;
849         }
850         nmi->sessionHandle = NULL;
851 
852         media->swapOutMedia = SwapOutNet;
853         media->swapInMedia = swapInProc;
854 
855         param_section = media->media_alias;
856 
857         nmi->sessionHandle = NI_GenericGetService(dispatcher, NULL,
858                                                   param_section, def_service,
859                                                   TRUE);
860         if (firstSessionHandle == NULL)
861             firstSessionHandle = nmi->sessionHandle;
862     } while (SelectNextDataSource());
863 
864     lastEntrezServ = firstSessionHandle;
865 
866     return firstSessionHandle;
867 }
868 
869 
SwapOutNet(VoidPtr med)870 static Boolean SwapOutNet (VoidPtr med)
871 {
872     return TRUE;
873 }
874