1 /*   netentr.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:  netentr.c
27 *
28 * Author:  Ostell, Kans, Epstein
29 *
30 * Version Creation Date:   06/02/92
31 *
32 * $Revision: 6.8 $
33 *
34 * File Description:
35 *       entrez index access library for Network Entrez
36 *
37 * Modifications:
38 * --------------------------------------------------------------------------
39 * Date     Name        Description of modification
40 * -------  ----------  -----------------------------------------------------
41 * 06-08-93 Schuler     Changed datatype for Monitor from Handle to MonitorPtr
42 *
43 * 8-16-94  Brylawski   Added routines to access medline term explosion,
44 *                      mesh tree browsing, and on-the-fly neighboring.
45 *
46 * 11-20-94 Brylawski   Modifed on-the-fly neighboring to permit the client
47 *                      to pass more information about user preferences.
48 *
49 * ==========================================================================
50 *
51 *
52 * RCS Modification History:
53 * $Log: netentr.c,v $
54 * Revision 6.8  2005/07/25 18:06:48  lavr
55 * Remove deprecated ni_ API references
56 *
57 * Revision 6.7  1999/05/28 15:39:31  kans
58 * missing # on else and endif
59 *
60 * Revision 6.6  1999/05/28 15:28:19  beloslyu
61 * set the netEntrezVersion from the defined macro
62 *
63 * Revision 6.5  1999/05/28 13:42:35  beloslyu
64 * Change the version of netentrez
65 *
66 * Revision 6.4  1998/08/24 21:00:50  kans
67 * fixed -v -fd warnings
68 *
69 * Revision 6.3  1998/03/20 18:40:07  kans
70 * all xxxListAsnRead functions check for NULL, return before dereferencing NULL pointer
71 *
72 * Revision 6.2  1998/03/18 18:57:15  kans
73 * return if selp == NULL to avoid dereferencing
74 *
75 * Revision 6.1  1998/02/21 22:34:34  kans
76 * NetEntHierarchyGet passes type and field
77 *
78 * Revision 6.0  1997/08/25 18:34:53  madden
79 * Revision changed to 6.0
80 *
81 * Revision 5.7  1997/07/29 21:24:09  vakatov
82 * [WIN32,DLL]  DLL'zation of "netentr.lib"
83 *
84 * Revision 5.6  1997/06/05 15:52:14  epstein
85 * change name of NetInit function per Eric Hackborn's request
86 *
87 * Revision 5.5  1997/05/27 18:11:32  kans
88 * NI_Service get failure uses ErrPostEx, not Message
89 *
90 * Revision 5.4  1997/04/02 20:59:49  epstein
91 * Increased version number so network entrez server can detect older clients
92 *
93  * Revision 5.3  1996/09/24  16:07:21  epstein
94  * Add ASN.1 spec version so server can discriminate between clients based upon their spec version
95  *
96  * Revision 5.2  1996/08/14  22:58:11  epstein
97  * tweaks for biostruc annots
98  *
99  * Revision 5.1  1996/08/14  19:43:54  epstein
100  * add annot get by feat ids, and also add date filtering support
101  *
102  * Revision 5.0  1996/05/28  14:10:21  ostell
103  * Set to revision 5.0
104  *
105  * Revision 4.13  1996/03/29  18:55:41  epstein
106  * add support for structure alignments
107  *
108  * Revision 4.12  1996/03/26  16:30:29  epstein
109  * migrate byte-swapping functions to ncbimisc.[ch]
110  *
111  * Revision 4.11  1995/12/27  21:36:02  epstein
112  * eliminate duplicate SkipSpaces() function which conflicts with new ncbistr.c function
113  *
114  * Revision 4.10  1995/11/13  22:02:00  epstein
115  * fix BLAST bad-count bug (per S. Shavirin)
116  *
117  * Revision 4.9  1995/10/02  15:28:27  epstein
118  * support range-checking
119  *
120  * Revision 4.8  1995/09/21  16:17:55  kans
121  * moved prototype for MsgSetReadTimeout
122  *
123  * Revision 4.7  1995/09/21  14:55:46  epstein
124  * add higher timeouts for evaluating boolean expressions
125  *
126  * Revision 4.6  1995/09/11  19:28:49  epstein
127  * add some more bullet-proofing when reestablish connections
128  *
129  * Revision 4.5  1995/08/28  17:27:36  epstein
130  * work around compiler nit
131  *
132  * Revision 4.4  1995/08/24  20:48:35  epstein
133  * adjust timeouts to accomodate slow cluster analysis
134  *
135  * Revision 4.2  1995/08/22  19:35:24  epstein
136  * add clustering support
137  *
138  * Revision 4.1  1995/08/11  20:27:22  epstein
139  * add max-models support for biostrucs
140  *
141  * Revision 4.0  1995/07/26  13:54:59  ostell
142  * force revision to 4.0
143  *
144  * Revision 1.48  1995/07/11  14:51:50  epstein
145  * fix-up for new docsum implementation
146  *
147  * Revision 1.47  1995/06/29  16:36:28  epstein
148  * add biostruc-complexity, and use new biostrucX ASN.1 construct to communicate with server
149  *
150  * Revision 1.46  95/06/07  16:10:50  epstein
151  * add return value to SwapInEntrez()
152  *
153  * Revision 1.45  95/06/07  15:47:27  epstein
154  * make BLAST search cancellable in conjunction with Monitor
155  *
156  * Revision 1.44  95/05/17  17:53:08  epstein
157  * add RCS log revision history
158  *
159 */
160 
161 #include <accentr.h>
162 #include <ncbinet.h>
163 #include <netentr.h>
164 #include <netlib.h>
165 #include <netpriv.h>
166 #include <objneten.h>
167 
168 typedef struct namedItem {
169     Boolean   knownToServer;
170     CharPtr   term;
171     Char      tmpFileName[PATH_MAX];
172     DocType   type;
173     DocField  field;
174 } NamedItem, PNTR NamedItemPtr;
175 
176 static void NEAR s_NetEntrezFini PROTO((void));
177 static ByteStorePtr NEAR s_NetEntTLEvalX PROTO((ValNodePtr elst));
178 static Int2 NEAR s_NetDocSumListGet PROTO((DocSumPtr PNTR result, Int2 numuid, DocType type, DocUidPtr uids, Int2 defer_count));
179 static Int2 NEAR s_NetLinkUidList PROTO((LinkSetPtr PNTR result, DocType type, DocType link_to_type, Int2 numuid, DocUidPtr uids, Boolean mark_missing));
180 static LinkSetPtr NEAR s_NetUidLinks PROTO((DocType type, DocUid uid, DocType link_to_type));
181 static Int2 NEAR s_NetTermListByTerm PROTO((DocType type, DocField field, CharPtr term, Int2 numterms, TermListProc proc, Int2Ptr first_page));
182 static Int2 NEAR s_NetTermListByPage PROTO((DocType type, DocField field, Int2 page, Int2 numpage, TermListProc proc));
183 static Boolean NEAR s_NetEntrezFindTerm PROTO((DocType type, DocField field, CharPtr term, Int4Ptr spcl, Int4Ptr totl));
184 static void NEAR s_NetEntrezCreateNamedUidList PROTO((CharPtr term, DocType type, DocField field, Int4 num, DocUidPtr uids));
185 static Int2 NEAR s_NetEntSeqEntryListGet PROTO((SeqEntryPtr PNTR result, Int2 numuid, DocUidPtr uids, Int2 retcode, Boolean mark_missing));
186 static
187 Int2 NEAR s_NetEntMedlineEntryListGet PROTO((MedlineEntryPtr PNTR result, Int2 numuid, DocUidPtr uids, Boolean mark_missing));
188 
189 static NamedListPtr KnownNamedTerm PROTO((CharPtr term, Boolean onlyIfNotKnown, DocType type, DocField field));
190 static void CleanupNamedUidLists PROTO((void));
191 static AsnTypePtr NetEntReadAsn PROTO((void));
192 static Boolean ReestablishNetEntrez PROTO((void));
193 static Boolean SwapInEntrez PROTO((VoidPtr med));
194 static void countChars PROTO((CharPtr str));
195 
196 static NI_HandPtr Entrez_ni = NULL;
197 static AsnIoPtr   Entrez_asnin = NULL;
198 static AsnIoPtr   Entrez_asnout = NULL;
199 static EntrezInfoPtr vi = NULL;
200 static CharPtr    infoBuf = NULL;
201 static size_t     charCount = 0;
202 static ValNodePtr namedTerms = NULL;
203 #if defined(NETENTREZVERSION)
204 static CharPtr    netEntrezVersion = NETENTREZVERSION;
205 #else
206 static CharPtr    netEntrezVersion = "2.02c2ASN1SPEC6 ";
207 #endif
208 static CharPtr    userApplId = NULL;
209 static Boolean    userWarnings;
210 static EntrezExtraInfoPtr eeip = NULL;
211 static Int4       serviceAttempts = 0;
212 
213 static AsnTypePtr ENTREZ_BACK = NULL;
214 static AsnTypePtr ENTREZ_BACK_blast_bad_count = NULL;
215 static AsnTypePtr ENTREZ_BACK_blast_job_progress = NULL;
216 static AsnTypePtr ENTREZ_BACK_blast_job_start = NULL;
217 static AsnTypePtr ENTREZ_BACK_blast_link_set = NULL;
218 static AsnTypePtr ENTREZ_BACK_cluster_arts = NULL;
219 static AsnTypePtr ENTREZ_BACK_docsumX = NULL;
220 static AsnTypePtr ENTREZ_BACK_error = NULL;
221 static AsnTypePtr ENTREZ_BACK_evalX = NULL;
222 static AsnTypePtr ENTREZ_BACK_eval_count = NULL;
223 static AsnTypePtr ENTREZ_BACK_extrainfo = NULL;
224 static AsnTypePtr ENTREZ_BACK_get_hierarchy = NULL;
225 static AsnTypePtr ENTREZ_BACK_init = NULL;
226 static AsnTypePtr ENTREZ_BACK_init_e_info = NULL;
227 static AsnTypePtr ENTREZ_BACK_neighbortext = NULL;
228 static AsnTypePtr ENTREZ_REQUEST = NULL;
229 static AsnTypePtr ENTREZ_REQUEST_blast = NULL;
230 static AsnTypePtr ENTREZ_REQUEST_bypage = NULL;
231 static AsnTypePtr ENTREZ_REQUEST_byterm = NULL;
232 static AsnTypePtr ENTREZ_REQUEST_cluster_arts = NULL;
233 static AsnTypePtr ENTREZ_REQUEST_createnamed = NULL;
234 static AsnTypePtr ENTREZ_REQUEST_docsumX = NULL;
235 static AsnTypePtr ENTREZ_REQUEST_evalX = NULL;
236 static AsnTypePtr ENTREZ_REQUEST_eval_count = NULL;
237 static AsnTypePtr ENTREZ_REQUEST_extrainfo = NULL;
238 static AsnTypePtr ENTREZ_REQUEST_findseqid = NULL;
239 static AsnTypePtr ENTREZ_REQUEST_findterm = NULL;
240 static AsnTypePtr ENTREZ_REQUEST_fini = NULL;
241 static AsnTypePtr ENTREZ_REQUEST_get_hierarchy = NULL;
242 static AsnTypePtr ENTREZ_REQUEST_getbiostr = NULL;
243 static AsnTypePtr ENTREZ_REQUEST_getbiostrX = NULL;
244 static AsnTypePtr ENTREZ_REQUEST_getbiostrX_get = NULL;
245 static AsnTypePtr REQUEST_getbiostrX_complexity = NULL;
246 static AsnTypePtr REQUEST_getbiostrX_max_models = NULL;
247 static AsnTypePtr ENTREZ_REQUEST_getbiostrannot = NULL;
248 static AsnTypePtr REQUEST_getbiostr_feat_ids = NULL;
249 static AsnTypePtr REQUEST_getbiostr_annot_by_fid = NULL;
250 
251 static AsnTypePtr ENTREZ_REQUEST_getmle = NULL;
252 static AsnTypePtr ENTREZ_REQUEST_getseq = NULL;
253 static AsnTypePtr ENTREZ_REQUEST_initX = NULL;
254 static AsnTypePtr ENTREZ_REQUEST_initX_version = NULL;
255 static AsnTypePtr ENTREZ_REQUEST_linkuidlist = NULL;
256 static AsnTypePtr ENTREZ_REQUEST_neighbortext = NULL;
257 static AsnTypePtr ENTREZ_REQUEST_seqidforgi = NULL;
258 static AsnTypePtr ENTREZ_REQUEST_uidlinks = NULL;
259 static AsnTypePtr ENTREZ_TERMGET_cls = NULL;
260 static AsnTypePtr ENTREZ_TERMGET_terms = NULL;
261 
262 extern EntrezInfoPtr LIBCALL EntrezInfoAsnRead PROTO((AsnIoPtr aip, AsnTypePtr atp));
263 EntrezInfoPtr NetEntrezGetInfo PROTO((void));
264 static void RemoveNonPrintingCharacters(CharPtr str);
265 
266 /*extern void MsgSetReadTimeout PROTO((MHandPtr mh, int t));*/
267 
268 
FindAsnType(AsnTypePtr PNTR atp,AsnModulePtr amp,CharPtr str)269 static void NEAR FindAsnType (AsnTypePtr PNTR atp, AsnModulePtr amp, CharPtr str)
270 
271 {
272   if (atp != NULL && (*atp) == NULL) {
273     *atp = AsnTypeFind (amp, str);
274   }
275 }
276 
277 
278 /*****************************************************************************
279 *
280 *   NetEntrezInit ()
281 *
282 *****************************************************************************/
283 
NetEntrezInit(CharPtr appl_id,Boolean no_warnings)284 NLM_EXTERN Boolean CDECL NetEntrezInit (CharPtr appl_id, Boolean no_warnings)
285 
286 {
287     AsnIoPtr   asnin;
288     AsnIoPtr   asnout;
289     AsnTypePtr atp;
290     MediaPtr   media;
291     DataVal    av;
292     CharPtr    versionId;
293     AsnModulePtr amp;
294 
295     NetEntAsnLoad();
296     amp = AsnAllModPtr();
297 
298     FindAsnType(&ENTREZ_BACK, amp, "Entrez-back");
299     FindAsnType(&ENTREZ_BACK_blast_bad_count, amp, "Entrez-back.blast.bad-count");
300     FindAsnType(&ENTREZ_BACK_blast_job_progress, amp, "Entrez-back.blast.job-progress");
301     FindAsnType(&ENTREZ_BACK_blast_job_start, amp, "Entrez-back.blast.job-start");
302     FindAsnType(&ENTREZ_BACK_blast_link_set, amp, "Entrez-back.blast.link-set");
303     FindAsnType(&ENTREZ_BACK_cluster_arts, amp, "Entrez-back.cluster-arts");
304     FindAsnType(&ENTREZ_BACK_docsumX, amp, "Entrez-back.docsumX");
305     FindAsnType(&ENTREZ_BACK_error, amp, "Entrez-back.error");
306     FindAsnType(&ENTREZ_BACK_evalX, amp, "Entrez-back.evalX");
307     FindAsnType(&ENTREZ_BACK_eval_count, amp, "Entrez-back.eval-count");
308     FindAsnType(&ENTREZ_BACK_extrainfo, amp, "Entrez-back.extrainfo");
309     FindAsnType(&ENTREZ_BACK_get_hierarchy, amp, "Entrez-back.get-hierarchy");
310     FindAsnType(&ENTREZ_BACK_init, amp, "Entrez-back.init");
311     FindAsnType(&ENTREZ_BACK_init_e_info, amp, "Entrez-back.init.e-info");
312     FindAsnType(&ENTREZ_BACK_neighbortext, amp, "Entrez-back.neighbortext");
313     FindAsnType(&ENTREZ_REQUEST, amp, "Entrez-request");
314     FindAsnType(&ENTREZ_REQUEST_blast, amp, "Entrez-request.blast");
315     FindAsnType(&ENTREZ_REQUEST_bypage, amp, "Entrez-request.bypage");
316     FindAsnType(&ENTREZ_REQUEST_byterm, amp, "Entrez-request.byterm");
317     FindAsnType(&ENTREZ_REQUEST_cluster_arts, amp, "Entrez-request.cluster-arts");
318     FindAsnType(&ENTREZ_REQUEST_createnamed, amp, "Entrez-request.createnamed");
319     FindAsnType(&ENTREZ_REQUEST_docsumX, amp, "Entrez-request.docsumX");
320     FindAsnType(&ENTREZ_REQUEST_evalX, amp, "Entrez-request.evalX");
321     FindAsnType(&ENTREZ_REQUEST_eval_count, amp, "Entrez-request.eval-count");
322     FindAsnType(&ENTREZ_REQUEST_extrainfo, amp, "Entrez-request.extrainfo");
323     FindAsnType(&ENTREZ_REQUEST_findseqid, amp, "Entrez-request.findseqid");
324     FindAsnType(&ENTREZ_REQUEST_findterm, amp, "Entrez-request.findterm");
325     FindAsnType(&ENTREZ_REQUEST_fini, amp, "Entrez-request.fini");
326     FindAsnType(&ENTREZ_REQUEST_get_hierarchy, amp, "Entrez-request.get-hierarchy");
327     FindAsnType(&ENTREZ_REQUEST_getbiostr, amp, "Entrez-request.getbiostr");
328     FindAsnType(&ENTREZ_REQUEST_getbiostrX, amp, "Entrez-request.getbiostrX");
329     FindAsnType(&REQUEST_getbiostrX_complexity, amp, "Entrez-request.getbiostrX.complexity");
330     FindAsnType(&REQUEST_getbiostrX_max_models, amp, "Entrez-request.getbiostrX.max-models");
331     FindAsnType(&ENTREZ_REQUEST_getbiostrX_get, amp, "Entrez-request.getbiostrX.get");
332     FindAsnType(&ENTREZ_REQUEST_getbiostrannot, amp, "Entrez-request.getbiostrannot");
333     FindAsnType(&REQUEST_getbiostr_feat_ids, amp, "Entrez-request.getbiostr-feat-ids");
334     FindAsnType(&REQUEST_getbiostr_annot_by_fid, amp, "Entrez-request.getbiostr-annot-by-fid");
335     FindAsnType(&ENTREZ_REQUEST_getmle, amp, "Entrez-request.getmle");
336     FindAsnType(&ENTREZ_REQUEST_getseq, amp, "Entrez-request.getseq");
337     FindAsnType(&ENTREZ_REQUEST_initX, amp, "Entrez-request.initX");
338     FindAsnType(&ENTREZ_REQUEST_initX_version, amp, "Entrez-request.initX.version");
339     FindAsnType(&ENTREZ_REQUEST_linkuidlist, amp, "Entrez-request.linkuidlist");
340     FindAsnType(&ENTREZ_REQUEST_neighbortext, amp, "Entrez-request.neighbortext");
341     FindAsnType(&ENTREZ_REQUEST_seqidforgi, amp, "Entrez-request.seqidforgi");
342     FindAsnType(&ENTREZ_REQUEST_uidlinks, amp, "Entrez-request.uidlinks");
343     FindAsnType(&ENTREZ_TERMGET_cls, amp, "Entrez-termget.cls");
344     FindAsnType(&ENTREZ_TERMGET_terms, amp, "Entrez-termget.terms");
345 
346     if (! NetEInit())
347         return FALSE;
348 
349     userWarnings = no_warnings;
350 
351     Entrez_ni = NetServiceGet("ENTR_LINK", "Entrez", SwapInEntrez, Entrez_ni);
352     if (Entrez_ni == NULL)
353     {
354     	serviceAttempts++;
355         ErrPostEx (SEV_ERROR, 0, 0, "NI_ServiceGet [%s] (%s) <%ld>",
356         	ni_errlist[ni_errno], ni_errtext, (long) serviceAttempts);
357         Entrez_asnin = NULL;
358         Entrez_asnout = NULL;
359         NetEntrezFini();
360         return FALSE;
361     }
362 
363     asnin = Entrez_ni->raip;
364     asnout = Entrez_ni->waip;
365 
366     Entrez_asnin = asnin;
367     Entrez_asnout = asnout;
368 
369     /* don't get upset if non-printing chars are encountered */
370     asnin->fix_non_print = 1;
371 
372     /**********************************************************/
373 
374     AsnWrite(asnout, ENTREZ_REQUEST, NULL);
375     AsnStartStruct(asnout, ENTREZ_REQUEST_initX);
376     if (netEntrezVersion != NULL) {
377         if (appl_id == NULL) {
378             av.ptrvalue = netEntrezVersion;
379             AsnWrite(asnout, ENTREZ_REQUEST_initX_version, &av);
380         } else {
381             versionId = MemNew(StrLen(netEntrezVersion) + StrLen(appl_id) + 4);
382             sprintf (versionId, "%s (%s)", netEntrezVersion, appl_id);
383             userApplId = StringSave(appl_id);
384             av.ptrvalue = versionId;
385             AsnWrite(asnout, ENTREZ_REQUEST_initX_version, &av);
386             MemFree (versionId);
387         }
388     }
389     AsnEndStruct(asnout, ENTREZ_REQUEST_initX);
390     AsnIoReset(asnout);
391 
392 
393     if ((atp = NetEntReadAsn()) == NULL)
394     {
395         return FALSE;
396     }
397     else
398     {
399         AsnReadVal(asnin, atp, NULL);   /* read the NULL */
400         atp = AsnReadId(asnin, amp, atp);
401         if (atp == ENTREZ_BACK_init_e_info)
402         {
403             if (vi != NULL)
404             {
405                 EntrezInfoFree (vi);
406                 vi = NULL;
407             }
408             vi = EntrezInfoAsnRead(asnin, atp);
409             if ((media = GetCurMedia()) != NULL &&
410                 media->media_type == MEDIUM_NETWORK)
411             {
412                 media->entrez_info = vi;
413             }
414             atp = AsnReadId(asnin, amp, atp);
415         }
416         if (atp != ENTREZ_BACK_init)
417             return FALSE;
418         AsnReadVal(asnin, atp, NULL);   /* read the NULL */
419         ConfigInit();
420         return  TRUE;
421     }
422 }
423 
424 /*****************************************************************************
425 *
426 *   NetEntrezFini ()
427 *
428 *****************************************************************************/
429 
s_NetEntrezFini(void)430 static void NEAR s_NetEntrezFini (void)
431 
432 {
433     AsnTypePtr atp;
434     AsnIoPtr asnout = Entrez_asnout;
435     AsnIoPtr asnin = Entrez_asnin;
436 
437     if (asnout != NULL && asnin != NULL)
438     {
439         AsnWrite(asnout, ENTREZ_REQUEST, NULL);
440         AsnWrite(asnout, ENTREZ_REQUEST_fini, NULL);
441         AsnIoReset(asnout);
442 
443         if ((atp = NetEntReadAsn()) != NULL)
444             AsnReadVal(asnin, atp, NULL);   /* read the NULL */
445     }
446 
447     if (infoBuf != NULL)
448     {
449         MemFree(infoBuf);
450         infoBuf = NULL;
451     }
452 
453     if (userApplId != NULL)
454     {
455         MemFree(userApplId);
456         userApplId = NULL;
457     }
458     if (eeip != NULL)
459     {
460         EntrezExtraInfoFree(eeip);
461         eeip = NULL;
462     }
463 
464     NI_ServiceDisconnect(Entrez_ni);
465     NetFini();
466     ConfigFini();
467 }
468 
469 /* the only thing done here is to suppress errors */
NetEntrezFini(void)470 NLM_EXTERN void CDECL NetEntrezFini (void)
471 
472 {
473     short erract;
474     ErrDesc err;
475 
476     ErrGetOpts(&erract, NULL);
477     ErrSetOpts(ERR_CONTINUE, 0);
478     ErrFetch(&err);
479 
480     s_NetEntrezFini();
481 
482     ErrSetOpts(erract, 0);
483     ErrFetch(&err);
484 
485     CleanupNamedUidLists ();
486 }
487 
488 /*****************************************************************************
489 *
490 *   NetEntrezGetInfo()
491 *       returns global Entrez information
492 *
493 *****************************************************************************/
494 NLM_EXTERN EntrezInfoPtr CDECL
NetEntrezGetInfo(void)495 NetEntrezGetInfo(void)
496 {
497     return vi;
498 }
499 
500 /*****************************************************************************
501 *
502 *   NetEntrezDetailedInfo()
503 *       returns NULL, or a string to some descriptive text
504 *
505 *****************************************************************************/
506 NLM_EXTERN CharPtr CDECL
NetEntrezDetailedInfo(void)507 NetEntrezDetailedInfo(void)
508 {
509     charCount = 0;
510     DumpNetStats(SUBSYS_CLI_ENTREZ, countChars);
511 
512     if (infoBuf != NULL)
513         MemFree(infoBuf);
514     infoBuf = MemNew(charCount + 540);
515     GetClientInfo(infoBuf);
516     return infoBuf;
517 }
518 
519 static EntrezExtraInfoPtr
GetEntrezExtraInfo(void)520 GetEntrezExtraInfo(void)
521 {
522     AsnTypePtr atp;
523     DataVal av;
524 
525     if (eeip == NULL && Entrez_asnout != NULL)
526     {
527         AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
528         av.intvalue = 4; /* number of currently known fields */
529         AsnWrite(Entrez_asnout, ENTREZ_REQUEST_extrainfo, &av);
530         AsnIoReset(Entrez_asnout);
531         if ((atp = NetEntReadAsn()) != NULL)
532             eeip = EntrezExtraInfoAsnRead(Entrez_asnin, ENTREZ_BACK_extrainfo);
533     }
534 
535     return eeip;
536 }
537 
538 /*****************************************************************************
539 *
540 *   NetEntGetMaxLinks()
541 *       returns max links in link set allowed by system
542 *
543 *****************************************************************************/
544 
NetEntGetMaxLinks(void)545 NLM_EXTERN Int4 NetEntGetMaxLinks(void)
546 {
547     EntrezExtraInfoPtr myeeip;
548 
549     if ((myeeip = GetEntrezExtraInfo()) == NULL)
550     {
551         return -1;
552     }
553 
554     return myeeip->maxlinks;
555 }
556 
557 /*****************************************************************************
558 *
559 *   NetEntTLNew ()
560 *
561 *****************************************************************************/
562 
NetEntTLNew(DocType type)563 NLM_EXTERN ValNodePtr CDECL NetEntTLNew (DocType type)
564 
565 {
566   ValNodePtr anp;
567 
568   anp = ValNodeNew(NULL);
569   anp->data.intvalue = (Int4)type;
570   return anp;
571 }
572 
573 /*****************************************************************************
574 *
575 *   NetEntTLAddTerm (elst, term, type, field, special)
576 *       Adds a term node to a boolean algebraic term query.
577 *
578 *****************************************************************************/
579 
NetEntTLAddTerm(ValNodePtr elst,CharPtr term,DocType type,DocField field,Boolean special,CharPtr highRange)580 NLM_EXTERN ValNodePtr CDECL NetEntTLAddTerm(ValNodePtr elst, CharPtr term, DocType type,
581                                   DocField field, Boolean special, CharPtr highRange)
582 
583 {
584     ValNodePtr anp;
585     TermDataPtr termdatp;
586     NamedListPtr nlp;
587 
588     anp = NULL;
589     if (elst != NULL) {
590         if (elst->data.intvalue != (Int4)type)
591             return NULL;
592         anp = ValNodeNew (elst);
593         if (anp != NULL) {
594             if ((nlp = KnownNamedTerm(term, TRUE, type, field)) != NULL &&
595                 nlp->uids != NULL) {
596                 NetEntrezCreateNamedUidList (term, type, field, nlp->uids->numid,
597                                              nlp->uids->ids);
598             }
599 
600             if (special) {
601                 anp->choice = SPECIALTERM;
602             } else {
603                 anp->choice = TOTALTERM;
604             }
605 
606             termdatp = (TermDataPtr) MemNew(sizeof(TermData));
607             termdatp->field = field;
608             termdatp->type = type;
609             termdatp->term = StringSave(term);
610             termdatp->highRange = StringSave(highRange);
611             anp->data.ptrvalue = (Pointer) termdatp;
612         }
613     }
614     LOG_STAT(SUBSYS_CLI_ENTREZ, "Boolean terms", 1);
615     return anp;
616 }
617 
618 /*****************************************************************************
619 *
620 *   NetEntTLFree (elst)
621 *       Frees a boolean algebraic term query list.
622 *
623 *****************************************************************************/
624 
NetEntTLFree(ValNodePtr elst)625 NLM_EXTERN ValNodePtr CDECL NetEntTLFree (ValNodePtr elst)
626 
627 {
628     ValNodePtr anp;
629     TermDataPtr trmp;
630 
631     if (elst != NULL) {
632         elst->data.intvalue = 0;   /* clear type */
633         for (anp = elst->next; anp != NULL; anp = anp->next) {
634             if (anp->choice == SPECIALTERM || anp->choice == TOTALTERM) {
635                 trmp = (TermDataPtr) anp->data.ptrvalue;
636                 MemFree (trmp->term);
637                 trmp->term = NULL;
638                 MemFree (trmp->highRange);
639                 trmp->highRange = NULL;
640             }
641         }
642         ValNodeFreeData (elst);
643     }
644     return NULL;
645 }
646 
647 /*****************************************************************************
648 *
649 *   NetEntTLEval (elst)
650 *       Evaluates a boolean algebraic term query list, returning a pointer to
651 *       a LinkSetPtr containing the resultant unique identifiers.
652 *
653 *****************************************************************************/
654 
655 
NetEntTLEval(ValNodePtr elst)656 NLM_EXTERN LinkSetPtr CDECL NetEntTLEval (ValNodePtr elst)
657 
658 {
659     ByteStorePtr bsp;
660     LinkSetPtr lsp;
661     Int4 numlinks;
662 
663     if ((bsp = NetEntTLEvalX(elst)) != NULL)
664     {
665         numlinks = BSLen(bsp) / sizeof(DocUid);
666         lsp = LinkSetNew();
667         lsp->num = numlinks;
668         if (numlinks <= EntrezGetUserMaxLinks())
669         {
670                 lsp->uids = MemNew((size_t)(numlinks * sizeof(DocUid)));                        BSSeek (bsp, 0L, 0);
671                 BSRead(bsp, lsp->uids, (numlinks * sizeof(DocUid)));
672         }
673         BSFree(bsp);
674     }
675     return lsp;
676 
677 }
678 
679 
680 
681 
682 /*****************************************************************************
683 *
684 *   NetEntTLEvalX (elst)
685 *       Evaluates a boolean algebraic term query list, returning a pointer to
686 *       a ByteStore containing the resultant unique identifiers.
687 *
688 *****************************************************************************/
689 
s_NetEntTLEvalX(ValNodePtr elst)690 static ByteStorePtr NEAR s_NetEntTLEvalX (ValNodePtr elst)
691 
692 {
693     ByteStorePtr bsp = NULL;
694     AsnTypePtr atp;
695     DataVal av;
696 
697     if (elst == NULL)
698         return NULL;
699     if (elst->next == NULL) /* expression without terms */
700         return NULL;
701     AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
702     AsnStartStruct(Entrez_asnout, ENTREZ_REQUEST_evalX);
703     av.intvalue = elst->data.intvalue;
704     AsnWrite(Entrez_asnout, ENTREZ_TERMGET_cls, &av);
705     BoolExprAsnWrite (elst->next, Entrez_asnout, ENTREZ_TERMGET_terms);
706     AsnEndStruct(Entrez_asnout, ENTREZ_REQUEST_evalX);
707     AsnIoReset(Entrez_asnout);
708 
709     if ((atp = NetEntReadAsn()) == NULL)
710         return NULL;
711 
712     if (atp == ENTREZ_BACK_evalX)
713     {
714         AsnReadVal(Entrez_asnin, atp, &av);
715         bsp = (ByteStorePtr) av.ptrvalue;
716 #ifdef IS_LITTLE_ENDIAN
717         {
718             Int4 datum;
719             Int4 offset;
720             Int4 i;
721 
722             for (i = BSLen(bsp) / sizeof(Int4), offset = 0; i > 0;
723                  i--, offset += sizeof(Int4))
724             {
725                 BSSeek(bsp, offset, SEEK_SET);
726                 BSRead(bsp, &datum, sizeof(Int4));
727                 datum = SwapUint4(datum);
728                 BSSeek(bsp, offset, SEEK_SET);
729                 BSWrite(bsp, &datum, sizeof(Int4));
730             }
731         }
732 #endif /* IS_LITTLE_ENDIAN */
733     }
734     LOG_STAT(SUBSYS_CLI_ENTREZ, "Boolean expressions evaluated", 1);
735     LOG_STAT(SUBSYS_CLI_ENTREZ, "Resulting UIDs from Boolean evaluation", bsp == NULL ? 0 : BSLen(bsp) / sizeof(DocUid));
736     return bsp;
737 }
738 
NetEntTLEvalX(ValNodePtr elst)739 NLM_EXTERN ByteStorePtr CDECL NetEntTLEvalX (ValNodePtr elst)
740 
741 {
742     int i;
743     ByteStorePtr retval;
744     short erract;
745     ErrDesc err;
746 
747     for (i = 0; i < ENT_SERV_RETRIES; i++)
748     {
749         if (i > 0)
750         {
751             if (! ReestablishNetEntrez())
752                 break;
753         }
754 
755         ErrGetOpts(&erract, NULL);
756         ErrSetOpts(ERR_CONTINUE, 0);
757         ErrFetch(&err);
758         /*MsgSetReadTimeout(Entrez_ni, 1200);*/
759         retval = s_NetEntTLEvalX(elst);
760         /*MsgSetReadTimeout(Entrez_ni, 60);*/
761         ErrSetOpts(erract, 0);
762         if (! ErrFetch(&err))
763             return retval; /* success */
764     }
765 
766     ErrPost(CTX_UNKNOWN, 1, "NetEntTLEval failure");
767     return NULL;
768 }
769 
770 /*****************************************************************************
771 *
772 *   NetEntTLEvalCount (elst)
773 *       Evaluates a boolean algebraic term query list, returning a count of
774 *       the resultant unique identifiers.
775 *
776 *****************************************************************************/
777 
s_NetEntTLEvalCount(ValNodePtr elst)778 static Int4 NEAR s_NetEntTLEvalCount (ValNodePtr elst)
779 
780 {
781     Int4 retval = 0;
782     AsnTypePtr atp;
783     DataVal av;
784 
785     if (elst->next == NULL) /* expression without terms */
786         return 0;
787     AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
788     AsnStartStruct(Entrez_asnout, ENTREZ_REQUEST_eval_count);
789     av.intvalue = elst->data.intvalue;
790     AsnWrite(Entrez_asnout, ENTREZ_TERMGET_cls, &av);
791     BoolExprAsnWrite (elst->next, Entrez_asnout, ENTREZ_TERMGET_terms);
792     AsnEndStruct(Entrez_asnout, ENTREZ_REQUEST_eval_count);
793     AsnIoReset(Entrez_asnout);
794 
795     /*MsgSetReadTimeout(Entrez_ni, 1200);*.
796     if ((atp = NetEntReadAsn()) == NULL)
797         return 0;
798     /*MsgSetReadTimeout(Entrez_ni, 60);*/
799 
800     if (atp == ENTREZ_BACK_eval_count)
801     {
802         AsnReadVal(Entrez_asnin, atp, &av);
803         retval = (Int4) av.intvalue;
804     }
805     LOG_STAT(SUBSYS_CLI_ENTREZ, "Boolean expressions counted", 1);
806     LOG_STAT(SUBSYS_CLI_ENTREZ, "Resulting UIDs from Boolean count-evaluation", retval);
807     return retval;
808 }
809 
NetEntTLEvalCount(ValNodePtr elst)810 NLM_EXTERN Int4 CDECL NetEntTLEvalCount (ValNodePtr elst)
811 
812 {
813     int i;
814     Int4 retval;
815     short erract;
816     ErrDesc err;
817 
818     for (i = 0; i < ENT_SERV_RETRIES; i++)
819     {
820         if (i > 0)
821         {
822             if (! ReestablishNetEntrez())
823                 break;
824         }
825 
826         ErrGetOpts(&erract, NULL);
827         ErrSetOpts(ERR_CONTINUE, 0);
828         ErrFetch(&err);
829         retval = s_NetEntTLEvalCount(elst);
830         ErrSetOpts(erract, 0);
831         if (! ErrFetch(&err))
832             return retval; /* success */
833     }
834 
835     ErrPost(CTX_UNKNOWN, 1, "NetEntTLEvalCount failure");
836     return 0;
837 }
838 
839 
840 /*****************************************************************************
841 *
842 *   NetDocSumListGet (result, numuid, type, uids)
843 *       returns a count of entries read
844 *       head of linked list is in result
845 *
846 *****************************************************************************/
s_NetDocSumListGet(DocSumPtr PNTR result,Int2 numuid,DocType type,DocUidPtr uids,Int2 defer_count)847 static Int2 NEAR s_NetDocSumListGet (DocSumPtr PNTR result, Int2 numuid,
848                                       DocType type, DocUidPtr uids,
849                                       Int2 defer_count)
850 
851 {
852     AsnTypePtr atp;
853     EntrezIdsPtr eip;
854     Int2 retval;
855     EntrezDocGetPtr edgp;
856     AsnModulePtr amp;
857     NewSummaryListPtr newlist;
858 
859     NetEntAsnLoad();
860     amp = AsnAllModPtr();
861 
862     AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
863     edgp = EntrezDocGetNew();
864     edgp->ids = EntrezIdsNew();
865     eip = edgp->ids;
866     edgp->cls = type;
867     edgp->mark_missing = FALSE;
868     eip->numid = numuid;
869     eip->ids = uids;
870     edgp->defer_count = defer_count;
871     EntrezDocGetAsnWrite(edgp, Entrez_asnout, ENTREZ_REQUEST_docsumX);
872     eip->ids = NULL; /* for clean memory free */
873     EntrezDocGetFree(edgp);
874 
875     AsnIoReset(Entrez_asnout);
876 
877     if ((atp = NetEntReadAsn()) == NULL)
878         return -1;
879 
880     newlist = NewSummaryListAsnRead(Entrez_asnin, atp);
881     if (newlist == NULL)
882         return -1;
883     if (newlist->type != type)
884     {
885         NewSummaryListFree(newlist);
886         return -1;
887     }
888     MemCopy (result, newlist->data, (size_t) newlist->num * sizeof(DocSumPtr));
889     retval = newlist->num;
890     MemFree(newlist->data);
891     newlist->data = NULL; /* to avoid freeing actual DocSums */
892     NewSummaryListFree (newlist);
893 
894     LOG_STAT(SUBSYS_CLI_ENTREZ, "Document summaries retrieved", retval);
895     LOG_STAT(SUBSYS_CLI_ENTREZ, "Document summaries requested", numuid);
896 
897     return retval;
898 }
899 
NetDocSumListGet(DocSumPtr PNTR result,Int2 numuid,DocType type,DocUidPtr uids,Int2 defer_count)900 NLM_EXTERN Int2 CDECL NetDocSumListGet (DocSumPtr PNTR result, Int2 numuid,
901                           DocType type, DocUidPtr uids, Int2 defer_count)
902 {
903     int i;
904     int retval;
905     short erract;
906     ErrDesc err;
907 
908     /* default is to obtain these from the Entrez server */
909 
910     for (i = 0; i < ENT_SERV_RETRIES; i++)
911     {
912         if (i > 0)
913         {
914             if (! ReestablishNetEntrez())
915                 break;
916         }
917 
918         ErrGetOpts(&erract, NULL);
919         ErrSetOpts(ERR_CONTINUE, 0);
920         ErrFetch(&err);
921         retval = s_NetDocSumListGet (result, numuid, type, uids, defer_count);
922         ErrSetOpts(erract, 0);
923         if (! ErrFetch(&err))
924         {
925             goto expand_uids;
926         }
927     }
928 
929     ErrPost(CTX_UNKNOWN, 1, "DocSumGet failure");
930     return -1;
931 
932 expand_uids:
933     if (retval < 0 || retval == numuid)
934         return retval;
935 
936     {
937         Int2 i,j;
938         DocSumPtr dsp;
939 #define USE_TEMP_MEMORY
940 #ifdef USE_TEMP_MEMORY
941         DocSumPtr PNTR temp;
942 
943         /* some UIDs are missing; we must find which ones and insert NULLs */
944         if ((temp = MemNew(sizeof(DocSumPtr) * numuid)) == NULL)
945         {
946             ErrPost(CTX_UNKNOWN, 1, "DocSumGet failure <memory allocation>");
947             return -1;
948         }
949 
950         for (i = 0; i < numuid; i++)
951         {
952             temp[i] = result[i];
953             result[i] = NULL;
954         }
955 
956         for (i = 0, j = 0; i < retval; i++) {
957             dsp = temp[i];
958             if (dsp != NULL) {
959                 while (j < numuid && dsp->uid != uids[j]) {
960                     j++;
961                 }
962                 if (j < numuid) {
963                     result[j] = dsp;
964                     j++;
965                 }
966             }
967         }
968 
969         MemFree (temp);
970 #else
971         /* more dangerous algorithm ... operates on result in-place */
972         for (i = retval - 1, j = numuid - 1; i >= 0; i--) {
973             dsp = result[i];
974             if (dsp != NULL) {
975                 while (j >= 0 && dsp->uid != uids[j]) {
976                     result[j] = NULL;
977                     j--;
978                 }
979                 if (j >= 0)
980                 {
981                     result[j] = dsp;
982                     j--;
983                 }
984             }
985         }
986 
987         for (; j >= 0; j--)
988         { /* null out any unassigned bottom entries */
989             result[j] = NULL;
990         }
991 #endif /* USE_TEMP_MEMORY */
992 
993         return retval;
994     }
995 }
996 
997 
998 /*****************************************************************************
999 *
1000 *   DocSumPtr NetDocSum(type, uid)
1001 *
1002 *****************************************************************************/
1003 
NetDocSum(DocType type,DocUid uid)1004 NLM_EXTERN DocSumPtr CDECL NetDocSum (DocType type, DocUid uid)
1005 {
1006     DocSumPtr dsp = NULL;
1007 
1008     NetDocSumListGet(&dsp, 1, type, &uid, 0);
1009     return dsp;
1010 }
1011 
1012 /*****************************************************************************
1013 *
1014 *   NetLinkUidList(type, link_to_type, numuid, uids)
1015 *       returns count of input uids processed
1016 *       returns -1 on error
1017 *       if neighbors (type == link_to_type)
1018 *           sums weights for same uids
1019 *       if (more than EntrezUserMaxLinks() uids, frees uids and weights,
1020 *           but leaves num set)
1021 *
1022 *****************************************************************************/
1023 static
s_NetLinkUidList(LinkSetPtr PNTR result,DocType type,DocType link_to_type,Int2 numuid,DocUidPtr uids,Boolean mark_missing)1024 Int2 NEAR s_NetLinkUidList (LinkSetPtr PNTR result, DocType type,
1025                               DocType   link_to_type, Int2 numuid, DocUidPtr uids,
1026                               Boolean mark_missing)
1027 
1028 {
1029     LinkSetGetPtr lsgp;
1030     MarkedLinkSetPtr mls;
1031     AsnTypePtr atp;
1032     Int2 retval;
1033 
1034     lsgp = LinkSetGetNew();
1035     lsgp->query_cls = type;
1036     lsgp->link_to_cls = link_to_type;
1037     lsgp->max = EntrezGetUserMaxLinks();
1038     lsgp->mark_missing = mark_missing;
1039     lsgp->query_size = numuid;
1040     lsgp->query = MemNew(sizeof(DocUid) * numuid);
1041 
1042     MemCopy (lsgp->query, uids, sizeof(DocUid) * numuid);
1043     AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
1044     LinkSetGetAsnWrite(lsgp, Entrez_asnout, ENTREZ_REQUEST_linkuidlist);
1045     AsnIoReset(Entrez_asnout);
1046 
1047     LinkSetGetFree (lsgp);
1048 
1049     if ((atp = NetEntReadAsn()) == NULL)
1050         return -1;
1051     if ((mls = MarkedLinkSetAsnRead(Entrez_asnin, atp)) == NULL)
1052         return -1;
1053     *result = mls->link_set;
1054     retval = mls->uids_processed;
1055     if (mark_missing && mls->marked_missing != NULL)
1056         MemCopy (uids, mls->marked_missing->ids, numuid * sizeof(DocUid));
1057     mls->link_set = NULL; /* for clean memory free */
1058     MarkedLinkSetFree (mls);
1059 
1060     LOG_STAT(SUBSYS_CLI_ENTREZ, "UID attempted for neighbors", numuid);
1061     LOG_STAT(SUBSYS_CLI_ENTREZ, "UID processed for neighbors", retval);
1062     LOG_STAT(SUBSYS_CLI_ENTREZ, "UID neighbors found", *result == NULL ? 0 : (*result)->num);
1063     return retval;
1064 }
1065 
NetLinkUidList(LinkSetPtr PNTR result,DocType type,DocType link_to_type,Int2 numuid,DocUidPtr uids,Boolean mark_missing)1066 NLM_EXTERN Int2 CDECL NetLinkUidList (LinkSetPtr PNTR result, DocType type,
1067                             DocType link_to_type, Int2 numuid, DocUidPtr uids,
1068                             Boolean mark_missing)
1069 {
1070     int i;
1071     int retval;
1072     short erract;
1073     ErrDesc err;
1074     DocUidPtr local_uids;
1075 
1076     /* make a local copy, to handle modifications */
1077     local_uids = MemNew(sizeof(DocUid) * numuid);
1078 
1079     for (i = 0; i < ENT_SERV_RETRIES; i++)
1080     {
1081         MemCopy(local_uids, uids, sizeof(DocUid) * numuid);
1082         if (i > 0)
1083         {
1084             if (! ReestablishNetEntrez())
1085                 break;
1086         }
1087 
1088         ErrGetOpts(&erract, NULL);
1089         ErrSetOpts(ERR_CONTINUE, 0);
1090         ErrFetch(&err);
1091         retval = s_NetLinkUidList(result, type, link_to_type, numuid,
1092                       local_uids, mark_missing);
1093         ErrSetOpts(erract, 0);
1094         if (! ErrFetch(&err))
1095         {
1096             MemCopy(uids, local_uids, sizeof(DocUid) * numuid);
1097             MemFree(local_uids);
1098             return retval; /* success */
1099         }
1100     }
1101 
1102     MemFree(local_uids);
1103     ErrPost(CTX_UNKNOWN, 1, "NetLinkUidList failure");
1104     return -1;
1105 }
1106 
1107 /*****************************************************************************
1108 *
1109 *   NetUidLinks()
1110 *       retrieves links to other uids
1111 *
1112 *****************************************************************************/
1113 static
s_NetUidLinks(DocType type,DocUid uid,DocType link_to_type)1114 LinkSetPtr NEAR s_NetUidLinks(DocType type, DocUid uid, DocType link_to_type)
1115 
1116 {
1117     LinkSetPtr lsp;
1118     LinkSetGetPtr lsgp;
1119     MarkedLinkSetPtr mls;
1120     AsnTypePtr atp;
1121 
1122     lsgp = LinkSetGetNew();
1123     lsgp->query_cls = type;
1124     lsgp->link_to_cls = link_to_type;
1125     lsgp->max = EntrezGetUserMaxLinks();
1126     lsgp->mark_missing = FALSE;
1127     lsgp->query_size = 1;
1128     lsgp->query = MemNew(sizeof(DocUid));
1129     lsgp->query[0] = uid;
1130 
1131     AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
1132     LinkSetGetAsnWrite(lsgp, Entrez_asnout, ENTREZ_REQUEST_uidlinks);
1133     AsnIoReset(Entrez_asnout);
1134 
1135     LinkSetGetFree (lsgp);
1136 
1137     if ((atp = NetEntReadAsn()) == NULL)
1138         return NULL;
1139     if ((mls = MarkedLinkSetAsnRead(Entrez_asnin, atp)) == NULL)
1140         return NULL;
1141     lsp = mls->link_set;
1142     mls->link_set = NULL; /* for clean memory free */
1143     MarkedLinkSetFree (mls);
1144 
1145     return lsp;
1146 }
1147 
NetUidLinks(DocType type,DocUid uid,DocType link_to_type)1148 NLM_EXTERN LinkSetPtr CDECL NetUidLinks(DocType type, DocUid uid, DocType link_to_type)
1149 {
1150     int i;
1151     LinkSetPtr retval;
1152     short erract;
1153     ErrDesc err;
1154 
1155     for (i = 0; i < ENT_SERV_RETRIES; i++)
1156     {
1157         if (i > 0)
1158         {
1159             if (! ReestablishNetEntrez())
1160                 break;
1161         }
1162 
1163         ErrGetOpts(&erract, NULL);
1164         ErrSetOpts(ERR_CONTINUE, 0);
1165         ErrFetch(&err);
1166         retval = s_NetUidLinks(type, uid, link_to_type);
1167         ErrSetOpts(erract, 0);
1168         if (! ErrFetch(&err))
1169             return retval; /* success */
1170     }
1171 
1172     ErrPost(CTX_UNKNOWN, 1, "NetUidLinks failure");
1173     return NULL;
1174 }
1175 
1176 
1177 /* The number of pages or terms to be obtain from the network in one request */
1178 #define NUM_NET_PAGES       4
1179 #define NUM_NET_TERMS       50
1180 
1181 /* The maximum number of terms to obtain in one TermListByTerm; this value   */
1182 /* need not depend upon NUM_NET_TERMS                                        */
1183 #define OBTAIN_IN_ONE_READ 100
1184 
1185 /*****************************************************************************
1186 *
1187 *   NetTermListByTerm (type, field, term, numterms, proc, first_page)
1188 *       Gets Terms starting with page near term
1189 *       returns number of complete pages read
1190 *       sets first_page to first page read
1191 *
1192 *****************************************************************************/
1193 static
s_NetTermListByTerm(DocType type,DocField field,CharPtr term,Int2 numterms,TermListProc proc,Int2Ptr first_page)1194 Int2 NEAR s_NetTermListByTerm (DocType type, DocField field, CharPtr term,
1195                                  Int2 numterms, TermListProc proc,
1196                                  Int2Ptr first_page)
1197 
1198 {
1199     AsnIoPtr asnin = Entrez_asnin;
1200     AsnIoPtr asnout = Entrez_asnout;
1201     int i;
1202     TermRespPtr p;
1203     TermByTermPtr tbt;
1204     TermByPagePtr tbp;
1205     AsnTypePtr atp;
1206     struct termresp PNTR termp;
1207     int retval = 0;
1208     int first_read = TRUE;
1209     Boolean done = FALSE;
1210     int next_page;
1211     Int4 max_terms;
1212     int terms_to_read;
1213 
1214     if (numterms == 0) /* 0 ==> infinity */
1215         max_terms = INT4_MAX;
1216     else
1217         max_terms = numterms;
1218 
1219     while (! done) {
1220         terms_to_read = MIN(max_terms, NUM_NET_TERMS);
1221         if (first_read)
1222         {
1223             tbt = TermByTermNew();
1224 
1225             AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
1226             tbt->type = type;
1227             tbt->fld = field;
1228             tbt->term = StringSave(term);
1229 
1230             /* For efficiency, if the caller has only requested a few terms, */
1231             /* then obtain them all in one shot; also note that if we're not */
1232             /* going to obtain all of the requested terms in a single shot,  */
1233             /* then num_terms must be 0, because we need to read an integral */
1234             /* number of pages.                                              */
1235             if (max_terms <= OBTAIN_IN_ONE_READ)
1236                 tbt->num_terms = max_terms;
1237             else
1238                 tbt->num_terms = 0; /* bounded by # of pages, not terms */
1239 
1240             TermByTermAsnWrite(tbt, Entrez_asnout, ENTREZ_REQUEST_byterm);
1241             TermByTermFree (tbt);
1242         }
1243         else { /* we already know what page */
1244             tbp = TermByPageNew();
1245 
1246             AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
1247             tbp->type = type;
1248             tbp->fld = field;
1249             tbp->page = next_page;
1250             tbp->num_pages = NUM_NET_PAGES;
1251             TermByPageAsnWrite(tbp, Entrez_asnout, ENTREZ_REQUEST_bypage);
1252             TermByPageFree (tbp);
1253         }
1254 
1255         AsnIoReset(Entrez_asnout);
1256 
1257         /* now, read back response */
1258         if ((atp = NetEntReadAsn()) == NULL)
1259             return -1;
1260         if ((p = TermRespAsnRead(asnin, atp)) == NULL)
1261             return -1;
1262 
1263         if (first_read)
1264         {
1265             *first_page = p->first_page;
1266             next_page = p->first_page;
1267             first_read = FALSE;
1268         }
1269 
1270         if (p->num_terms == 0) /* end of file */
1271             done = TRUE;
1272 
1273         termp = p->termresp;
1274 
1275         LOG_STAT(SUBSYS_CLI_ENTREZ, "Terms read (by term)", p->num_terms);
1276         for (i = 0; i < p->num_terms && !done; i++, termp++)
1277         {
1278             /* StringSave() is needed because application frees the term */
1279             if (! proc(termp->term, termp->special_count, termp->total_count) )
1280                 done = TRUE;
1281             termp->term = NULL;
1282         }
1283 
1284         retval += p->num_pages_read;
1285         max_terms -= p->num_terms;
1286         next_page += p->num_pages_read;
1287 
1288         TermRespFree (p);
1289 
1290         if (max_terms <= 0)
1291             done = TRUE;
1292     }
1293 
1294     LOG_STAT(SUBSYS_CLI_ENTREZ, "Term pages read (by term)", retval);
1295     return retval; /* page count */
1296 }
1297 
NetTermListByTerm(DocType type,DocField field,CharPtr term,Int2 numterms,TermListProc proc,Int2Ptr first_page)1298 NLM_EXTERN Int2 CDECL NetTermListByTerm (DocType type, DocField field, CharPtr term,
1299                                Int2 numterms, TermListProc proc,
1300                                Int2Ptr first_page)
1301 {
1302     int i;
1303     int retval;
1304     short erract;
1305     ErrDesc err;
1306 
1307     for (i = 0; i < ENT_SERV_RETRIES; i++)
1308     {
1309         if (i > 0)
1310         {
1311             if (! ReestablishNetEntrez())
1312                 break;
1313         }
1314 
1315         ErrGetOpts(&erract, NULL);
1316         ErrSetOpts(ERR_CONTINUE, 0);
1317         ErrFetch(&err);
1318         retval = s_NetTermListByTerm (type, field, term, numterms,
1319                                       proc, first_page);
1320         ErrSetOpts(erract, 0);
1321         if (! ErrFetch(&err))
1322             return retval; /* success */
1323     }
1324 
1325     ErrPost(CTX_UNKNOWN, 1, "NetTermListByTerm failure");
1326     return 0;
1327 }
1328 
1329 /*****************************************************************************
1330 *
1331 *   NetTermListByPage (type, field, page, numpage, proc)
1332 *       Gets terms starting at page, for numpage, by calling proc
1333 *       returns number of complete pages read
1334 *
1335 *****************************************************************************/
1336 
1337 static
s_NetTermListByPage(DocType type,DocField field,Int2 page,Int2 numpage,TermListProc proc)1338 Int2 NEAR s_NetTermListByPage (DocType type, DocField field, Int2 page,
1339                                  Int2 numpage, TermListProc proc)
1340 
1341 {
1342     AsnIoPtr asnin = Entrez_asnin;
1343     AsnIoPtr asnout = Entrez_asnout;
1344     TermRespPtr p;
1345     int i;
1346     struct termresp PNTR termp;
1347     TermByPagePtr tbp;
1348     AsnTypePtr atp;
1349     Boolean done = FALSE;
1350     int retval = 0;
1351     int next_page = page;
1352     int pages_to_read;
1353     Int4 max_pages;
1354 
1355     if (numpage == 0) /* 0 ==> infinity */
1356         max_pages = INT4_MAX;
1357     else
1358         max_pages = numpage;
1359 
1360     while (! done) {
1361         pages_to_read = MIN(max_pages, NUM_NET_PAGES);
1362         tbp = TermByPageNew();
1363 
1364         AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
1365         tbp->type = type;
1366         tbp->fld = field;
1367         tbp->page = next_page;
1368         tbp->num_pages = pages_to_read;
1369         TermByPageAsnWrite(tbp, Entrez_asnout, ENTREZ_REQUEST_bypage);
1370         TermByPageFree(tbp);
1371         AsnIoReset(Entrez_asnout);
1372 
1373         /* now, read back response */
1374         if ((atp = NetEntReadAsn()) == NULL)
1375             return -1;
1376         if ((p = TermRespAsnRead(asnin, atp)) == NULL)
1377             return -1;
1378 
1379         if (p->num_terms == 0) /* end of file */
1380             done = TRUE;
1381 
1382         termp = p->termresp;
1383 
1384         LOG_STAT(SUBSYS_CLI_ENTREZ, "Terms read (by page)", p->num_terms);
1385         for (i = 0; i < p->num_terms && !done; i++, termp++)
1386         {
1387             /* StringSave() is needed because application frees the term */
1388             if (! proc(termp->term, termp->special_count, termp->total_count) )
1389                 done = TRUE;
1390             termp->term = NULL;
1391         }
1392 
1393         retval += p->num_pages_read;
1394         TermRespFree (p);
1395 
1396         next_page += pages_to_read;
1397         max_pages -= pages_to_read;
1398 
1399         if (max_pages <= 0)
1400             done = TRUE;
1401     }
1402     LOG_STAT(SUBSYS_CLI_ENTREZ, "Term pages read (by page)", retval);
1403     return retval; /* page count */
1404 }
1405 
NetTermListByPage(DocType type,DocField field,Int2 page,Int2 numpage,TermListProc proc)1406 NLM_EXTERN Int2 CDECL NetTermListByPage (DocType type, DocField field, Int2 page,
1407                                Int2 numpage, TermListProc proc)
1408 {
1409     int i;
1410     int retval;
1411     short erract;
1412     ErrDesc err;
1413 
1414     for (i = 0; i < ENT_SERV_RETRIES; i++)
1415     {
1416         if (i > 0)
1417         {
1418             if (! ReestablishNetEntrez())
1419                 break;
1420         }
1421 
1422         ErrGetOpts(&erract, NULL);
1423         ErrSetOpts(ERR_CONTINUE, 0);
1424         ErrFetch(&err);
1425         retval = s_NetTermListByPage (type, field, page, numpage, proc);
1426         ErrSetOpts(erract, 0);
1427         if (! ErrFetch(&err))
1428             return retval; /* success */
1429     }
1430 
1431     ErrPost(CTX_UNKNOWN, 1, "NetTermListByPage failure");
1432     return 0;
1433 }
1434 
1435 /*****************************************************************************
1436 *
1437 *   NetEntrezFindTerm(type, field, term, spec, total)
1438 *       returns count of special and total for a term
1439 *       if term ends with  "...", does a truncated merge of the term
1440 *
1441 *****************************************************************************/
1442 static
s_NetEntrezFindTerm(DocType type,DocField field,CharPtr term,Int4Ptr spcl,Int4Ptr totl)1443 Boolean NEAR s_NetEntrezFindTerm (DocType type, DocField field,
1444                                   CharPtr term, Int4Ptr spcl, Int4Ptr totl)
1445 
1446 {
1447     AsnIoPtr asnin = Entrez_asnin;
1448     AsnIoPtr asnout = Entrez_asnout;
1449     TermCountsPtr tcs;
1450     TermLookupPtr tlp;
1451     Boolean found;
1452     AsnTypePtr atp;
1453 
1454     tlp = TermLookupNew();
1455     tlp->type = type;
1456     tlp->fld = field;
1457     tlp->term = StringSave(term);
1458     AsnWrite(asnout, ENTREZ_REQUEST, NULL);
1459     TermLookupAsnWrite(tlp, asnout, ENTREZ_REQUEST_findterm);
1460     TermLookupFree(tlp);
1461     AsnIoReset(asnout);
1462 
1463     /* now, read back response */
1464     if ((atp = NetEntReadAsn()) == NULL)
1465         return FALSE;
1466     if ((tcs = TermCountsAsnRead(asnin, atp)) == NULL)
1467         return FALSE;
1468     LOG_STAT(SUBSYS_CLI_ENTREZ, "Term lookup attempts", 1);
1469     LOG_STAT(SUBSYS_CLI_ENTREZ, "Terms found (special)", tcs->spec_count);
1470     LOG_STAT(SUBSYS_CLI_ENTREZ, "Terms found (total)", tcs->tot_count);
1471     *spcl = tcs->spec_count;
1472     *totl = tcs->tot_count;
1473     found = tcs->found;
1474 
1475     TermCountsFree(tcs);
1476 
1477     return found;
1478 }
1479 
NetEntrezFindTerm(DocType type,DocField field,CharPtr term,Int4Ptr spcl,Int4Ptr totl)1480 NLM_EXTERN Boolean CDECL NetEntrezFindTerm (DocType type, DocField field,
1481                                  CharPtr term, Int4Ptr spcl, Int4Ptr totl)
1482 
1483 {
1484     int i;
1485     int retval;
1486     short erract;
1487     ErrDesc err;
1488 
1489     for (i = 0; i < ENT_SERV_RETRIES; i++)
1490     {
1491         if (i > 0)
1492         {
1493             if (! ReestablishNetEntrez())
1494                 break;
1495         }
1496 
1497         ErrGetOpts(&erract, NULL);
1498         ErrSetOpts(ERR_CONTINUE, 0);
1499         ErrFetch(&err);
1500         retval = s_NetEntrezFindTerm (type, field, term, spcl, totl);
1501         ErrSetOpts(erract, 0);
1502         if (! ErrFetch(&err))
1503             return retval; /* success */
1504     }
1505 
1506     ErrPost(CTX_UNKNOWN, 1, "NetEntrezFindTerm failure");
1507     return FALSE;
1508 }
1509 
1510 
CleanupNamedUidLists(void)1511 static void CleanupNamedUidLists (void)
1512 {
1513     ValNodePtr node;
1514     NamedItemPtr nip;
1515     ValNodePtr nextNode;
1516 
1517     for (node = namedTerms; node != NULL; node = nextNode)
1518     {
1519         nip = (NamedItemPtr) node->data.ptrvalue;
1520 
1521         nextNode = node->next;
1522 
1523         if (nip != NULL) {
1524             FileRemove (nip->tmpFileName);
1525             MemFree (nip->term);
1526             MemFree (nip);
1527         }
1528 
1529         MemFree (node);
1530     }
1531 
1532     namedTerms = NULL;
1533 }
1534 
1535 /**** Check to see if a term is already known to the Network server ********/
KnownNamedTerm(CharPtr term,Boolean onlyIfNotKnown,DocType type,DocField field)1536 static NamedListPtr KnownNamedTerm (CharPtr term, Boolean onlyIfNotKnown,
1537                                     DocType type, DocField field)
1538 {
1539     static NamedList dummy;
1540     ValNodePtr node;
1541     NamedItemPtr nip;
1542     AsnIoPtr aip;
1543     NamedListPtr nlp;
1544 
1545 
1546     for (node = namedTerms; node != NULL; node = node->next)
1547     {
1548         nip = (NamedItemPtr) node->data.ptrvalue;
1549 
1550         if (nip == NULL) {
1551             continue;
1552         }
1553 
1554         if (StringICmp (term, nip->term) == 0 && type == nip->type &&
1555             field == nip->field)
1556         { /* match */
1557             if (onlyIfNotKnown) {
1558                 if (! nip->knownToServer) {
1559                     /* read the file and load the data structure */
1560                     aip = AsnIoOpen (nip->tmpFileName, "rb");
1561                     nlp = NamedListAsnRead(aip, NULL);
1562                     AsnIoClose (aip);
1563                     return nlp;
1564                 } else {
1565                     return NULL;
1566                 }
1567             } else {
1568                 return &dummy;
1569             }
1570         }
1571     }
1572 
1573     return NULL; /* not found */
1574 }
1575 
1576 /**** Creates a term node from the uid parameter ********/
s_NetEntrezCreateNamedUidList(CharPtr term,DocType type,DocField field,Int4 num,DocUidPtr uids)1577 static void NEAR s_NetEntrezCreateNamedUidList (CharPtr term, DocType type, DocField field, Int4 num, DocUidPtr uids)
1578 {
1579     AsnIoPtr asnin = Entrez_asnin;
1580     AsnIoPtr asnout = Entrez_asnout;
1581     NamedListPtr nlp;
1582     AsnTypePtr atp;
1583     NamedItemPtr namedItem;
1584     AsnIoPtr aip;
1585     ValNodePtr node;
1586 
1587     nlp = NamedListNew();
1588     nlp->type = type;
1589     nlp->fld = field;
1590     nlp->term = StringSave(term);
1591     nlp->uids = EntrezIdsNew();
1592     nlp->uids->numid = num;
1593     nlp->uids->ids = (DocUidPtr) MemDup(uids, (size_t) num * sizeof(DocUid));
1594     AsnWrite(asnout, ENTREZ_REQUEST, NULL);
1595     NamedListAsnWrite(nlp, asnout, ENTREZ_REQUEST_createnamed);
1596 
1597     AsnIoReset(asnout);
1598 
1599     if (KnownNamedTerm(term, FALSE, type, field) == NULL) {
1600         node = ValNodeNew (namedTerms);
1601         if (namedTerms == NULL) {
1602           namedTerms = node;
1603         }
1604         namedItem = MemNew (sizeof(NamedItem));
1605         if (node != NULL && namedItem != NULL) {
1606             namedItem->knownToServer = TRUE;
1607             TmpNam (namedItem->tmpFileName);
1608             namedItem->term = StringSave(term);
1609             namedItem->type = type;
1610             namedItem->field = field;
1611             node->data.ptrvalue = (VoidPtr) namedItem;
1612             aip = AsnIoOpen (namedItem->tmpFileName, "wb");
1613             NamedListAsnWrite (nlp, aip, NULL);
1614             AsnIoClose (aip);
1615         }
1616     }
1617 
1618     NamedListFree(nlp);
1619 
1620     if ((atp = NetEntReadAsn()) == NULL)
1621         return;
1622     if (AsnReadVal(asnin, atp, NULL) < 0)   /* read the NULL */
1623         return;
1624 
1625     LOG_STAT(SUBSYS_CLI_ENTREZ, "Named terms created", 1);
1626     LOG_STAT(SUBSYS_CLI_ENTREZ, "Named terms created (UID count)", num);
1627 }
1628 
NetEntrezCreateNamedUidListX(CharPtr term,DocType type,DocField field,ByteStorePtr bsp)1629 NLM_EXTERN void CDECL NetEntrezCreateNamedUidListX (CharPtr term, DocType type, DocField field, ByteStorePtr bsp)
1630 {}
1631 
NetEntrezCreateNamedUidList(CharPtr term,DocType type,DocField field,Int4 num,DocUidPtr uids)1632 NLM_EXTERN void CDECL NetEntrezCreateNamedUidList (CharPtr term, DocType type, DocField field, Int4 num, DocUidPtr uids)
1633 {
1634     int i;
1635     short erract;
1636     ErrDesc err;
1637 
1638     for (i = 0; i < ENT_SERV_RETRIES; i++)
1639     {
1640         if (i > 0)
1641         {
1642             if (! ReestablishNetEntrez())
1643                 break;
1644         }
1645 
1646         ErrGetOpts(&erract, NULL);
1647         ErrSetOpts(ERR_CONTINUE, 0);
1648         ErrFetch(&err);
1649         s_NetEntrezCreateNamedUidList (term, type, field, num, uids);
1650         ErrSetOpts(erract, 0);
1651         if (! ErrFetch(&err))
1652             return; /* success */
1653     }
1654 
1655     ErrPost(CTX_UNKNOWN, 1, "NetEntrezCreateNamedUidList failure");
1656     return;
1657 }
1658 
1659 
NetEntReadAsn(void)1660 static AsnTypePtr NetEntReadAsn(void)
1661 {
1662     AsnTypePtr atp;
1663     DataVal av;
1664     AsnIoPtr asnin = Entrez_asnin;
1665     AsnModulePtr amp;
1666 
1667     NetEntAsnLoad();
1668     amp = AsnAllModPtr();
1669 
1670     atp = ENTREZ_BACK;
1671     if ((atp = AsnReadId(asnin, amp, atp)) != ENTREZ_BACK)
1672     {
1673         ErrPost(CTX_UNKNOWN, 1, "EOF on response from Entrez server");
1674         return NULL;
1675     }
1676     AsnReadVal(asnin, atp, &av);
1677     atp = AsnReadId(asnin, amp, atp);   /* read the CHOICE */
1678     if (atp == ENTREZ_BACK_error)
1679     {
1680         AsnReadVal(asnin, atp, &av);
1681         return NULL;
1682     }
1683     else
1684         return atp;
1685 }
1686 
ReestablishNetEntrez(void)1687 static Boolean ReestablishNetEntrez(void)
1688 {
1689     Monitor *mon;
1690     Boolean retval;
1691     NamedItemPtr nip;
1692     ValNodePtr node;
1693     CharPtr uApplId = NULL;
1694 
1695     if (userApplId != NULL)
1696     { /* make a copy because this can get wiped out by NetEntrezInit() */
1697         uApplId = StringSave(userApplId);
1698     }
1699 
1700     mon = MonitorStrNew("Re-establishing Entrez Service", 40);
1701     MonitorStrValue(mon, "Requesting Entrez service");
1702     NetFini();
1703     retval = TRUE;
1704 
1705     /* clear state information for named UID lists */
1706     for (node = namedTerms; node != NULL; node = node->next)
1707     {
1708         nip = (NamedItemPtr) node->data.ptrvalue;
1709 
1710         if (nip != NULL) {
1711             nip->knownToServer = FALSE;
1712         }
1713     }
1714 
1715     LOG_STAT(SUBSYS_CLI_ENTREZ, "Service Re-establishments", 1);
1716 
1717     if (! NetEntrezInit(uApplId, userWarnings))
1718     {
1719         MonitorStrValue(mon, "Entrez get failed; re-contacting dispatcher");
1720         retval = FALSE;
1721         if (ForceNetInit())
1722         { /* successfully established contact w/dispatcher */
1723             MonitorStrValue(mon, "Entrez get failed; re-requesting Entrez service");
1724             retval = NetEntrezInit(uApplId, userWarnings);
1725         }
1726         else {
1727             ErrPost(CTX_UNKNOWN, 1, "Unable to re-contact dispatcher");
1728             ErrShow();
1729             LOG_STAT(SUBSYS_CLI_ENTREZ, "Service Re-establishments \"retries\"", 1);
1730         }
1731     }
1732 
1733     MonitorFree(mon);
1734 
1735     if (Entrez_asnin == NULL || Entrez_asnout == NULL)
1736     {
1737         retval = FALSE;
1738     }
1739 
1740     if (! retval )
1741     {
1742         ErrPost(CTX_UNKNOWN, 1, "Unable to re-establish Entrez service");
1743         ErrShow();
1744     } else {
1745         ConfigFini(); /* to balance the extra ConfigInit() */
1746     }
1747 
1748     MemFree (uApplId);
1749     return retval;
1750 }
1751 
1752 
SwapInEntrez(VoidPtr med)1753 static Boolean SwapInEntrez (VoidPtr med)
1754 {
1755     MediaPtr media = (MediaPtr) med;
1756     NetMediaInfoPtr nmi;
1757 
1758     if (media == NULL || (nmi = (NetMediaInfoPtr) media->media_info) == NULL)
1759         return FALSE;
1760 
1761     if (nmi->sessionHandle == NULL)
1762         return FALSE;
1763 
1764     Entrez_ni = nmi->sessionHandle;
1765 
1766     Entrez_asnin = Entrez_ni->raip;
1767     Entrez_asnout = Entrez_ni->waip;
1768 
1769     return TRUE;
1770 }
1771 
countChars(CharPtr str)1772 static void countChars(CharPtr str)
1773 {
1774     charCount += StringLen(str) + 5;
1775 }
1776 
1777 /*****************************************************************************
1778 *
1779 *   NetEntMedlineEntryListGet (result, numuid, uids, mark_missing)
1780 *       returns a count of entries read
1781 *       if (mark_missing) ids which could not be located are made negative
1782 *
1783 *****************************************************************************/
1784 static
s_NetEntMedlineEntryListGet(MedlineEntryPtr PNTR result,Int2 numuid,DocUidPtr uids,Boolean mark_missing)1785 Int2 NEAR s_NetEntMedlineEntryListGet (MedlineEntryPtr PNTR result, Int2 numuid,
1786                                     DocUidPtr uids, Boolean mark_missing)
1787 {
1788     AsnTypePtr atp;
1789     EntrezDocGetPtr edgp;
1790     MedlineEntryListPtr mllp;
1791     int count;
1792 
1793     edgp = EntrezDocGetNew();
1794 
1795     edgp->cls = TYP_ML; /* unused */
1796     edgp->ids = EntrezIdsNew();
1797     edgp->ids->numid = numuid;
1798     edgp->ids->ids = uids;
1799     edgp->mark_missing = mark_missing;
1800 
1801     AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
1802     EntrezDocGetAsnWrite(edgp, Entrez_asnout, ENTREZ_REQUEST_getmle);
1803     AsnIoReset(Entrez_asnout);
1804     edgp->ids->ids = NULL; /* for clean memory free */
1805     EntrezDocGetFree(edgp);
1806 
1807     if ((atp = NetEntReadAsn()) == NULL)
1808         return 0;
1809 
1810     if ((mllp = MedlineEntryListAsnRead(Entrez_asnin, atp)) == NULL)
1811         return 0;
1812 
1813     MemCopy (result, mllp->data, (size_t) mllp->num * sizeof(MedlineEntryPtr));
1814 
1815     /* note that the structures underlying mllp->data are not freed; they */
1816     /* are used by the caller                                             */
1817     MemFree(mllp->data);
1818     mllp->data = NULL; /* for clean free */
1819     if (mark_missing && mllp->marked_missing)
1820     {
1821         MemCopy (uids, mllp->marked_missing->ids,
1822              (size_t) mllp->marked_missing->numid * sizeof(DocUid));
1823     }
1824     count = mllp->num;
1825     MedlineEntryListFree (mllp);
1826     LOG_STAT(SUBSYS_CLI_ENTREZ, "Medline entries retrieved", count);
1827     LOG_STAT(SUBSYS_CLI_ENTREZ, "Medline entries requested", numuid);
1828 
1829     return count;
1830 }
1831 
NetEntMedlineEntryListGet(MedlineEntryPtr PNTR result,Int2 numuid,DocUidPtr uids,Boolean mark_missing)1832 NLM_EXTERN Int2 NetEntMedlineEntryListGet (MedlineEntryPtr PNTR result, Int2 numuid,
1833                                     DocUidPtr uids, Boolean mark_missing)
1834 {
1835     int i;
1836     int retval;
1837     short erract;
1838     ErrDesc err;
1839     DocUidPtr local_uids;
1840 
1841     /* make a local copy, to handle modifications */
1842     local_uids = MemNew(sizeof(DocUid) * numuid);
1843 
1844     for (i = 0; i < ENT_SERV_RETRIES; i++)
1845     {
1846         MemCopy(local_uids, uids, sizeof(DocUid) * numuid);
1847         if (i > 0)
1848         {
1849             if (! ReestablishNetEntrez())
1850                 break;
1851         }
1852 
1853         ErrGetOpts(&erract, NULL);
1854         ErrSetOpts(ERR_CONTINUE, 0);
1855         ErrFetch(&err);
1856         retval = s_NetEntMedlineEntryListGet(result, numuid, local_uids,
1857                                           mark_missing);
1858         ErrSetOpts(erract, 0);
1859         if (! ErrFetch(&err))
1860         {
1861             MemCopy(uids, local_uids, sizeof(DocUid) * numuid);
1862             MemFree(local_uids);
1863             return retval; /* success */
1864         }
1865     }
1866 
1867     MemFree(local_uids);
1868     ErrPost(CTX_UNKNOWN, 1, "NetMedlineEntryListGet failure");
1869     return -1;
1870 }
1871 
1872 /*****************************************************************************
1873 *
1874 *   NetEntSeqEntryListGet (result, numuid, uids, mark_missing)
1875 *       returns a count of entries read
1876 *       if (mark_missing) ids which could not be located are made negative
1877 *
1878 *****************************************************************************/
1879 static
s_NetEntSeqEntryListGet(SeqEntryPtr PNTR result,Int2 numuid,DocUidPtr uids,Int2 retcode,Boolean mark_missing)1880 Int2 NEAR s_NetEntSeqEntryListGet (SeqEntryPtr PNTR result, Int2 numuid, DocUidPtr uids, Int2 retcode, Boolean mark_missing)
1881 {
1882     AsnTypePtr atp;
1883     EntrezIdsPtr glp;
1884     SeqEntryListPtr selp;
1885     EntrezSeqGetPtr sgsp;
1886     int count;
1887 
1888     sgsp = EntrezSeqGetNew();
1889     glp = EntrezIdsNew();
1890     sgsp->ids = glp;
1891 
1892     glp->numid = numuid;
1893     glp->ids = uids;
1894     sgsp->mark_missing = mark_missing;
1895     sgsp->retype = retcode;
1896 
1897     AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
1898     EntrezSeqGetAsnWrite(sgsp, Entrez_asnout, ENTREZ_REQUEST_getseq);
1899     AsnIoReset(Entrez_asnout);
1900     glp->ids = NULL; /* for clean memory free */
1901     EntrezSeqGetFree(sgsp);
1902 
1903     if ((atp = NetEntReadAsn()) == NULL)
1904         return 0;
1905 
1906     if ((selp = SeqEntryListAsnRead(Entrez_asnin, atp)) == NULL)
1907         return 0;
1908 
1909     MemCopy (result, selp->data, (size_t) selp->num * sizeof(SeqEntryPtr));
1910     /* note that the structures underlying selp->data are not freed; they */
1911     /* are used by the caller                                             */
1912     MemFree(selp->data);
1913     selp->data = NULL; /* for clean free */
1914     if (mark_missing && selp->marked_missing)
1915     {
1916         MemCopy (uids, selp->marked_missing->ids,
1917              (size_t) selp->marked_missing->numid * sizeof(DocUid));
1918     }
1919     count = selp->num;
1920     SeqEntryListFree (selp);
1921     LOG_STAT(SUBSYS_CLI_ENTREZ, "Sequence entries retrieved", count);
1922     LOG_STAT(SUBSYS_CLI_ENTREZ, "Sequence entries requested", numuid);
1923 
1924     return count;
1925 }
1926 
NetEntSeqEntryListGet(SeqEntryPtr PNTR result,Int2 numuid,DocUidPtr uids,Int2 retcode,Boolean mark_missing)1927 NLM_EXTERN Int2 CDECL NetEntSeqEntryListGet (SeqEntryPtr PNTR result, Int2 numuid,
1928                                DocUidPtr uids, Int2 retcode, Boolean mark_missing)
1929 {
1930     int i;
1931     int retval;
1932     short erract;
1933     ErrDesc err;
1934     DocUidPtr local_uids;
1935 
1936     /* make a local copy, to handle modifications */
1937     local_uids = MemNew(sizeof(DocUid) * numuid);
1938 
1939     for (i = 0; i < ENT_SERV_RETRIES; i++)
1940     {
1941         MemCopy(local_uids, uids, sizeof(DocUid) * numuid);
1942         if (i > 0)
1943         {
1944             if (! ReestablishNetEntrez())
1945                 break;
1946         }
1947 
1948         ErrGetOpts(&erract, NULL);
1949         ErrSetOpts(ERR_CONTINUE, 0);
1950         ErrFetch(&err);
1951         retval = s_NetEntSeqEntryListGet(result, numuid, local_uids, retcode,
1952                                       mark_missing);
1953         ErrSetOpts(erract, 0);
1954         if (! ErrFetch(&err))
1955         {
1956             MemCopy(uids, local_uids, sizeof(DocUid) * numuid);
1957             MemFree(local_uids);
1958             return retval; /* success */
1959         }
1960     }
1961 
1962     MemFree(local_uids);
1963     ErrPost(CTX_UNKNOWN, 1, "NetSeqEntryListGet failure");
1964     return -1;
1965 }
1966 
1967 
1968 #ifdef Biostruc_supported
1969 /*****************************************************************************
1970 *
1971 *   NetEntrezBiostrucListGet (result, numuid, uids, mark_missing)
1972 *       returns a count of entries read
1973 *       if (mark_missing) ids which could not be located are made negative
1974 *
1975 *****************************************************************************/
1976 static
s_NetEntrezBiostrucListGet(BiostrucPtr PNTR result,Int4 mdlLvl,Int4 maxModels,Int2 numuid,DocUidPtr uids,Boolean mark_missing)1977 Int2 NEAR s_NetEntrezBiostrucListGet (BiostrucPtr PNTR result, Int4 mdlLvl,
1978                                       Int4 maxModels, Int2 numuid,
1979                                       DocUidPtr uids, Boolean mark_missing)
1980 {
1981     AsnTypePtr atp;
1982     EntrezDocGetPtr edgp;
1983     BiostrucListPtr bslp;
1984     int count;
1985     DataVal av;
1986 
1987     edgp = EntrezDocGetNew();
1988 
1989     edgp->cls = TYP_ST; /* unused */
1990     edgp->ids = EntrezIdsNew();
1991     edgp->ids->numid = numuid;
1992     edgp->ids->ids = uids;
1993     edgp->mark_missing = mark_missing;
1994 
1995     av.intvalue = mdlLvl;
1996     AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
1997     AsnStartStruct(Entrez_asnout, ENTREZ_REQUEST_getbiostrX);
1998     AsnWrite(Entrez_asnout, REQUEST_getbiostrX_complexity, &av);
1999     EntrezDocGetAsnWrite(edgp, Entrez_asnout, ENTREZ_REQUEST_getbiostrX_get);
2000     av.intvalue = maxModels;
2001     AsnWrite(Entrez_asnout, REQUEST_getbiostrX_max_models, &av);
2002     AsnEndStruct(Entrez_asnout, ENTREZ_REQUEST_getbiostrX);
2003     AsnIoReset(Entrez_asnout);
2004     edgp->ids->ids = NULL; /* for clean memory free */
2005     EntrezDocGetFree(edgp);
2006 
2007     if ((atp = NetEntReadAsn()) == NULL)
2008         return 0;
2009 
2010     if ((bslp = BiostrucListAsnRead(Entrez_asnin, atp)) == NULL)
2011         return 0;
2012 
2013     MemCopy (result, bslp->data, (size_t) bslp->num * sizeof(BiostrucPtr));
2014 
2015     /* note that the structures underlying bslp->data are not freed; they */
2016     /* are used by the caller                                             */
2017     MemFree(bslp->data);
2018     bslp->data = NULL; /* for clean free */
2019     if (mark_missing && bslp->marked_missing)
2020     {
2021         MemCopy (uids, bslp->marked_missing->ids,
2022              (size_t) bslp->marked_missing->numid * sizeof(DocUid));
2023     }
2024     count = bslp->num;
2025     BiostrucListFree (bslp);
2026     LOG_STAT(SUBSYS_CLI_ENTREZ, "Biostruc entries retrieved", count);
2027     LOG_STAT(SUBSYS_CLI_ENTREZ, "Biostruc entries requested", numuid);
2028 
2029     return count;
2030 }
2031 
NetEntrezBiostrucListGet(BiostrucPtr PNTR result,Int4 mdlLvl,Int4 maxModels,Int2 numuid,DocUidPtr uids,Boolean mark_missing)2032 NLM_EXTERN Int2 NetEntrezBiostrucListGet (BiostrucPtr PNTR result, Int4 mdlLvl, Int4 maxModels, Int2 numuid,
2033                                     DocUidPtr uids, Boolean mark_missing)
2034 {
2035     int i;
2036     int retval;
2037     short erract;
2038     ErrDesc err;
2039     DocUidPtr local_uids;
2040 
2041     /* make a local copy, to handle modifications */
2042     local_uids = MemNew(sizeof(DocUid) * numuid);
2043 
2044     for (i = 0; i < ENT_SERV_RETRIES; i++)
2045     {
2046         MemCopy(local_uids, uids, sizeof(DocUid) * numuid);
2047         if (i > 0)
2048         {
2049             if (! ReestablishNetEntrez())
2050                 break;
2051         }
2052 
2053         ErrGetOpts(&erract, NULL);
2054         ErrSetOpts(ERR_CONTINUE, 0);
2055         ErrFetch(&err);
2056         retval = s_NetEntrezBiostrucListGet(result, mdlLvl, maxModels, numuid, local_uids,
2057                                           mark_missing);
2058         ErrSetOpts(erract, 0);
2059         if (! ErrFetch(&err))
2060         {
2061             MemCopy(uids, local_uids, sizeof(DocUid) * numuid);
2062             MemFree(local_uids);
2063             return retval; /* success */
2064         }
2065     }
2066 
2067     MemFree(local_uids);
2068     ErrPost(CTX_UNKNOWN, 1, "NetBiostrucListGet failure");
2069     return -1;
2070 }
2071 
2072 static
s_NetEntrezBiostrucAnnotSetGet(DocUid gi)2073 BiostrucAnnotSetPtr NEAR s_NetEntrezBiostrucAnnotSetGet (DocUid gi)
2074 {
2075     DataVal av;
2076     BiostrucAnnotSetPtr retval;
2077     AsnTypePtr atp;
2078 
2079     AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
2080     av.intvalue = gi;
2081     AsnWrite(Entrez_asnout, ENTREZ_REQUEST_getbiostrannot, &av);
2082     AsnIoReset(Entrez_asnout);
2083 
2084     if ((atp = NetEntReadAsn()) == NULL)
2085         return NULL;
2086 
2087     retval = BiostrucAnnotSetAsnRead(Entrez_asnin, atp);
2088 
2089     LOG_STAT(SUBSYS_CLI_ENTREZ, "BiostrucAnnotSets retrieved", 1);
2090 
2091     return retval;
2092 }
2093 
NetEntrezBiostrucAnnotSetGet(DocUid gi)2094 NLM_EXTERN BiostrucAnnotSetPtr CDECL NetEntrezBiostrucAnnotSetGet (DocUid gi)
2095 {
2096     int i;
2097     BiostrucAnnotSetPtr retval;
2098     short erract;
2099     ErrDesc err;
2100 
2101     for (i = 0; i < ENT_SERV_RETRIES; i++)
2102     {
2103         if (i > 0)
2104         {
2105             if (! ReestablishNetEntrez())
2106                 break;
2107         }
2108 
2109         ErrGetOpts(&erract, NULL);
2110         ErrSetOpts(ERR_CONTINUE, 0);
2111         ErrFetch(&err);
2112         retval = s_NetEntrezBiostrucAnnotSetGet(gi);
2113         ErrSetOpts(erract, 0);
2114         if (! ErrFetch(&err))
2115         {
2116             return retval; /* success */
2117         }
2118     }
2119 
2120     ErrPost(CTX_UNKNOWN, 1, "NetBiostrucAnnotSet failure");
2121     return NULL;
2122 }
2123 
2124 static
s_NetEntrezBiostrucFeatIds(DocUid mmdbid,Int2 feature_type,Int4 feature_set_id)2125 LinkSetPtr NEAR s_NetEntrezBiostrucFeatIds(DocUid mmdbid, Int2 feature_type, Int4 feature_set_id)
2126 {
2127     LinkSetPtr retval;
2128     GetFeatIdsPtr gfi;
2129     AsnTypePtr atp;
2130 
2131     AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
2132     gfi = GetFeatIdsNew();
2133     gfi->mmdbid = mmdbid;
2134     gfi->feature_type = feature_type;
2135     gfi->feature_set_id = feature_set_id;
2136     GetFeatIdsAsnWrite(gfi, Entrez_asnout, REQUEST_getbiostr_feat_ids);
2137     AsnIoReset(Entrez_asnout);
2138     GetFeatIdsFree(gfi);
2139 
2140     if ((atp = NetEntReadAsn()) == NULL)
2141         return NULL;
2142 
2143     retval = LinkSetAsnRead(Entrez_asnin, atp);
2144 
2145     LOG_STAT(SUBSYS_CLI_ENTREZ, "BiostrucAnnotFeatids retrieved", 1);
2146 
2147     return retval;
2148 }
2149 
NetEntrezBiostrucFeatIds(DocUid mmdbid,Int2 feature_type,Int4 feature_set_id)2150 NLM_EXTERN LinkSetPtr CDECL NetEntrezBiostrucFeatIds(DocUid mmdbid, Int2 feature_type, Int4 feature_set_id)
2151 {
2152     int i;
2153     LinkSetPtr retval;
2154     short erract;
2155     ErrDesc err;
2156 
2157     for (i = 0; i < ENT_SERV_RETRIES; i++)
2158     {
2159         if (i > 0)
2160         {
2161             if (! ReestablishNetEntrez())
2162                 break;
2163         }
2164 
2165         ErrGetOpts(&erract, NULL);
2166         ErrSetOpts(ERR_CONTINUE, 0);
2167         ErrFetch(&err);
2168         retval = s_NetEntrezBiostrucFeatIds(mmdbid, feature_type, feature_set_id);
2169         ErrSetOpts(erract, 0);
2170         if (! ErrFetch(&err))
2171         {
2172             return retval; /* success */
2173         }
2174     }
2175 
2176     ErrPost(CTX_UNKNOWN, 1, "NetBiostrucAnnotFeatIds failure");
2177     return NULL;
2178 }
2179 
2180 static
s_NetEntrezBiostrucAnnotSetGetByFid(DocUid mmdbid,Int4 feature_id,Int4 feature_set_id)2181 BiostrucAnnotSetPtr NEAR s_NetEntrezBiostrucAnnotSetGetByFid (DocUid mmdbid, Int4 feature_id, Int4 feature_set_id)
2182 {
2183     BiostrucAnnotSetPtr retval;
2184     AsnTypePtr atp;
2185     GetByFidPtr gbf;
2186 
2187     gbf = GetByFidNew();
2188     gbf->mmdbid = mmdbid;
2189     gbf->feature_id = feature_id;
2190     gbf->feature_set_id = feature_set_id;
2191     GetByFidAsnWrite(gbf, Entrez_asnout, REQUEST_getbiostr_annot_by_fid);
2192     AsnIoReset(Entrez_asnout);
2193     GetByFidFree(gbf);
2194 
2195     if ((atp = NetEntReadAsn()) == NULL)
2196         return NULL;
2197 
2198     retval = BiostrucAnnotSetAsnRead(Entrez_asnin, atp);
2199 
2200     LOG_STAT(SUBSYS_CLI_ENTREZ, "BiostrucAnnotSetsByFid retrieved", 1);
2201 
2202     return retval;
2203 }
2204 
NetEntrezBiostrucAnnotSetGetByFid(DocUid mmdbid,Int4 feature_id,Int4 feature_set_id)2205 NLM_EXTERN BiostrucAnnotSetPtr CDECL NetEntrezBiostrucAnnotSetGetByFid (DocUid mmdbid, Int4 feature_id, Int4 feature_set_id)
2206 {
2207     int i;
2208     BiostrucAnnotSetPtr retval;
2209     short erract;
2210     ErrDesc err;
2211 
2212     for (i = 0; i < ENT_SERV_RETRIES; i++)
2213     {
2214         if (i > 0)
2215         {
2216             if (! ReestablishNetEntrez())
2217                 break;
2218         }
2219 
2220         ErrGetOpts(&erract, NULL);
2221         ErrSetOpts(ERR_CONTINUE, 0);
2222         ErrFetch(&err);
2223         retval = s_NetEntrezBiostrucAnnotSetGetByFid (mmdbid, feature_id, feature_set_id);
2224         ErrSetOpts(erract, 0);
2225         if (! ErrFetch(&err))
2226         {
2227             return retval; /* success */
2228         }
2229     }
2230 
2231     ErrPost(CTX_UNKNOWN, 1, "NetBiostrucAnnotByFid failure");
2232     return NULL;
2233 }
2234 #endif /* Biostruc_supported */
2235 
2236 
2237 static
s_NetSeqIdForGI(DocUid gi)2238 SeqIdPtr NEAR s_NetSeqIdForGI (DocUid gi)
2239 {
2240     DataVal av;
2241     SeqIdPtr retval;
2242     AsnTypePtr atp;
2243 
2244     AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
2245     av.intvalue = gi;
2246     AsnWrite(Entrez_asnout, ENTREZ_REQUEST_seqidforgi, &av);
2247     AsnIoReset(Entrez_asnout);
2248 
2249     if ((atp = NetEntReadAsn()) == NULL)
2250         return NULL;
2251 
2252     retval = SeqIdAsnRead(Entrez_asnin, atp);
2253 
2254     LOG_STAT(SUBSYS_CLI_ENTREZ, "Sequence IDs looked up by GI", 1);
2255 
2256     return retval;
2257 }
2258 
NetSeqIdForGI(DocUid gi)2259 NLM_EXTERN SeqIdPtr CDECL NetSeqIdForGI (DocUid gi)
2260 {
2261     int i;
2262     SeqIdPtr retval;
2263     short erract;
2264     ErrDesc err;
2265 
2266     for (i = 0; i < ENT_SERV_RETRIES; i++)
2267     {
2268         if (i > 0)
2269         {
2270             if (! ReestablishNetEntrez())
2271                 break;
2272         }
2273 
2274         ErrGetOpts(&erract, NULL);
2275         ErrSetOpts(ERR_CONTINUE, 0);
2276         ErrFetch(&err);
2277         retval = s_NetSeqIdForGI(gi);
2278         ErrSetOpts(erract, 0);
2279         if (! ErrFetch(&err))
2280         {
2281             return retval; /* success */
2282         }
2283     }
2284 
2285     ErrPost(CTX_UNKNOWN, 1, "NetSeqIdForGI failure");
2286     return NULL;
2287 }
2288 
2289 static
s_NetFindSeqId(SeqIdPtr sip)2290 Int4 NEAR s_NetFindSeqId (SeqIdPtr sip)
2291 {
2292     DataVal av;
2293     AsnTypePtr atp;
2294 
2295     AsnWrite(Entrez_asnout, ENTREZ_REQUEST, NULL);
2296     SeqIdAsnWrite(sip, Entrez_asnout, ENTREZ_REQUEST_findseqid);
2297     AsnIoReset(Entrez_asnout);
2298 
2299     if ((atp = NetEntReadAsn()) == NULL)
2300         return 0;
2301 
2302     AsnReadVal(Entrez_asnin, atp, &av);
2303 
2304     LOG_STAT(SUBSYS_CLI_ENTREZ, "Sequence GIs looked up by SeqID", 1);
2305 
2306     return av.intvalue;
2307 }
2308 
NetEntrezFindSeqId(SeqIdPtr sip)2309 NLM_EXTERN Int4 CDECL NetEntrezFindSeqId (SeqIdPtr sip)
2310 {
2311     int i;
2312     Int4 retval;
2313     short erract;
2314     ErrDesc err;
2315 
2316     for (i = 0; i < ENT_SERV_RETRIES; i++)
2317     {
2318         if (i > 0)
2319         {
2320             if (! ReestablishNetEntrez())
2321                 break;
2322         }
2323 
2324         ErrGetOpts(&erract, NULL);
2325         ErrSetOpts(ERR_CONTINUE, 0);
2326         ErrFetch(&err);
2327         retval = s_NetFindSeqId(sip);
2328         ErrSetOpts(erract, 0);
2329         if (! ErrFetch(&err))
2330         {
2331             return retval; /* success */
2332         }
2333     }
2334 
2335     ErrPost(CTX_UNKNOWN, 1, "NetFindSeqId failure");
2336 
2337     return 0;
2338 }
2339 
s_NetEntHierarchyGet(CharPtr term,DocType type,DocField field)2340 static EntrezHierarchyPtr s_NetEntHierarchyGet(CharPtr term, DocType type, DocField field)
2341 {
2342   AsnIoPtr asnin = Entrez_asnin;
2343   AsnIoPtr asnout = Entrez_asnout;
2344   EntrezHierarchyPtr ehp;
2345   TermLookupPtr tlp;
2346   AsnTypePtr atp;
2347 
2348   tlp = TermLookupNew();
2349   tlp->type = type;
2350   tlp->fld = field;
2351   tlp->term = StringSave(term);
2352   AsnWrite(asnout, ENTREZ_REQUEST, NULL);
2353   TermLookupAsnWrite(tlp, asnout, ENTREZ_REQUEST_get_hierarchy);
2354   TermLookupFree(tlp);
2355   AsnIoReset(asnout);
2356 
2357   /* now, read back response */
2358   if ((atp = NetEntReadAsn()) == NULL)
2359     return FALSE;
2360 
2361   if ( (ehp = EntrezHierarchyAsnRead(asnin,ENTREZ_BACK_get_hierarchy)) == NULL)
2362     return  NULL;
2363 
2364   if (ehp->numInLineage == 0 && ehp->numChildren == 0)
2365   {
2366       EntrezHierarchyFree(ehp);
2367       return NULL;
2368   }
2369 
2370   return (ehp);
2371 }
2372 
2373 
NetEntHierarchyGet(CharPtr term,DocType type,DocField field)2374 NLM_EXTERN EntrezHierarchyPtr NetEntHierarchyGet (CharPtr term, DocType type, DocField field)
2375 {
2376   int i;
2377   EntrezHierarchyPtr ehp;
2378   short erract;
2379   ErrDesc err;
2380 
2381   for (i = 0; i < ENT_SERV_RETRIES; i++)
2382     {
2383       if (i > 0)
2384         {
2385           if (! ReestablishNetEntrez())
2386             break;
2387         }
2388 
2389       ErrGetOpts(&erract, NULL);
2390       ErrSetOpts(ERR_CONTINUE, 0);
2391       ErrFetch(&err);
2392       ehp = s_NetEntHierarchyGet(term, type, field);
2393       ErrSetOpts(erract, 0);
2394       if (! ErrFetch(&err))
2395         {
2396           return ehp; /* success */
2397         }
2398     }
2399 
2400   ErrPost(CTX_UNKNOWN, 1, "NetEntMeshTreeGet failure");
2401 
2402   return NULL;
2403 }
2404 
s_DatabaseFromName(CharPtr name)2405 static Int2 s_DatabaseFromName (CharPtr name)
2406 
2407 {
2408   Int2           db;
2409   EntrezInfoPtr  eip;
2410 
2411   if (name == NULL) return 0;
2412   eip = EntrezGetInfo ();
2413   if (eip == NULL || eip->type_info == NULL) return 0;
2414   for (db = 0; db < eip->type_count; db++) {
2415     if (StringICmp (eip->type_info [db].name, name) == 0) {
2416       return eip->type_info [db].id;
2417     }
2418   }
2419   return 0;
2420 }
2421 
s_FieldFromTag(CharPtr tag)2422 static Int2 s_FieldFromTag (CharPtr tag)
2423 
2424 {
2425   EntrezInfoPtr  eip;
2426   Int2           fld;
2427 
2428   if (tag == NULL) return 0;
2429   eip = EntrezGetInfo ();
2430   if (eip == NULL || eip->field_info == NULL) return 0;
2431   for (fld = 0; fld < eip->field_count; fld++) {
2432     if (StringICmp (eip->field_info [fld].tag, tag) == 0) {
2433       return eip->field_info [fld].id;
2434     }
2435   }
2436   return 0;
2437 }
2438 
NetEntMeshHierarchyGet(CharPtr term)2439 NLM_EXTERN EntrezHierarchyPtr NetEntMeshHierarchyGet(CharPtr term)
2440 {
2441   Int2  fld_mesh_hier;
2442   Int2  typ_ml;
2443 
2444   typ_ml = s_DatabaseFromName ("MEDLINE");
2445   fld_mesh_hier = s_FieldFromTag ("MESH");
2446   return NetEntHierarchyGet (term, typ_ml, fld_mesh_hier);
2447 }
2448 
2449 
s_NetEntDoNeighborText(EntrezNeighborTextPtr entp)2450 static LinkSetPtr s_NetEntDoNeighborText(EntrezNeighborTextPtr entp)
2451 {
2452   LinkSetPtr lsp = NULL;
2453   AsnTypePtr atp;
2454   AsnIoPtr asnin = Entrez_asnin;
2455   AsnIoPtr asnout = Entrez_asnout;
2456 
2457   RemoveNonPrintingCharacters(entp->normalText);
2458   RemoveNonPrintingCharacters(entp->specialText);
2459 
2460   if  ( (*SkipSpaces(entp->normalText) == '\0')
2461        && (*SkipSpaces(entp->specialText) == '\0') )
2462     return (NULL);
2463 
2464   AsnWrite(asnout, ENTREZ_REQUEST, NULL);
2465   EntrezNeighborTextAsnWrite(entp,asnout,ENTREZ_REQUEST_neighbortext);
2466   AsnIoReset(asnout);
2467 
2468   if ( (atp = NetEntReadAsn()) == NULL)
2469     return NULL;
2470 
2471   if ( (lsp = LinkSetAsnRead(asnin, ENTREZ_BACK_neighbortext)) == NULL)
2472     return(NULL);
2473 
2474   return (lsp);
2475 }
2476 
2477 
2478 
NetEntDoNeighborText(EntrezNeighborTextPtr entp)2479 NLM_EXTERN LinkSetPtr CDECL NetEntDoNeighborText (EntrezNeighborTextPtr entp)
2480 {
2481   int i;
2482   LinkSetPtr lsp;
2483   short erract;
2484   ErrDesc err;
2485 
2486   for (i = 0; i < ENT_SERV_RETRIES; i++)
2487     {
2488       if (i > 0)
2489         {
2490           if (! ReestablishNetEntrez())
2491             break;
2492         }
2493 
2494       ErrGetOpts(&erract, NULL);
2495       ErrSetOpts(ERR_CONTINUE, 0);
2496       ErrFetch(&err);
2497       lsp = s_NetEntDoNeighborText(entp);
2498 /* debug       if (lsp == NULL)
2499         fprintf(stderr,"failed to get linkset pointer. \n"); */
2500       ErrSetOpts(erract, 0);
2501       if (! ErrFetch(&err))
2502         return lsp; /* success */
2503     }
2504 
2505   ErrPost(CTX_UNKNOWN, 1, "NetEntDoNeighborText failure");
2506   return NULL;
2507 }
2508 
2509 
NetEntCanNeighborText(void)2510 NLM_EXTERN Boolean CDECL NetEntCanNeighborText(void)
2511 {
2512     EntrezExtraInfoPtr myeeip;
2513 
2514     if ((myeeip = GetEntrezExtraInfo()) == NULL)
2515     {
2516         return FALSE;
2517     }
2518 
2519     return myeeip->canneighbortext;
2520 }
2521 
2522 
NetEntExpandedMedlineFeatures(void)2523 NLM_EXTERN Boolean CDECL NetEntExpandedMedlineFeatures(void)
2524 {
2525     EntrezExtraInfoPtr myeeip;
2526 
2527     if ((myeeip = GetEntrezExtraInfo()) == NULL)
2528     {
2529         return FALSE;
2530     }
2531 
2532     return myeeip->expanded_medline;
2533 }
2534 
2535 
NetEntCanBlast(void)2536 NLM_EXTERN Boolean CDECL NetEntCanBlast(void)
2537 {
2538     EntrezExtraInfoPtr myeeip;
2539 
2540     if ((myeeip = GetEntrezExtraInfo()) == NULL)
2541     {
2542         return FALSE;
2543     }
2544 
2545     return myeeip->canblast;
2546 }
2547 
2548 
RemoveNonPrintingCharacters(CharPtr str)2549 static void RemoveNonPrintingCharacters(CharPtr str)
2550 {
2551   while (*str)
2552     {
2553       if ( (*str < ' ') || (*str > 0x7E) )
2554         *str = ' ';
2555       str++;
2556     }
2557 }
2558 
2559 static Boolean
blastProgressMonitor(Int4 value,Boolean isStart,Boolean destroyIt)2560 blastProgressMonitor (Int4 value, Boolean isStart, Boolean destroyIt)
2561 {
2562     static MonitorPtr mon = NULL;
2563     Boolean retval = TRUE;
2564 
2565     if (destroyIt)
2566     {
2567         if (mon != NULL)
2568         {
2569             MonitorFree(mon);
2570             mon = NULL;
2571         }
2572         return TRUE;
2573     }
2574 
2575     if (isStart)
2576     {
2577         if (mon != NULL)
2578         {
2579             MonitorFree(mon);
2580             mon = NULL;
2581         }
2582         mon = MonitorIntNew("BLAST progress", 0, value);
2583     } else {
2584         if (mon != NULL)
2585         {
2586             retval = MonitorIntValue(mon, value);
2587         }
2588     }
2589 
2590     return retval;
2591 }
2592 
2593 static LinkSetPtr
s_NetEntBlastBioseq(BioseqPtr bsp,DocType db,CharPtr program,CharPtr database,CharPtr options,Boolean usemonitor,BoolPtr noMoreTriesPtr)2594 s_NetEntBlastBioseq(BioseqPtr bsp, DocType db, CharPtr program, CharPtr database, CharPtr options, Boolean usemonitor, BoolPtr noMoreTriesPtr)
2595 {
2596      EntrezBlastreqPtr ebrp;
2597      LinkSetPtr lsp;
2598      AsnTypePtr atp;
2599      DataVal av;
2600      AsnModulePtr amp;
2601 
2602      NetEntAsnLoad();
2603      amp = AsnAllModPtr();
2604 
2605      ebrp = EntrezBlastreqNew();
2606      ebrp->bsp = bsp;
2607      ebrp->bsp_database = db;
2608      ebrp->program = StringSave(program);
2609      ebrp->database = StringSave(database);
2610      ebrp->options = StringSave(options);
2611      ebrp->showprogress = usemonitor;
2612      EntrezBlastreqAsnWrite(ebrp, Entrez_asnout, ENTREZ_REQUEST_blast);
2613      ebrp->bsp = NULL; /* we don't "own" this so have no business freeing it */
2614      EntrezBlastreqFree(ebrp);
2615      AsnIoReset(Entrez_asnout);
2616 
2617      while (TRUE)
2618      {
2619          if ( (atp = NetEntReadAsn()) == NULL)
2620            return NULL;
2621          AsnReadVal(Entrez_asnin, atp, NULL);
2622          if ( (atp = AsnReadId(Entrez_asnin, amp, atp)) == NULL)
2623            return NULL;
2624          if (atp == ENTREZ_BACK_blast_bad_count)
2625          {
2626              AsnReadVal(Entrez_asnin, atp, NULL);
2627              blastProgressMonitor(0, FALSE, TRUE);
2628              return NULL;
2629          } else
2630          if (atp == ENTREZ_BACK_blast_link_set)
2631          {
2632              blastProgressMonitor(0, FALSE, TRUE);
2633              lsp = LinkSetAsnRead(Entrez_asnin, atp);
2634              return (lsp);
2635          } else
2636          if (atp == ENTREZ_BACK_blast_job_start)
2637          {
2638             AsnReadVal(Entrez_asnin, atp, &av);
2639             if (usemonitor)
2640                 blastProgressMonitor(av.intvalue, TRUE, FALSE);
2641          } else
2642          if (atp == ENTREZ_BACK_blast_job_progress)
2643          {
2644             AsnReadVal(Entrez_asnin, atp, &av);
2645             if (usemonitor)
2646                 if (! blastProgressMonitor(av.intvalue, FALSE, FALSE))
2647                 { /* user cancelled BLAST search */
2648                     blastProgressMonitor(0, FALSE, TRUE);
2649                     /* drop our connection since we don't know what state we're in */
2650                     ReestablishNetEntrez();
2651                     if (noMoreTriesPtr != NULL)
2652                         *noMoreTriesPtr = TRUE;
2653                     return NULL;
2654                 }
2655          } else {
2656              return NULL;
2657          }
2658      }
2659 }
2660 
2661 NLM_EXTERN LinkSetPtr LIBCALL
NetEntBlastBioseq(BioseqPtr bsp,DocType db,CharPtr program,CharPtr database,CharPtr options,Boolean usemonitor)2662 NetEntBlastBioseq(BioseqPtr bsp, DocType db, CharPtr program, CharPtr database, CharPtr options, Boolean usemonitor)
2663 {
2664   int i;
2665   LinkSetPtr lsp;
2666   short erract;
2667   ErrDesc err;
2668   Boolean noMoreTries;
2669 
2670   for (i = 0; i < ENT_SERV_RETRIES; i++)
2671     {
2672       if (i > 0)
2673         {
2674           if (! ReestablishNetEntrez())
2675             break;
2676         }
2677 
2678       ErrGetOpts(&erract, NULL);
2679       ErrSetOpts(ERR_CONTINUE, 0);
2680       ErrFetch(&err);
2681       /*MsgSetReadTimeout(Entrez_ni, 1200);*/
2682       noMoreTries = FALSE;
2683       lsp = s_NetEntBlastBioseq(bsp, db, program, database, options, usemonitor, &noMoreTries);
2684       /*MsgSetReadTimeout(Entrez_ni, 60);*/
2685       ErrSetOpts(erract, 0);
2686       if (noMoreTries || ! ErrFetch(&err))
2687         return lsp;
2688     }
2689 
2690   ErrPost(CTX_UNKNOWN, 1, "NetEntBlastBioseq failure");
2691   return NULL;
2692 }
2693 
s_NetEntClusterAnalysis(DocUidPtr uids,Int4 numuids,DocField fld,Int4 minCluster,Int4 maxCluster,Int4 maxTerms,CharPtr * terms,Int4Ptr termTotals)2694 static Int4 s_NetEntClusterAnalysis(DocUidPtr uids, Int4 numuids, DocField fld, Int4 minCluster, Int4 maxCluster, Int4 maxTerms, CharPtr *terms, Int4Ptr termTotals)
2695 {
2696     ClusterArticlesPtr clap;
2697     ClusterRespPtr clrp;
2698     EntrezIdsPtr eip;
2699     Int4 numTerms;
2700     Int4 i;
2701     ValNodePtr vnpTerms;
2702     ValNodePtr vnpCounts;
2703     AsnTypePtr atp;
2704 
2705     clap = ClusterArticlesNew();
2706     eip = EntrezIdsNew();
2707     eip->ids = uids;
2708     eip->numid = numuids;
2709     clap->ids = eip;
2710     clap->fld = fld;
2711     clap->min_cluster = minCluster;
2712     clap->max_cluster = maxCluster;
2713     clap->max_terms = maxTerms;
2714     ClusterArticlesAsnWrite(clap, Entrez_asnout, ENTREZ_REQUEST_cluster_arts);
2715     AsnIoReset(Entrez_asnout);
2716     eip->ids = NULL; /* for clean free */
2717     ClusterArticlesFree(clap);
2718 
2719     if ( (atp = NetEntReadAsn()) == NULL)
2720       return -1;
2721     if ( (clrp = ClusterRespAsnRead(Entrez_asnin, ENTREZ_BACK_cluster_arts)) == NULL)
2722       return -1;
2723     numTerms = clrp->count;
2724 
2725     for (vnpTerms = clrp->terms, vnpCounts = clrp->term_counts, i = 0;
2726          vnpTerms != NULL && vnpCounts != NULL; i++, vnpTerms = vnpTerms->next,
2727          vnpCounts = vnpCounts->next)
2728     {
2729         terms[i] = (CharPtr) vnpTerms->data.ptrvalue;
2730         vnpTerms->data.ptrvalue = NULL; /* for clean free */
2731         termTotals[i] = (Int4) vnpCounts->data.intvalue;
2732     }
2733 
2734     ClusterRespFree(clrp);
2735     return numTerms;
2736 }
2737 
NetEntClusterAnalysis(DocUidPtr uids,Int4 numuids,DocField fld,Int4 minCluster,Int4 maxCluster,Int4 maxTerms,CharPtr * terms,Int4Ptr termTotals)2738 NLM_EXTERN Int4 LIBCALL NetEntClusterAnalysis(DocUidPtr uids, Int4 numuids, DocField fld, Int4 minCluster, Int4 maxCluster, Int4 maxTerms, CharPtr *terms, Int4Ptr termTotals)
2739 {
2740     int i;
2741     Int4 retval;
2742     short erract;
2743     ErrDesc err;
2744     /*extern void MsgSetReadTimeout PROTO((MHandPtr mh, int t));*/
2745 
2746     for (i = 0; i < ENT_SERV_RETRIES; i++)
2747     {
2748         if (i > 0)
2749         {
2750             if (! ReestablishNetEntrez())
2751                 break;
2752         }
2753 
2754         ErrGetOpts(&erract, NULL);
2755         ErrSetOpts(ERR_CONTINUE, 0);
2756         ErrFetch(&err);
2757         /*MsgSetReadTimeout(Entrez_ni, 1200);*/
2758         retval = s_NetEntClusterAnalysis(uids, numuids, fld, minCluster, maxCluster, maxTerms, terms, termTotals);
2759         /*MsgSetReadTimeout(Entrez_ni, 60);*/
2760         ErrSetOpts(erract, 0);
2761         if (! ErrFetch(&err))
2762         {
2763             return retval; /* success */
2764         }
2765     }
2766 
2767     ErrPost(CTX_UNKNOWN, 1, "NetEntClusterAnalysis failure");
2768 
2769     return -1;
2770 }
2771