NCBI C Toolkit Cross Reference

C/access/pmfapi.c


  1 /*   pmfapi.c
  2 * ===========================================================================
  3 *
  4 *                            PUBLIC DOMAIN NOTICE
  5 *            National Center for Biotechnology Information (NCBI)
  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 do not place any restriction on its use or reproduction.
 13 *  We would, however, appreciate having the NCBI and the author cited in
 14 *  any work or product based on this material
 15 *
 16 *  Although all reasonable efforts have been taken to ensure the accuracy
 17 *  and reliability of the software and data, the NLM and the U.S.
 18 *  Government do not and cannot warrant the performance or results that
 19 *  may be obtained by using this software or data. The NLM and the U.S.
 20 *  Government disclaim all warranties, express or implied, including
 21 *  warranties of performance, merchantability or fitness for any particular
 22 *  purpose.
 23 *
 24 * ===========================================================================
 25 *
 26 * File Name:  pmfapi.c
 27 *
 28 * Author:  Jonathan Kans
 29 *
 30 * Version Creation Date:   5/5/00
 31 *
 32 * $Revision: 1.105 $
 33 *
 34 * File Description: 
 35 *
 36 * Modifications:  
 37 * --------------------------------------------------------------------------
 38 *
 39 * ==========================================================================
 40 */
 41 
 42 #include <ncbi.h>
 43 #include <pmfapi.h>
 44 #include <objmedli.h>
 45 #include <objpubme.h>
 46 #include <objsset.h>
 47 #include <objmgr.h>
 48 #include <sequtil.h>
 49 #include <sqnutils.h>
 50 
 51 #ifdef OS_MAC
 52 #include <Events.h>
 53 #endif
 54 
 55 #ifdef OS_UNIX
 56 #include <sys/times.h>
 57 #include <limits.h>
 58 #endif
 59 
 60 /* ml to std code modified from original in medutil.c */
 61 
 62 static Boolean AllUpperCase (
 63   CharPtr p
 64 )
 65 
 66 {
 67   Char  ch;
 68 
 69   if (p == NULL) return FALSE;
 70   ch = *p;
 71   while (ch != '\0') {
 72     if (! IS_UPPER (ch)) return FALSE;
 73     p++;
 74     ch = *p;
 75   }
 76   return TRUE;
 77 }
 78 
 79 static void SplitMLAuthorName (
 80   CharPtr name,
 81   CharPtr last,
 82   CharPtr initials,
 83   CharPtr suffix
 84 )
 85 
 86 {
 87   CharPtr  p, p2;
 88   Int2     i;
 89   Char     sbuf [20], ibuf [20];
 90 
 91   /* Clear the ibuf field and transfer the entire name to 'last',
 92   excluding leading and trailing spaces */
 93 
 94   if (name == NULL) return;
 95 
 96   ibuf [0] = '\0';
 97   sbuf [0] = '\0';
 98   last [0] = '\0';
 99   initials [0] = '\0';
100   suffix [0] = '\0';
101   while (*name <= ' ') {
102     name++;
103     if (*name == '\0') return;
104   }
105   StringCpy( last, name );
106 
107   for (i=StringLen (last) - 1; ((i >= 0) && (last [i] <= ' ')); i--) {
108     last[i] = '\0';
109   }
110 
111   /* Strip off the last token (initials or name suffix (Jr, Sr, suffix.) */
112 
113   p = StringRChr (last, (int) ' ');
114   if (p != NULL) { /* more than just last name */
115 
116     /* Separate the token from the last name */
117 
118     p2 = p + 1;
119     while ((p > last) && (*p == ' ')) {
120       *p = '\0';
121       p--;
122     }
123 
124     /* If the last token is not all upper case, and there are more than
125     two tokens, see if the next to the last are initials (upper case) */
126 
127     if (! AllUpperCase (p2) && (p = StringRChr (last, (int) ' ' )) != NULL) {
128 
129       /* We have at least three tokens, is the next to last initials? */
130 
131       if (AllUpperCase (p + 1)) {
132 
133         /* Yes - concatenate the last two tokens as initials */
134 
135         StringCpy (ibuf, p + 1);
136         StringCpy (sbuf, p2);
137         while (p > last && (*p == ' ')) {
138           *p = '\0';
139           p--;
140         }
141       }
142     }
143     
144     if (ibuf [0] == '\0') { /* Only the last token goes in ibuf */
145       StringCpy (ibuf, p2);
146     }
147   }
148 
149   /* now add periods to ibuf and convert suffix */
150 
151   for (p = initials, p2 = ibuf; *p2 != '\0'; p2++, p++) {
152     *p = *p2;
153     if (! IS_LOWER(*(p2 + 1))) { /* watch out for foreign names */
154       p++;
155       *p = '.';
156     }
157   }
158   *p = '\0';
159 
160   if (sbuf [0]) {
161     if (StringCmp (sbuf, "1d") == 0 || StringCmp (sbuf, "1st") == 0)
162       p = StringMove (suffix, "I");
163     else if (StringCmp (sbuf, "2d") == 0 || StringCmp (sbuf, "2nd") == 0)
164       p = StringMove (suffix, "II");
165     else if (StringCmp (sbuf, "3d") == 0 || StringCmp (sbuf, "3rd") == 0)
166       p = StringMove (suffix, "III");
167     else if (StringCmp (sbuf, "4th") == 0)
168       p = StringMove (suffix, "IV");
169     else if (StringCmp (sbuf, "5th") == 0)
170       p = StringMove (suffix, "V");
171     else if (StringCmp (sbuf, "6th") == 0)
172       p = StringMove (suffix, "VI");
173     else if (StringCmp (sbuf, "Sr") == 0)
174       p = StringMove (suffix, "Sr.");
175     else if (StringCmp (sbuf, "Jr") == 0)
176       p = StringMove (suffix, "Jr.");
177     else
178       p = StringMove (suffix, sbuf);
179   }
180 }
181 
182 static ValNodePtr ConvertMLtoSTD (
183   CharPtr token
184 )
185 
186 {
187   AuthorPtr   aup;
188   CharPtr     eptr;
189   Char        last [80], initials [20], suffix [20];
190   NameStdPtr  nsp;
191   PersonIdPtr pid;
192   ValNodePtr  vnp;
193 
194   if (token == NULL) return NULL;
195   for (eptr = token + StringLen (token) - 1;
196        eptr > token && *eptr == ' ';
197        eptr--) continue;
198 
199   SplitMLAuthorName (token, last, initials, suffix);
200 
201   nsp = NameStdNew ();
202   if (nsp == NULL) return NULL;
203   nsp->names [0] = StringSave (last);
204   if (initials [0] != '\0') {
205     nsp->names[4] = StringSave (initials);
206   }
207   if (suffix[0] != '\0') {
208     nsp->names[5] = StringSave (suffix);
209   }
210   if (nsp->names[0] != NULL) {
211     pid = PersonIdNew ();
212     pid->choice = 2; /* name */
213     pid->data = nsp;
214     aup = AuthorNew ();
215     aup->name = pid;
216     vnp = ValNodeNew (NULL);
217     vnp->data.ptrvalue = (Pointer) aup;
218     return vnp;
219   }
220   return NULL;
221 }
222 
223 static void ChangeMedlineAuthorsToISO (
224   MedlineEntryPtr mep
225 )
226 
227 {
228   AuthListPtr  alp;
229   CitArtPtr    cap;
230   ValNodePtr   curr, oldnames, tmp, v;
231 
232   if (mep == NULL) return;
233   cap = mep->cit;
234   if (cap == NULL) return;
235   alp = cap->authors;
236   if (alp == NULL || alp->choice != 2) return;
237 
238   /* do not convert if too big for buffers */
239 
240   for (tmp = alp->names; tmp != NULL; tmp = tmp->next) {
241     if (StringLen ((CharPtr) tmp->data.ptrvalue) > 70) return;
242   }
243 
244   oldnames = alp->names;
245   alp->names = NULL;
246   alp->choice = 1; /* make std names */
247 
248   for (tmp = oldnames; tmp != NULL; tmp = tmp->next) {
249     curr = ConvertMLtoSTD ((CharPtr) tmp->data.ptrvalue);
250     if (alp->names == NULL) {
251       alp->names = curr;
252     } else {
253       for (v = alp->names; v->next != NULL; v = v->next) continue;
254       v->next = curr;
255     }
256   }
257 
258   ValNodeFreeData (oldnames);
259 }
260 
261 static Boolean log_query_url = FALSE;
262 static Boolean log_query_url_set = FALSE;
263 
264 NLM_EXTERN CONN PubMedFetchOpenConnection (
265   Int4 uid
266 )
267 
268 {
269   Char  query [64];
270 
271   if (uid < 1) return NULL;
272 
273   /*
274   sprintf (query, "db=PubMed&id=%ld&report=asn1&mode=text", (long) uid);
275   return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 80, "/entrez/utils/pmfetch.fcgi",
276                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
277                              eMIME_AsnText, eENCOD_None, 0);
278   */
279 
280   sprintf (query, "id=%ld", (long) uid);
281   return QUERY_OpenServiceQuery ("PubFetch", query, 30);
282 }
283 
284 static void MakeDateTimeStamp (
285   CharPtr buf
286 )
287 
288 {
289   DayTime  dt;
290 
291   if (buf == NULL) return;
292   *buf = '\0';
293 
294   if (GetDayTime (&dt)) {
295     sprintf (buf, "%2ld/%2ld/%4ld %2ld:%2ld:%2ld",
296              (long) (dt.tm_mon + 1), (long) dt.tm_mday, (long) (dt.tm_year + 1900),
297              (long) dt.tm_hour, (long) dt.tm_min, (long) dt.tm_sec);
298     if (buf [0] == ' ') {
299       buf [0] = '0';
300     }
301     if (buf [3] == ' ') {
302       buf [3] = '0';
303     }
304     if (buf [11] == ' ') {
305       buf [11] = '0';
306     }
307     if (buf [14] == ' ') {
308       buf [14] = '0';
309     }
310     if (buf [17] == ' ') {
311       buf [17] = '0';
312     }
313   }
314 }
315 
316 NLM_EXTERN CONN PubSeqFetchOpenConnection (
317   Int4 uid,
318   Int2 retcode,
319   Int4 flags
320 )
321 
322 {
323   Char     buf [32];
324   CONN     conn;
325   Char     query [64];
326 #ifdef OS_UNIX
327   CharPtr  str;
328 #endif
329 
330   if (uid < 1) return NULL;
331   if (retcode < 0 || retcode > 4) {
332     retcode = 0;
333   }
334   if (flags < 0) {
335     flags = -1;
336   }
337 
338 #ifdef PUB_SEQ_FETCH_DEBUG
339   sprintf (query, "val=%ld&save=idf&view=1&maxplex=%d&extrafeat=%ld", (long) uid, (int) retcode, (long) flags);
340   return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 80, "/entrez/viewer.fcgi",
341                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
342                              eMIME_AsnText, eENCOD_None, 0);
343 #endif
344 
345   sprintf (query, "val=%ld&maxplex=%d&extrafeat=%ld", (long) uid, (int) retcode, (long) flags);
346   conn = QUERY_OpenServiceQuery ("SeqFetch", query, 30);
347 
348 #ifdef OS_UNIX
349   if (! log_query_url_set) {
350     str = (CharPtr) getenv ("PUBSEQ_FETCH_LOG_URL");
351     if (StringDoesHaveText (str)) {
352       if (StringICmp (str, "TRUE") == 0) {
353         log_query_url = TRUE;
354       }
355     }
356     log_query_url_set = TRUE;
357   }
358 #endif
359 
360   if (conn == NULL) {
361     MakeDateTimeStamp (buf);
362     if (StringHasNoText (buf)) {
363       StringCpy (buf, "?");
364     }
365     ErrPostEx (SEV_ERROR, 0, 0, "PubSeqFetchOpenConnection failed for gi %ld, date/time %s", (long) uid, buf);
366     return conn;
367   }
368 
369 #ifdef OS_UNIX
370   if (log_query_url) {
371     str = CONN_Description (conn);
372     if (str == NULL) {
373       ErrPostEx (SEV_ERROR, 0, 0, "CONN_Description failed for gi %ld", (long) uid);
374     } else {
375       ErrPostEx (SEV_ERROR, 0, 0, "CONN_Description for gi %ld is %s", (long) uid, str);
376     }
377     MemFree (str);
378   }
379 #endif
380 
381   return conn;
382 }
383 
384 NLM_EXTERN CONN PubSeqFetchTraceOpenConnection (
385   Uint4 tid,
386   Int2 retcode,
387   Int4 flags
388 )
389 
390 {
391   Char     buf [32];
392   CONN     conn;
393   Char     query [64];
394 #ifdef OS_UNIX
395   CharPtr  str;
396 #endif
397 
398   if (tid < 1) return NULL;
399   if (retcode < 0 || retcode > 4) {
400     retcode = 0;
401   }
402   if (flags < 0) {
403     flags = -1;
404   }
405 
406 #ifdef PUB_SEQ_FETCH_DEBUG
407   sprintf (query, "val=0:TRACE:%lu&save=idf&view=1&maxplex=%d&extrafeat=%ld", (unsigned long) tid, (int) retcode, (long) flags);
408   return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 80, "/entrez/viewer.fcgi",
409                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
410                              eMIME_AsnText, eENCOD_None, 0);
411 #endif
412 
413   sprintf (query, "val=0:TRACE:%lu&maxplex=%d&extrafeat=%ld", (unsigned long) tid, (int) retcode, (long) flags);
414   conn = QUERY_OpenServiceQuery ("SeqFetch", query, 30);
415 
416 #ifdef OS_UNIX
417   if (! log_query_url_set) {
418     str = (CharPtr) getenv ("PUBSEQ_FETCH_LOG_URL");
419     if (StringDoesHaveText (str)) {
420       if (StringICmp (str, "TRUE") == 0) {
421         log_query_url = TRUE;
422       }
423     }
424     log_query_url_set = TRUE;
425   }
426 #endif
427 
428   if (conn == NULL) {
429     MakeDateTimeStamp (buf);
430     if (StringHasNoText (buf)) {
431       StringCpy (buf, "?");
432     }
433     ErrPostEx (SEV_ERROR, 0, 0, "PubSeqFetchTraceOpenConnection failed for ti %lu, date/time %s", (unsigned long) tid, buf);
434     return conn;
435   }
436 
437 #ifdef OS_UNIX
438   if (log_query_url) {
439     str = CONN_Description (conn);
440     if (str == NULL) {
441       ErrPostEx (SEV_ERROR, 0, 0, "CONN_Description failed for ti %lu", (unsigned long) tid);
442     } else {
443       ErrPostEx (SEV_ERROR, 0, 0, "CONN_Description for ti %lu is %s", (unsigned long) tid, str);
444     }
445     MemFree (str);
446   }
447 #endif
448 
449   return conn;
450 }
451 
452 NLM_EXTERN CONN PubSeqFetchSRAOpenConnection (
453   CharPtr sraid
454 )
455 
456 {
457   Char     buf [32];
458   CONN     conn;
459   Char     query [64];
460 #ifdef OS_UNIX
461   CharPtr  str;
462 #endif
463 
464   if (StringHasNoText (sraid)) return NULL;
465 
466 #ifdef PUB_SEQ_FETCH_DEBUG
467   sprintf (query, "val=gnl|SRA|%s&save=idf&view=1", sraid);
468   return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 80, "/entrez/viewer.fcgi",
469                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
470                              eMIME_AsnText, eENCOD_None, 0);
471 #endif
472 
473   /*
474   sprintf (query, "view=0&save=idf&val=gnl|SRA|%s", sraid);
475   return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 80, "/entrez/viewer.fcgi",
476                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
477                              eMIME_AsnBinary, eENCOD_None, 0);
478   */
479 
480   sprintf (query, "val=gnl|SRA|%s", sraid);
481   conn = QUERY_OpenServiceQuery ("SeqFetch", query, 30);
482 
483 #ifdef OS_UNIX
484   if (! log_query_url_set) {
485     str = (CharPtr) getenv ("PUBSEQ_FETCH_LOG_URL");
486     if (StringDoesHaveText (str)) {
487       if (StringICmp (str, "TRUE") == 0) {
488         log_query_url = TRUE;
489       }
490     }
491     log_query_url_set = TRUE;
492   }
493 #endif
494 
495   if (conn == NULL) {
496     MakeDateTimeStamp (buf);
497     if (StringHasNoText (buf)) {
498       StringCpy (buf, "?");
499     }
500     ErrPostEx (SEV_ERROR, 0, 0, "PubSeqFetchSRAOpenConnection failed for sra %s, date/time %s", sraid, buf);
501     return conn;
502   }
503 
504 #ifdef OS_UNIX
505   if (log_query_url) {
506     str = CONN_Description (conn);
507     if (str == NULL) {
508       ErrPostEx (SEV_ERROR, 0, 0, "CONN_Description failed for sra %s", sraid);
509     } else {
510       ErrPostEx (SEV_ERROR, 0, 0, "CONN_Description for sra %s is %s", sraid, str);
511     }
512     MemFree (str);
513   }
514 #endif
515 
516   return conn;
517 }
518 
519 
520 static CharPtr girevtxt = "cmd=seqid&txt=on&seqid=fasta&val=";
521 
522 NLM_EXTERN CONN GiRevHistOpenConnection (
523   Int4 uid,
524   Int4 num,
525   Int4Ptr uids
526 )
527 
528 {
529   CONN     conn;
530   Int4     i;
531   CharPtr  query;
532   Char     tmp [16];
533 
534   if (uid > 0 && uids == NULL) {
535     uids = &uid;
536     num = 1;
537   }
538   if (uids == NULL || num < 1) return NULL;
539 
540   query = (CharPtr) MemNew (11 * num + StringLen (girevtxt) + 5);
541   if (query == NULL) return NULL;
542   /*
543   StringCpy (query, girevtxt);
544   */
545   StringCpy (query, "val=");
546 
547   sprintf (tmp, "%ld", (long) uids [0]);
548   StringCat (query, tmp);
549 
550   for (i = 1; i < num; i++) {
551     sprintf (tmp, ",%ld", (long) uids [i]);
552     StringCat (query, tmp);
553   }
554 
555   /*
556   conn = QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 80, "/entrez/sutils/girevhist.cgi",
557                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
558                              eMIME_Plain, eENCOD_None, 0);
559   */
560 
561   conn = QUERY_OpenServiceQuery ("Gi2Accn", query, 30);
562 
563   MemFree (query);
564   return conn;
565 }
566 
567 static CharPtr giaccvertxt = "cmd=seqid&txt=on&seqid=15&val=";
568 
569 NLM_EXTERN CONN GiAccVerOpenConnection (
570   Int4 uid,
571   Int4 num,
572   Int4Ptr uids
573 )
574 
575 {
576   CONN     conn;
577   Int4     i;
578   CharPtr  query;
579   Char     tmp [16];
580 
581   if (uid > 0 && uids == NULL) {
582     uids = &uid;
583     num = 1;
584   }
585   if (uids == NULL || num < 1) return NULL;
586 
587   query = (CharPtr) MemNew (11 * num + StringLen (giaccvertxt) + 5);
588   if (query == NULL) return NULL;
589   /*
590   StringCpy (query, giaccvertxt);
591   */
592   StringCpy (query, "val=");
593 
594   sprintf (tmp, "%ld", (long) uids [0]);
595   StringCat (query, tmp);
596 
597   for (i = 1; i < num; i++) {
598     sprintf (tmp, ",%ld", (long) uids [i]);
599     StringCat (query, tmp);
600   }
601 
602   /*
603   conn = QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 80, "/entrez/sutils/girevhist.cgi",
604                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
605                              eMIME_Plain, eENCOD_None, 0);
606   */
607 
608   conn = QUERY_OpenServiceQuery ("Gi2AccVer", query, 30);
609 
610   MemFree (query);
611   return conn;
612 }
613 
614 NLM_EXTERN CONN AccnRevHistOpenConnection (
615   CharPtr accn
616 )
617 
618 {
619   Char  query [64];
620 
621   if (StringHasNoText (accn)) return NULL;
622   
623   /*
624   sprintf (query, "val=%s&save=idf&view=gi&maxplex=0", accn);
625   return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 80, "/entrez/viewer.fcgi",
626                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
627                              eMIME_Plain, eENCOD_None, 0);
628   */
629 
630   sprintf (query, "val=%s", accn);
631   return QUERY_OpenServiceQuery ("Accn2Gi", query, 30);
632 }
633 
634 NLM_EXTERN CONN GiSeqIdSetOpenConnection (
635   Int4 gi
636 )
637 
638 {
639   Char  query [64];
640 
641   if (gi < 1) return NULL;
642 
643   /*
644   sprintf (query, "cmd=seqid&txt=on&val=%ld&seqid=asntext&os=PUBSEQ_OS", (long) gi);
645   return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 80, "/entrez/sutils/girevhist.cgi",
646                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
647                              eMIME_Plain, eENCOD_None, 0);
648   */
649 
650   sprintf (query, "val=%ld", (long) gi);
651   return QUERY_OpenServiceQuery ("Gi2SeqIdSet", query, 30);
652 }
653 
654 static CharPtr accnlsttxt = "cmd=seqid&txt=on&seqid=fastalong&val=";
655 
656 NLM_EXTERN CONN AccnListOpenConnection (
657   CharPtr PNTR accns
658 )
659 
660 {
661   CONN     conn;
662   Int4     i;
663   size_t   len;
664   Int4     num;
665   CharPtr  query;
666   CharPtr  tmp;
667 
668   if (accns == NULL) return NULL;
669 
670   for (num = 0, len = 0; accns [num] != NULL; num++) {
671     len += StringLen (accns [num]) + 1;
672   }
673   if (num < 1) return NULL;
674 
675   query = (CharPtr) MemNew (len + StringLen (accnlsttxt) + 5);
676   if (query == NULL) return NULL;
677   tmp = query;
678 
679   /*
680   tmp = StringMove (tmp, accnlsttxt);
681   */
682   tmp = StringMove (tmp, "val=");
683 
684   tmp = StringMove (tmp, accns [0]);
685 
686   for (i = 1; accns [i] != NULL; i++) {
687     tmp = StringMove (tmp, ",");
688     tmp = StringMove (tmp, accns [i]);
689   }
690 
691   /*
692   conn = QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 80, "/entrez/sutils/girevhist.cgi",
693                              query, "Entrez2Tool", 30, eMIME_T_NcbiData,
694                              eMIME_Plain, eENCOD_None, 0);
695   */
696 
697   conn = QUERY_OpenServiceQuery ("AccnList", query, 30);
698 
699   MemFree (query);
700   return conn;
701 }
702 
703 static EIO_Status CommonWaitForReply (
704   CONN conn
705 )
706 
707 {
708   time_t           currtime, starttime;
709   time_t           max = 0;
710   EIO_Status       status;
711   STimeout         timeout;
712 #ifdef OS_MAC
713   EventRecord      currEvent;
714 #endif
715 
716   if (conn == NULL) return eIO_Unknown;
717 
718 #ifdef OS_MAC
719   timeout.sec = 0;
720   timeout.usec = 0;
721 #else
722   timeout.sec = 100;
723   timeout.usec = 0;
724 #endif
725 
726   starttime = GetSecs ();
727   while ((status = CONN_Wait (conn, eIO_Read, &timeout)) == eIO_Timeout && max < 300) {
728     currtime = GetSecs ();
729     max = currtime - starttime;
730 #ifdef OS_MAC
731     WaitNextEvent (0, &currEvent, 0, NULL);
732 #endif
733   }
734 
735   return status;
736 }
737 
738 NLM_EXTERN PubmedEntryPtr PubMedReadReply (
739   CONN conn,
740   EIO_Status status
741 )
742 
743 {
744   AsnIoConnPtr    aicp;
745   PubmedEntryPtr  pep = NULL;
746 
747   if (conn != NULL && status == eIO_Success) {
748     aicp = QUERY_AsnIoConnOpen ("r", conn);
749     pep = PubmedEntryAsnRead (aicp->aip, NULL);
750     QUERY_AsnIoConnClose (aicp);
751   }
752 
753   if (pep != NULL) {
754     ChangeMedlineAuthorsToISO ((MedlineEntryPtr) pep->medent);
755   }
756 
757   return pep;
758 }
759 
760 NLM_EXTERN PubmedEntryPtr PubMedWaitForReply (
761   CONN conn
762 )
763 
764 {
765   PubmedEntryPtr  pep = NULL;
766 
767   if (conn == NULL) return NULL;
768 
769   if (CommonWaitForReply (conn) == eIO_Success) {
770     pep = PubMedReadReply (conn, eIO_Success);
771   }
772   CONN_Close (conn);
773 
774   return pep;
775 }
776 
777 #define PUB_SEQ_DEBUG_TEMP_FILE "pubseqfetchtempfile"
778 
779 NLM_EXTERN SeqEntryPtr PubSeqReadReply (
780   CONN conn,
781   EIO_Status status
782 )
783 
784 {
785   AsnIoConnPtr  aicp;
786   ErrSev        oldsev;
787   SeqEntryPtr   sep = NULL;
788 #ifdef PUB_SEQ_FETCH_DEBUG
789   AsnIoPtr      aip;
790   FILE          *fp;
791 #endif
792 
793   if (conn != NULL && status == eIO_Success) {
794 #ifdef PUB_SEQ_FETCH_DEBUG
795     fp = FileOpen (PUB_SEQ_DEBUG_TEMP_FILE, "w");
796     QUERY_CopyResultsToFile (conn, fp);
797     FileClose (fp);
798     aip = AsnIoOpen (PUB_SEQ_DEBUG_TEMP_FILE, "r");
799     sep = SeqEntryAsnRead (aip, NULL);
800     AsnIoClose (aip);
801     if (sep != NULL) {
802       FileRemove (PUB_SEQ_DEBUG_TEMP_FILE);
803     }
804 #else
805     oldsev = ErrSetMessageLevel (SEV_MAX);
806     aicp = QUERY_AsnIoConnOpen ("rb", conn);
807     sep = SeqEntryAsnRead (aicp->aip, NULL);
808     QUERY_AsnIoConnClose (aicp);
809     ErrSetMessageLevel (oldsev);
810 #endif
811   }
812   return sep;
813 }
814 
815 NLM_EXTERN SeqEntryPtr PubSeqWaitForReply (
816   CONN conn
817 )
818 
819 {
820   SeqEntryPtr  sep = NULL;
821   EIO_Status   status;
822 #ifdef OS_UNIX
823   CharPtr      str;
824 #endif
825 
826   if (conn == NULL) return NULL;
827 
828 #ifdef OS_UNIX
829   if (! log_query_url_set) {
830     str = (CharPtr) getenv ("PUBSEQ_FETCH_LOG_URL");
831     if (StringDoesHaveText (str)) {
832       if (StringICmp (str, "TRUE") == 0) {
833         log_query_url = TRUE;
834       }
835     }
836     log_query_url_set = TRUE;
837   }
838 #endif
839 
840   status = CommonWaitForReply (conn);
841   if (status == eIO_Success) {
842     sep = PubSeqReadReply (conn, eIO_Success);
843 #ifdef OS_UNIX
844     /*
845     if (sep == NULL) {
846       ErrPostEx (SEV_ERROR, 0, 0, "PubSeqWaitForReply unable to read valid result");
847     }
848     */
849   } else {
850     ErrPostEx (SEV_ERROR, 0, 0, "PubSeqWaitForReply failed with status %d", (int) status);
851 #endif
852   }
853   CONN_Close (conn);
854 
855   return sep;
856 }
857 
858 NLM_EXTERN CharPtr GiRevHistReadReply (
859   CONN conn,
860   EIO_Status status
861 )
862 
863 {
864   AsnIoConnPtr  aicp;
865   ByteStorePtr  bsp;
866   Char          buf [512];
867   size_t        n_read;
868   CharPtr       str = NULL;
869 
870   if (conn != NULL && status == eIO_Success) {
871     bsp = BSNew (512);
872     aicp = QUERY_AsnIoConnOpen ("r", conn);
873     while ((status = CONN_Read (aicp->conn, (Pointer) buf, sizeof (buf), &n_read, eIO_ReadPlain)) == eIO_Success) {
874       BSWrite (bsp, buf, n_read);
875     }
876     str = BSMerge (bsp, NULL);
877     BSFree (bsp);
878     QUERY_AsnIoConnClose (aicp);
879   }
880   return str;
881 }
882 
883 NLM_EXTERN CharPtr GiRevHistWaitForReply (
884   CONN conn
885 )
886 
887 {
888   CharPtr  str = NULL;
889 
890   if (conn == NULL) return NULL;
891 
892   if (CommonWaitForReply (conn) == eIO_Success) {
893     str = GiRevHistReadReply (conn, eIO_Success);
894   }
895   CONN_Close (conn);
896 
897   return str;
898 }
899 
900 NLM_EXTERN CharPtr GiAccVerReadReply (
901   CONN conn,
902   EIO_Status status
903 )
904 
905 {
906   AsnIoConnPtr  aicp;
907   ByteStorePtr  bsp;
908   Char          buf [512];
909   size_t        n_read;
910   CharPtr       str = NULL;
911 
912   if (conn != NULL && status == eIO_Success) {
913     bsp = BSNew (512);
914     aicp = QUERY_AsnIoConnOpen ("r", conn);
915     while ((status = CONN_Read (aicp->conn, (Pointer) buf, sizeof (buf), &n_read, eIO_ReadPlain)) == eIO_Success) {
916       BSWrite (bsp, buf, n_read);
917     }
918     str = BSMerge (bsp, NULL);
919     BSFree (bsp);
920     QUERY_AsnIoConnClose (aicp);
921   }
922   return str;
923 }
924 
925 NLM_EXTERN CharPtr GiAccVerWaitForReply (
926   CONN conn
927 )
928 
929 {
930   CharPtr  str = NULL;
931 
932   if (conn == NULL) return NULL;
933 
934   if (CommonWaitForReply (conn) == eIO_Success) {
935     str = GiAccVerReadReply (conn, eIO_Success);
936   }
937   CONN_Close (conn);
938 
939   return str;
940 }
941 
942 NLM_EXTERN Int4 AccnRevHistReadReply (
943   CONN conn,
944   EIO_Status status
945 )
946 
947 {
948   AsnIoConnPtr  aicp;
949   Char          buf [32];
950   Char          ch;
951   Int4          gi = 0;
952   size_t        n_read;
953   CharPtr       ptr;
954   long int      val;
955 
956   if (conn != NULL && status == eIO_Success) {
957     aicp = QUERY_AsnIoConnOpen ("r", conn);
958     status = CONN_Read (aicp->conn, (Pointer) buf, sizeof (buf), &n_read, eIO_ReadPlain);
959     if (status == eIO_Success) {
960       ptr = buf;
961       ch = *ptr;
962       while (ch != '\0' && ch != '\n' && ch != '\r') {
963          ptr++;
964          ch = *ptr;
965       }
966       *ptr = '\0';
967       if (sscanf (buf, "%ld", &val) == 1 && val > 0) {
968         gi = val;
969       }
970     }
971     QUERY_AsnIoConnClose (aicp);
972   }
973   return gi;
974 }
975 
976 NLM_EXTERN Int4 AccnRevHistWaitForReply (
977   CONN conn
978 )
979 
980 {
981   Int4  gi = 0;
982 
983   if (conn == NULL) return 0;
984 
985   if (CommonWaitForReply (conn) == eIO_Success) {
986     gi = AccnRevHistReadReply (conn, eIO_Success);
987   }
988   CONN_Close (conn);
989 
990   return gi;
991 }
992 
993 NLM_EXTERN SeqIdPtr GiSeqIdSetReadReply (
994   CONN conn,
995   EIO_Status status
996 )
997 
998 {
999   AsnIoConnPtr  aicp;
1000   SeqIdPtr      last = NULL;
1001   ErrSev        sev;
1002   SeqIdPtr      sid;
1003   SeqIdPtr      sip = NULL;
1004 
1005   if (conn != NULL && status == eIO_Success) {
1006     aicp = QUERY_AsnIoConnOpen ("r", conn);
1007     sev = ErrSetLogLevel (SEV_WARNING);
1008     while ((sid = SeqIdAsnRead (aicp->aip, NULL)) != NULL) {
1009       if (sip == NULL) {
1010         sip = sid;
1011       } else if (last != NULL) {
1012         last->next = sid;
1013       }
1014       last = sid;
1015     }
1016     ErrSetLogLevel (sev);
1017     QUERY_AsnIoConnClose (aicp);
1018   }
1019   return sip;
1020 }
1021 
1022 NLM_EXTERN SeqIdPtr GiSeqIdSetWaitForReply (
1023   CONN conn
1024 )
1025 
1026 {
1027   SeqIdPtr  sip = NULL;
1028 
1029   if (conn == NULL) return NULL;
1030 
1031   if (CommonWaitForReply (conn) == eIO_Success) {
1032     sip = GiSeqIdSetReadReply (conn, eIO_Success);
1033   }
1034   CONN_Close (conn);
1035 
1036   return sip;
1037 }
1038 
1039 NLM_EXTERN CharPtr AccnListReadReply (
1040   CONN conn,
1041   EIO_Status status
1042 )
1043 
1044 {
1045   AsnIoConnPtr  aicp;
1046   ByteStorePtr  bsp;
1047   Char          buf [512];
1048   size_t        n_read;
1049   CharPtr       str = NULL;
1050 
1051   if (conn != NULL && status == eIO_Success) {
1052     bsp = BSNew (512);
1053     aicp = QUERY_AsnIoConnOpen ("r", conn);
1054     while ((status = CONN_Read (aicp->conn, (Pointer) buf, sizeof (buf), &n_read, eIO_ReadPlain)) == eIO_Success) {
1055       BSWrite (bsp, buf, n_read);
1056     }
1057     str = BSMerge (bsp, NULL);
1058     BSFree (bsp);
1059     QUERY_AsnIoConnClose (aicp);
1060   }
1061   return str;
1062 }
1063 
1064 NLM_EXTERN CharPtr AccnListWaitForReply (
1065   CONN conn
1066 )
1067 
1068 {
1069   CharPtr  str = NULL;
1070 
1071   if (conn == NULL) return NULL;
1072 
1073   if (CommonWaitForReply (conn) == eIO_Success) {
1074     str = AccnListReadReply (conn, eIO_Success);
1075   }
1076   CONN_Close (conn);
1077 
1078   return str;
1079 }
1080 
1081 static Boolean log_sync_query_times = FALSE;
1082 static Boolean log_sync_query_set = FALSE;
1083 
1084 NLM_EXTERN PubmedEntryPtr PubMedSynchronousQuery (
1085   Int4 uid
1086 )
1087 
1088 {
1089   CONN            conn;
1090   PubmedEntryPtr  pep;
1091 #ifdef OS_UNIX
1092   clock_t         starttime;
1093   clock_t         stoptime;
1094   CharPtr         str;
1095   struct tms      timebuf;
1096 #endif
1097 
1098   if (uid < 1) return NULL;
1099 
1100 #ifdef OS_UNIX
1101   if (! log_sync_query_set) {
1102     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1103     if (StringDoesHaveText (str)) {
1104       if (StringICmp (str, "TRUE") == 0) {
1105         log_sync_query_times = TRUE;
1106       }
1107     }
1108     log_sync_query_set = TRUE;
1109   }
1110 #endif
1111 
1112   conn = PubMedFetchOpenConnection (uid);
1113 
1114   if (conn == NULL) return NULL;
1115 
1116   QUERY_SendQuery (conn);
1117 
1118 #ifdef OS_UNIX
1119   if (log_sync_query_times) {
1120     starttime = times (&timebuf);
1121   }
1122 #endif
1123 
1124   pep = PubMedWaitForReply (conn);
1125 
1126 #ifdef OS_UNIX
1127   if (log_sync_query_times) {
1128     stoptime = times (&timebuf);
1129     printf ("PubMedWaitForReply %ld\n", (long) (stoptime - starttime));
1130   }
1131 #endif
1132 
1133   return pep;
1134 }
1135 
1136 typedef struct psconfirm {
1137   Int4     uid;
1138   Uint4    tid;
1139   CharPtr  sid;
1140   Int4     gi;
1141   Uint4    ti;
1142   CharPtr  si;
1143 } PsConfirm, PNTR PsConfirmPtr;
1144 
1145 static void ConfirmGiInSep (
1146   BioseqPtr bsp,
1147   Pointer userdata
1148 )
1149 
1150 {
1151   Int4          gi;
1152   PsConfirmPtr  psp;
1153   SeqIdPtr      sip;
1154 
1155   if (bsp == NULL || userdata == NULL) return;
1156   psp = (PsConfirmPtr) userdata;
1157   for (sip = bsp->id; sip != NULL; sip = sip->next) {
1158     if (sip->choice != SEQID_GI) continue;
1159     gi = (Int4) sip->data.intvalue;
1160     if (psp->gi == 0 || gi == psp->uid) {
1161       psp->gi = gi;
1162     }
1163   }
1164 }
1165 
1166 
1167 static void ConfirmTiInSep (
1168   BioseqPtr bsp,
1169   Pointer userdata
1170 )
1171 
1172 {
1173   Uint4          ti;
1174   PsConfirmPtr  psp;
1175   SeqIdPtr      sip;
1176   DbtagPtr      dbtag;
1177 
1178   if (bsp == NULL || userdata == NULL) return;
1179   psp = (PsConfirmPtr) userdata;
1180   for (sip = bsp->id; sip != NULL; sip = sip->next) {
1181     if (sip->choice != SEQID_GENERAL) continue;
1182     dbtag = (DbtagPtr) sip->data.ptrvalue;
1183     if (dbtag == NULL || StringCmp (dbtag->db, "ti") != 0 || dbtag->tag == NULL) continue;
1184     if (dbtag->tag->str == NULL && (Uint4) dbtag->tag->id > 0) {
1185       ti = (Uint4) dbtag->tag->id;
1186       if (psp->ti == 0 || ti == psp->tid) {
1187         psp->ti = ti;
1188       }
1189     }
1190   }
1191 }
1192 
1193 static void ConfirmSraidInSep (
1194   BioseqPtr bsp,
1195   Pointer userdata
1196 )
1197 
1198 {
1199   PsConfirmPtr  psp;
1200   SeqIdPtr      sip;
1201   CharPtr       sraid;
1202   DbtagPtr      dbtag;
1203 
1204   if (bsp == NULL || userdata == NULL) return;
1205   psp = (PsConfirmPtr) userdata;
1206   for (sip = bsp->id; sip != NULL; sip = sip->next) {
1207     if (sip->choice != SEQID_GENERAL) continue;
1208     dbtag = (DbtagPtr) sip->data.ptrvalue;
1209     if (dbtag == NULL || StringCmp (dbtag->db, "SRA") != 0 || dbtag->tag == NULL) continue;
1210     if (dbtag->tag->str != NULL) {
1211       sraid = dbtag->tag->str;
1212       if (psp->si == NULL || StringCmp (sraid, psp->si) == 0) {
1213         psp->si = sraid;
1214       }
1215     }
1216   }
1217 }
1218 
1219 NLM_EXTERN SeqEntryPtr PubSeqSynchronousQuery (
1220   Int4 uid,
1221   Int2 retcode,
1222   Int4 flags
1223 )
1224 
1225 {
1226   Char         buf [32];
1227   CONN         conn;
1228   PsConfirm    ps;
1229   SeqEntryPtr  sep;
1230   CharPtr      str = NULL;
1231 #ifdef OS_UNIX
1232   clock_t      starttime;
1233   clock_t      stoptime;
1234   struct tms   timebuf;
1235 #endif
1236 
1237   if (uid < 1) return NULL;
1238 
1239 #ifdef OS_UNIX
1240   if (! log_sync_query_set) {
1241     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1242     if (StringDoesHaveText (str)) {
1243       if (StringICmp (str, "TRUE") == 0) {
1244         log_sync_query_times = TRUE;
1245       }
1246     }
1247     log_sync_query_set = TRUE;
1248   }
1249 #endif
1250 
1251   conn = PubSeqFetchOpenConnection (uid, retcode, flags);
1252 
1253   if (conn == NULL) return NULL;
1254 
1255   QUERY_SendQuery (conn);
1256 
1257 #ifdef OS_UNIX
1258   if (log_sync_query_times) {
1259     starttime = times (&timebuf);
1260   }
1261 #endif
1262 
1263   str = CONN_Description (conn);
1264   if (StringHasNoText (str)) {
1265     str = StringSave ("?");
1266   }
1267 
1268   sep = PubSeqWaitForReply (conn);
1269 
1270 #ifdef OS_UNIX
1271   if (log_sync_query_times) {
1272     stoptime = times (&timebuf);
1273     printf ("PubSeqWaitForReply %ld\n", (long) (stoptime - starttime));
1274   }
1275 #endif
1276 
1277   if (sep != NULL) {
1278     ps.uid = uid;
1279     ps.tid = 0;
1280     ps.sid = NULL;
1281     ps.gi = 0;
1282     ps.ti = 0;
1283     ps.si = NULL;
1284     VisitBioseqsInSep (sep, (Pointer) &ps, ConfirmGiInSep);
1285     if (ps.gi != uid) {
1286       ErrPostEx (SEV_ERROR, 0, 0,
1287                  "PubSeqSynchronousQuery requested gi %ld but received gi %ld",
1288                  (long) uid, (long) ps.gi);
1289     }
1290   } else {
1291     MakeDateTimeStamp (buf);
1292     if (StringHasNoText (buf)) {
1293       StringCpy (buf, "?");
1294     }
1295     ErrPostEx (SEV_ERROR, 0, 0,
1296                "PubSeqSynchronousQuery failed for gi %ld, date/time %s, URL is %s",
1297                (long) uid, buf, str);
1298   }
1299 
1300   MemFree (str);
1301 
1302   return sep;
1303 }
1304 
1305 
1306 NLM_EXTERN SeqEntryPtr PubSeqSynchronousQueryTI (
1307   Uint4 tid,
1308   Int2 retcode,
1309   Int4 flags
1310 )
1311 
1312 {
1313   Char         buf [32];
1314   CONN         conn;
1315   PsConfirm    ps;
1316   SeqEntryPtr  sep;
1317   CharPtr      str = NULL;
1318 #ifdef OS_UNIX
1319   clock_t      starttime;
1320   clock_t      stoptime;
1321   struct tms   timebuf;
1322 #endif
1323 
1324   if (tid < 1) return NULL;
1325 
1326 #ifdef OS_UNIX
1327   if (! log_sync_query_set) {
1328     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1329     if (StringDoesHaveText (str)) {
1330       if (StringICmp (str, "TRUE") == 0) {
1331         log_sync_query_times = TRUE;
1332       }
1333     }
1334     log_sync_query_set = TRUE;
1335   }
1336 #endif
1337 
1338   conn = PubSeqFetchTraceOpenConnection (tid, retcode, flags);
1339 
1340   if (conn == NULL) return NULL;
1341 
1342   QUERY_SendQuery (conn);
1343 
1344 #ifdef OS_UNIX
1345   if (log_sync_query_times) {
1346     starttime = times (&timebuf);
1347   }
1348 #endif
1349 
1350   str = CONN_Description (conn);
1351   if (StringHasNoText (str)) {
1352     str = StringSave ("?");
1353   }
1354 
1355   sep = PubSeqWaitForReply (conn);
1356 
1357 #ifdef OS_UNIX
1358   if (log_sync_query_times) {
1359     stoptime = times (&timebuf);
1360     printf ("PubSeqWaitForReply %ld\n", (long) (stoptime - starttime));
1361   }
1362 #endif
1363 
1364   if (sep != NULL) {
1365     ps.uid = 0;
1366     ps.tid = tid;
1367     ps.sid = NULL;
1368     ps.gi = 0;
1369     ps.ti = 0;
1370     ps.si = NULL;
1371     VisitBioseqsInSep (sep, (Pointer) &ps, ConfirmTiInSep);
1372     if (ps.ti != tid) {
1373       ErrPostEx (SEV_ERROR, 0, 0,
1374                  "PubSeqSynchronousQueryTI requested ti %lu but received ti %lu",
1375                  (long) tid, (long) ps.ti);
1376     }
1377   } else {
1378     MakeDateTimeStamp (buf);
1379     if (StringHasNoText (buf)) {
1380       StringCpy (buf, "?");
1381     }
1382     ErrPostEx (SEV_ERROR, 0, 0,
1383                "PubSeqSynchronousQueryTI failed for ti %lu, date/time %s, URL is %s",
1384                (long) tid, buf, str);
1385   }
1386 
1387   MemFree (str);
1388 
1389   return sep;
1390 }
1391 
1392 NLM_EXTERN SeqEntryPtr PubSeqSynchronousQuerySRA (
1393   CharPtr sraid
1394 )
1395 
1396 {
1397   Char         buf [32];
1398   CONN         conn;
1399   PsConfirm    ps;
1400   SeqEntryPtr  sep;
1401   CharPtr      str = NULL;
1402 #ifdef OS_UNIX
1403   clock_t      starttime;
1404   clock_t      stoptime;
1405   struct tms   timebuf;
1406 #endif
1407 
1408   if (StringHasNoText (sraid)) return NULL;
1409 
1410 #ifdef OS_UNIX
1411   if (! log_sync_query_set) {
1412     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1413     if (StringDoesHaveText (str)) {
1414       if (StringICmp (str, "TRUE") == 0) {
1415         log_sync_query_times = TRUE;
1416       }
1417     }
1418     log_sync_query_set = TRUE;
1419   }
1420 #endif
1421 
1422   conn = PubSeqFetchSRAOpenConnection (sraid);
1423 
1424   if (conn == NULL) return NULL;
1425 
1426   QUERY_SendQuery (conn);
1427 
1428 #ifdef OS_UNIX
1429   if (log_sync_query_times) {
1430     starttime = times (&timebuf);
1431   }
1432 #endif
1433 
1434   str = CONN_Description (conn);
1435   if (StringHasNoText (str)) {
1436     str = StringSave ("?");
1437   }
1438 
1439   sep = PubSeqWaitForReply (conn);
1440 
1441 #ifdef OS_UNIX
1442   if (log_sync_query_times) {
1443     stoptime = times (&timebuf);
1444     printf ("PubSeqWaitForReply %ld\n", (long) (stoptime - starttime));
1445   }
1446 #endif
1447 
1448   if (sep != NULL) {
1449     ps.uid = 0;
1450     ps.tid = 0;
1451     ps.sid = sraid;
1452     ps.gi = 0;
1453     ps.ti = 0;
1454     ps.si = NULL;
1455     VisitBioseqsInSep (sep, (Pointer) &ps, ConfirmSraidInSep);
1456     if (StringCmp (ps.si, sraid) != 0) {
1457       ErrPostEx (SEV_ERROR, 0, 0,
1458                  "PubSeqSynchronousQuerySRA requested sra %s but received sra %s",
1459                  sraid, ps.si);
1460     }
1461   } else {
1462     MakeDateTimeStamp (buf);
1463     if (StringHasNoText (buf)) {
1464       StringCpy (buf, "?");
1465     }
1466     ErrPostEx (SEV_ERROR, 0, 0,
1467                "PubSeqSynchronousQuerySRA failed for sra %s, date/time %s, URL is %s",
1468                sraid, buf, str);
1469   }
1470 
1471   MemFree (str);
1472 
1473   return sep;
1474 }
1475 
1476 NLM_EXTERN CharPtr GiRevHistSynchronousQuery (
1477   Int4 uid,
1478   Int4 num,
1479   Int4Ptr uids
1480 )
1481 
1482 {
1483   CONN        conn;
1484   CharPtr     str;
1485 #ifdef OS_UNIX
1486   clock_t     starttime;
1487   clock_t     stoptime;
1488   struct tms  timebuf;
1489 #endif
1490 
1491 #ifdef OS_UNIX
1492   if (! log_sync_query_set) {
1493     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1494     if (StringDoesHaveText (str)) {
1495       if (StringICmp (str, "TRUE") == 0) {
1496         log_sync_query_times = TRUE;
1497       }
1498     }
1499     log_sync_query_set = TRUE;
1500   }
1501 #endif
1502 
1503   conn = GiRevHistOpenConnection (uid, num, uids);
1504 
1505   if (conn == NULL) return NULL;
1506 
1507   QUERY_SendQuery (conn);
1508 
1509 #ifdef OS_UNIX
1510   if (log_sync_query_times) {
1511     starttime = times (&timebuf);
1512   }
1513 #endif
1514 
1515   str = GiRevHistWaitForReply (conn);
1516 
1517 #ifdef OS_UNIX
1518   if (log_sync_query_times) {
1519     stoptime = times (&timebuf);
1520     printf ("GiRevHistWaitForReply %ld\n", (long) (stoptime - starttime));
1521   }
1522 #endif
1523 
1524   return str;
1525 }
1526 
1527 NLM_EXTERN CharPtr GiAccVerSynchronousQuery (
1528   Int4 uid,
1529   Int4 num,
1530   Int4Ptr uids
1531 )
1532 
1533 {
1534   CONN        conn;
1535   CharPtr     str;
1536 #ifdef OS_UNIX
1537   clock_t     starttime;
1538   clock_t     stoptime;
1539   struct tms  timebuf;
1540 #endif
1541 
1542 #ifdef OS_UNIX
1543   if (! log_sync_query_set) {
1544     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1545     if (StringDoesHaveText (str)) {
1546       if (StringICmp (str, "TRUE") == 0) {
1547         log_sync_query_times = TRUE;
1548       }
1549     }
1550     log_sync_query_set = TRUE;
1551   }
1552 #endif
1553 
1554   conn = GiAccVerOpenConnection (uid, num, uids);
1555 
1556   if (conn == NULL) return NULL;
1557 
1558   QUERY_SendQuery (conn);
1559 
1560 #ifdef OS_UNIX
1561   if (log_sync_query_times) {
1562     starttime = times (&timebuf);
1563   }
1564 #endif
1565 
1566   str = GiAccVerWaitForReply (conn);
1567 
1568 #ifdef OS_UNIX
1569   if (log_sync_query_times) {
1570     stoptime = times (&timebuf);
1571     printf ("GiAccVerWaitForReply %ld\n", (long) (stoptime - starttime));
1572   }
1573 #endif
1574 
1575   return str;
1576 }
1577 
1578 NLM_EXTERN Int4 AccnRevHistSynchronousQuery (
1579   CharPtr accn
1580 )
1581 
1582 {
1583   CONN        conn;
1584   Int4        gi;
1585 #ifdef OS_UNIX
1586   clock_t     starttime;
1587   clock_t     stoptime;
1588   CharPtr     str;
1589   struct tms  timebuf;
1590 #endif
1591 
1592 #ifdef OS_UNIX
1593   if (! log_sync_query_set) {
1594     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1595     if (StringDoesHaveText (str)) {
1596       if (StringICmp (str, "TRUE") == 0) {
1597         log_sync_query_times = TRUE;
1598       }
1599     }
1600     log_sync_query_set = TRUE;
1601   }
1602 #endif
1603 
1604   conn = AccnRevHistOpenConnection (accn);
1605 
1606   if (conn == NULL) return 0;
1607 
1608   QUERY_SendQuery (conn);
1609 
1610 #ifdef OS_UNIX
1611   if (log_sync_query_times) {
1612     starttime = times (&timebuf);
1613   }
1614 #endif
1615 
1616   gi = AccnRevHistWaitForReply (conn);
1617 
1618 #ifdef OS_UNIX
1619   if (log_sync_query_times) {
1620     stoptime = times (&timebuf);
1621     printf ("AccnRevHistWaitForReply %ld\n", (long) (stoptime - starttime));
1622   }
1623 #endif
1624 
1625   return gi;
1626 }
1627 
1628 NLM_EXTERN SeqIdPtr GiSeqIdSetSynchronousQuery (
1629   Int4 gi
1630 )
1631 
1632 {
1633   CONN        conn;
1634   SeqIdPtr    sip;
1635 #ifdef OS_UNIX
1636   clock_t     starttime;
1637   clock_t     stoptime;
1638   CharPtr     str;
1639   struct tms  timebuf;
1640 #endif
1641 
1642 #ifdef OS_UNIX
1643   if (! log_sync_query_set) {
1644     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1645     if (StringDoesHaveText (str)) {
1646       if (StringICmp (str, "TRUE") == 0) {
1647         log_sync_query_times = TRUE;
1648       }
1649     }
1650     log_sync_query_set = TRUE;
1651   }
1652 #endif
1653 
1654   conn = GiSeqIdSetOpenConnection (gi);
1655 
1656   if (conn == NULL) return NULL;
1657 
1658   QUERY_SendQuery (conn);
1659 
1660 #ifdef OS_UNIX
1661   if (log_sync_query_times) {
1662     starttime = times (&timebuf);
1663   }
1664 #endif
1665 
1666   sip = GiSeqIdSetWaitForReply (conn);
1667 
1668 #ifdef OS_UNIX
1669   if (log_sync_query_times) {
1670     stoptime = times (&timebuf);
1671     printf ("GiSeqIdSetWaitForReply %ld\n", (long) (stoptime - starttime));
1672   }
1673 #endif
1674 
1675   return sip;
1676 }
1677 
1678 NLM_EXTERN CharPtr AccnListSynchronousQuery (
1679   CharPtr PNTR accns
1680 )
1681 
1682 {
1683   CONN        conn;
1684   CharPtr     str;
1685 #ifdef OS_UNIX
1686   clock_t     starttime;
1687   clock_t     stoptime;
1688   struct tms  timebuf;
1689 #endif
1690 
1691 #ifdef OS_UNIX
1692   if (! log_sync_query_set) {
1693     str = (CharPtr) getenv ("NCBI_LOG_SYNC_QUERY_TIMES");
1694     if (StringDoesHaveText (str)) {
1695       if (StringICmp (str, "TRUE") == 0) {
1696         log_sync_query_times = TRUE;
1697       }
1698     }
1699     log_sync_query_set = TRUE;
1700   }
1701 #endif
1702 
1703   conn = AccnListOpenConnection (accns);
1704 
1705   if (conn == NULL) return NULL;
1706 
1707   QUERY_SendQuery (conn);
1708 
1709 #ifdef OS_UNIX
1710   if (log_sync_query_times) {
1711     starttime = times (&timebuf);
1712   }
1713 #endif
1714 
1715   str = AccnListWaitForReply (conn);
1716 
1717 #ifdef OS_UNIX
1718   if (log_sync_query_times) {
1719     stoptime = times (&timebuf);
1720     printf ("AccnListWaitForReply %ld\n", (long) (stoptime - starttime));
1721   }
1722 #endif
1723 
1724   return str;
1725 }
1726 
1727 NLM_EXTERN Boolean PubMedAsynchronousQuery (
1728   Int4 uid,
1729   QUEUE* queue,
1730   QueryResultProc resultproc,
1731   VoidPtr userdata
1732 )
1733 
1734 {
1735   CONN  conn;
1736 
1737   conn = PubMedFetchOpenConnection (uid);
1738 
1739   if (conn == NULL) return FALSE;
1740 
1741   QUERY_SendQuery (conn);
1742 
1743   QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
1744 
1745   return TRUE;
1746 }
1747 
1748 NLM_EXTERN Int4 PubMedCheckQueue (
1749   QUEUE* queue
1750 )
1751 
1752 {
1753   return QUERY_CheckQueue (queue);
1754 }
1755 
1756 NLM_EXTERN Boolean PubSeqAsynchronousQuery (
1757   Int4 uid,
1758   Int2 retcode,
1759   Int4 flags,
1760   QUEUE* queue,
1761   QueryResultProc resultproc,
1762   VoidPtr userdata
1763 )
1764 
1765 {
1766   CONN  conn;
1767 
1768   conn = PubSeqFetchOpenConnection (uid, retcode, flags);
1769 
1770   if (conn == NULL) return FALSE;
1771 
1772   QUERY_SendQuery (conn);
1773 
1774   QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
1775 
1776   return TRUE;
1777 }
1778 
1779 NLM_EXTERN Int4 PubSeqCheckQueue (
1780   QUEUE* queue
1781 )
1782 
1783 {
1784   return QUERY_CheckQueue (queue);
1785 }
1786 
1787 NLM_EXTERN Boolean GiRevHistAsynchronousQuery (
1788   Int4 uid,
1789   Int4 num,
1790   Int4Ptr uids,
1791   QUEUE* queue,
1792   QueryResultProc resultproc,
1793   VoidPtr userdata
1794 )
1795 
1796 {
1797   CONN  conn;
1798 
1799   conn = GiRevHistOpenConnection (uid, num, uids);
1800 
1801   if (conn == NULL) return FALSE;
1802 
1803   QUERY_SendQuery (conn);
1804 
1805   QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
1806 
1807   return TRUE;
1808 }
1809 
1810 NLM_EXTERN Int4 GiRevHistCheckQueue (
1811   QUEUE* queue
1812 )
1813 
1814 {
1815   return QUERY_CheckQueue (queue);
1816 }
1817 
1818 NLM_EXTERN Boolean GiAccVerAsynchronousQuery (
1819   Int4 uid,
1820   Int4 num,
1821   Int4Ptr uids,
1822   QUEUE* queue,
1823   QueryResultProc resultproc,
1824   VoidPtr userdata
1825 )
1826 
1827 {
1828   CONN  conn;
1829 
1830   conn = GiAccVerOpenConnection (uid, num, uids);
1831 
1832   if (conn == NULL) return FALSE;
1833 
1834   QUERY_SendQuery (conn);
1835 
1836   QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
1837 
1838   return TRUE;
1839 }
1840 
1841 NLM_EXTERN Int4 GiAccVerCheckQueue (
1842   QUEUE* queue
1843 )
1844 
1845 {
1846   return QUERY_CheckQueue (queue);
1847 }
1848 
1849 NLM_EXTERN Boolean AccnRevHistAsynchronousQuery (
1850   CharPtr accn,
1851   QUEUE* queue,
1852   QueryResultProc resultproc,
1853   VoidPtr userdata
1854 )
1855 
1856 {
1857   CONN  conn;
1858 
1859   conn = AccnRevHistOpenConnection (accn);
1860 
1861   if (conn == NULL) return FALSE;
1862 
1863   QUERY_SendQuery (conn);
1864 
1865   QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
1866 
1867   return TRUE;
1868 }
1869 
1870 NLM_EXTERN Int4 AccnRevHistCheckQueue (
1871   QUEUE* queue
1872 )
1873 
1874 {
1875   return QUERY_CheckQueue (queue);
1876 }
1877 
1878 NLM_EXTERN Boolean GiSeqIdSetAsynchronousQuery (
1879   Int4 gi,
1880   QUEUE* queue,
1881   QueryResultProc resultproc,
1882   VoidPtr userdata
1883 )
1884 
1885 {
1886   CONN  conn;
1887 
1888   conn = GiSeqIdSetOpenConnection (gi);
1889 
1890   if (conn == NULL) return FALSE;
1891 
1892   QUERY_SendQuery (conn);
1893 
1894   QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
1895 
1896   return TRUE;
1897 }
1898 
1899 NLM_EXTERN Int4 GiSeqIdSetCheckQueue (
1900   QUEUE* queue
1901 )
1902 
1903 {
1904   return QUERY_CheckQueue (queue);
1905 }
1906 
1907 NLM_EXTERN Boolean AccnListAsynchronousQuery (
1908   CharPtr PNTR accns,
1909   QUEUE* queue,
1910   QueryResultProc resultproc,
1911   VoidPtr userdata
1912 )
1913 
1914 {
1915   CONN  conn;
1916 
1917   conn = AccnListOpenConnection (accns);
1918 
1919   if (conn == NULL) return FALSE;
1920 
1921   QUERY_SendQuery (conn);
1922 
1923   QUERY_AddToQueue (queue, conn, resultproc, userdata, TRUE);
1924 
1925   return TRUE;
1926 }
1927 
1928 NLM_EXTERN Int4 AccnListCheckQueue (
1929   QUEUE* queue
1930 )
1931 
1932 {
1933   return QUERY_CheckQueue (queue);
1934 }
1935 
1936 /* object manager registerable fetch functions */
1937 
1938 static CharPtr pubseqfetchproc = "PubSeqBioseqFetch";
1939 static CharPtr tracefetchproc = "TraceBioseqFetch";
1940 static CharPtr srafetchproc = "SRABioseqFetch";
1941 static CharPtr pubseqseqidtogi = "PubSeqSeqIdForGi";
1942 static CharPtr pubseqgitoseqid = "PubSeqGiForSeqId";
1943 
1944 static Boolean  fetch_fail_warn = FALSE;
1945 static Boolean  fetch_fail_warn_set = FALSE;
1946 
1947 static Boolean  fetch_succeed_log = FALSE;
1948 static Boolean  fetch_succeed_log_set = FALSE;
1949 
1950 static Int2 LIBCALLBACK PubSeqBioseqFetchFunc (Pointer data)
1951 
1952 {
1953   BioseqPtr         bsp;
1954   Int4              flags = -1;
1955   OMUserDataPtr     omdp = NULL;
1956   OMProcControlPtr  ompcp;
1957   ObjMgrProcPtr     ompp;
1958   Int2              retcode = 0;
1959   SeqEntryPtr       sep = NULL;
1960   SeqIdPtr          sip;
1961   Int4              uid = 0;
1962 #ifdef OS_UNIX
1963   Char              id [64];
1964   BioseqPtr         firstbsp;
1965   SeqEntryPtr       firstsep;
1966   ObjMgrPtr         omp;
1967   CharPtr           str;
1968 #endif
1969 
1970   ompcp = (OMProcControlPtr) data;
1971   if (ompcp == NULL) return OM_MSG_RET_ERROR;
1972   ompp = ompcp->proc;
1973   if (ompp == NULL) return OM_MSG_RET_ERROR;
1974   sip = (SeqIdPtr) ompcp->input_data;
1975   if (sip == NULL) return OM_MSG_RET_ERROR;
1976 
1977 #ifdef OS_UNIX
1978   if (! fetch_fail_warn_set) {
1979     str = (CharPtr) getenv ("PUBSEQ_FETCH_FAIL_WARN");
1980     if (StringDoesHaveText (str)) {
1981       if (StringICmp (str, "TRUE") == 0) {
1982         fetch_fail_warn = TRUE;
1983       }
1984     }
1985     fetch_fail_warn_set = TRUE;
1986   }
1987 
1988   if (! fetch_succeed_log_set) {
1989     str = (CharPtr) getenv ("PUBSEQ_FETCH_SUCCEED_LOG");
1990     if (StringDoesHaveText (str)) {
1991       if (StringICmp (str, "TRUE") == 0) {
1992         fetch_succeed_log = TRUE;
1993       }
1994     }
1995     fetch_succeed_log_set = TRUE;
1996   }
1997 #endif
1998 
1999   omdp = ObjMgrGetUserData (ompcp->input_entityID, ompp->procid, OMPROC_FETCH, 0);
2000   if (omdp != NULL) {
2001     uid = omdp->userdata.intvalue;
2002 #ifdef OS_UNIX
2003     if (fetch_succeed_log) {
2004       ErrPostEx (SEV_ERROR, 0, 0, "PSFetch reloading gi %ld", uid);
2005     }
2006 #endif
2007     if (uid == 0) return OM_MSG_RET_ERROR;
2008   } else if (sip->choice == SEQID_GI) {
2009     uid = sip->data.intvalue;
2010   } else if (sip->choice != SEQID_LOCAL) {
2011     uid = GetGIForSeqId (sip);
2012   }
2013 
2014   if (uid == 0) return OM_MSG_RET_OK;
2015 
2016   sep = PubSeqSynchronousQuery (uid, retcode, flags);
2017 
2018   if (sep == NULL) {
2019 #ifdef OS_UNIX
2020     if (fetch_fail_warn) {
2021       ErrPostEx (SEV_ERROR, 0, 0, "PSSyncQuery failed for gi %ld", uid);
2022     }
2023 #endif
2024     return OM_MSG_RET_OK;
2025   }
2026   bsp = BioseqFindInSeqEntry (sip, sep);
2027 
2028 #ifdef OS_UNIX
2029   if (bsp != NULL) {
2030     if (fetch_succeed_log) {
2031       ErrPostEx (SEV_ERROR, 0, 0, "PSFetch succeeded for gi %ld", uid);
2032     }
2033   }
2034 
2035   if (bsp == NULL) {
2036     if (fetch_fail_warn) {
2037       firstsep = FindNthBioseq (sep, 1);
2038       if (firstsep != NULL && IS_Bioseq (firstsep)) {
2039         firstbsp = (BioseqPtr) firstsep->data.ptrvalue;
2040         if (firstbsp != NULL && firstbsp->id != NULL) {
2041           SeqIdWrite (firstbsp->id, id, PRINTID_FASTA_LONG, sizeof (id) - 1);
2042           ErrPostEx (SEV_ERROR, 0, 0, "PubSeqBioseqFetchFunc requested gi %ld, got %s", uid, id);
2043           omp = ObjMgrGet ();
2044           if (omp != NULL) {
2045             ErrPostEx (SEV_ERROR, 0, 0, "ObjMgr highEid %d totobj %d currobj %d maxtemp %d tempcnt %d hold %d",
2046                        (int) omp->HighestEntityID, (int) omp->totobj, (int) omp->currobj,
2047                        (int) omp->maxtemp, (int) omp->tempcnt, (int) omp->hold);
2048           }
2049         }
2050       }
2051     }
2052   }
2053 #endif
2054 
2055   ompcp->output_data = (Pointer) bsp;
2056   ompcp->output_entityID = ObjMgrGetEntityIDForChoice (sep);
2057 
2058   omdp = ObjMgrAddUserData (ompcp->output_entityID, ompp->procid, OMPROC_FETCH, 0);
2059   if (omdp != NULL) {
2060     omdp->userdata.intvalue = uid;
2061   }
2062 
2063   return OM_MSG_RET_DONE;
2064 }
2065 
2066 static Int2 LIBCALLBACK TraceBioseqFetchFunc (Pointer data)
2067 
2068 {
2069   BioseqPtr         bsp;
2070   DbtagPtr          dbt;
2071   Int4              flags = -1;
2072   ObjectIdPtr       oip;
2073   OMUserDataPtr     omdp = NULL;
2074   OMProcControlPtr  ompcp;
2075   ObjMgrProcPtr     ompp;
2076   Int2              retcode = 0;
2077   SeqEntryPtr       sep = NULL;
2078   SeqIdPtr          sip;
2079   Int4              uid = 0;
2080 
2081   ompcp = (OMProcControlPtr) data;
2082   if (ompcp == NULL) return OM_MSG_RET_ERROR;
2083   ompp = ompcp->proc;
2084   if (ompp == NULL) return OM_MSG_RET_ERROR;
2085   sip = (SeqIdPtr) ompcp->input_data;
2086   if (sip == NULL) return OM_MSG_RET_ERROR;
2087 
2088   omdp = ObjMgrGetUserData (ompcp->input_entityID, ompp->procid, OMPROC_FETCH, 0);
2089   if (omdp != NULL) {
2090     uid = omdp->userdata.intvalue;
2091     if (uid == 0) return OM_MSG_RET_ERROR;
2092   } else if (sip->choice == SEQID_GENERAL) {
2093     dbt = (DbtagPtr) sip->data.ptrvalue;
2094     if (dbt == NULL) return OM_MSG_RET_OK;
2095     if (StringICmp (dbt->db, "ti") != 0) return OM_MSG_RET_OK;
2096     oip = dbt->tag;
2097     if (oip == NULL || oip->id == 0) return OM_MSG_RET_OK;
2098     uid = oip->id;
2099   }
2100 
2101   if (uid == 0) return OM_MSG_RET_OK;
2102 
2103   sep = PubSeqSynchronousQueryTI (uid, retcode, flags);
2104 
2105   if (sep == NULL) {
2106     return OM_MSG_RET_OK;
2107   }
2108   bsp = BioseqFindInSeqEntry (sip, sep);
2109 
2110   ompcp->output_data = (Pointer) bsp;
2111   ompcp->output_entityID = ObjMgrGetEntityIDForChoice (sep);
2112 
2113   omdp = ObjMgrAddUserData (ompcp->output_entityID, ompp->procid, OMPROC_FETCH, 0);
2114   if (omdp != NULL) {
2115     omdp->userdata.intvalue = uid;
2116   }
2117 
2118   return OM_MSG_RET_DONE;
2119 }
2120 
2121 static Pointer LIBCALLBACK FreeSraID (Pointer data)
2122 
2123 {
2124   MemFree (data);
2125   return NULL;
2126 }
2127 static Int2 LIBCALLBACK SRABioseqFetchFunc (Pointer data)
2128 
2129 {
2130   BioseqPtr         bsp;
2131   DbtagPtr          dbt;
2132   ObjectIdPtr       oip;
2133   OMUserDataPtr     omdp = NULL;
2134   OMProcControlPtr  ompcp;
2135   ObjMgrProcPtr     ompp;
2136   SeqEntryPtr       sep = NULL;
2137   SeqIdPtr          sip;
2138   CharPtr           sraid = NULL;
2139 
2140   ompcp = (OMProcControlPtr) data;
2141   if (ompcp == NULL) return OM_MSG_RET_ERROR;
2142   ompp = ompcp->proc;
2143   if (ompp == NULL) return OM_MSG_RET_ERROR;
2144   sip = (SeqIdPtr) ompcp->input_data;
2145   if (sip == NULL) return OM_MSG_RET_ERROR;
2146 
2147   omdp = ObjMgrGetUserData (ompcp->input_entityID, ompp->procid, OMPROC_FETCH, 0);
2148   if (omdp != NULL) {
2149     sraid = omdp->userdata.ptrvalue;
2150     if (sraid == NULL) return OM_MSG_RET_ERROR;
2151   } else if (sip->choice == SEQID_GENERAL) {
2152     dbt = (DbtagPtr) sip->data.ptrvalue;
2153     if (dbt == NULL) return OM_MSG_RET_OK;
2154     if (StringICmp (dbt->db, "SRA") != 0) return OM_MSG_RET_OK;
2155     oip = dbt->tag;
2156     if (oip == NULL || oip->str == NULL) return OM_MSG_RET_OK;
2157     sraid = oip->str;
2158   }
2159 
2160   if (sraid == NULL) return OM_MSG_RET_OK;
2161 
2162   sep = PubSeqSynchronousQuerySRA (sraid);
2163 
2164   if (sep == NULL) {
2165     return OM_MSG_RET_OK;
2166   }
2167   bsp = BioseqFindInSeqEntry (sip, sep);
2168 
2169   ompcp->output_data = (Pointer) bsp;
2170   ompcp->output_entityID = ObjMgrGetEntityIDForChoice (sep);
2171 
2172   omdp = ObjMgrAddUserData (ompcp->output_entityID, ompp->procid, OMPROC_FETCH, 0);
2173   if (omdp != NULL) {
2174     omdp->userdata.ptrvalue = StringSave (sraid);
2175     omdp->freefunc = FreeSraID;
2176   }
2177 
2178   return OM_MSG_RET_DONE;
2179 }
2180 
2181 static Int2 LIBCALLBACK PubSeqSeqIdForGiFunc (Pointer data)
2182 
2183 {
2184   Char              ch;
2185   OMProcControlPtr  ompcp;
2186   ObjMgrProcPtr     ompp;
2187   CharPtr           ptr;
2188   SeqIdPtr          sid = NULL;
2189   SeqIdPtr          sip;
2190   CharPtr           str;
2191   Int4              uid;
2192 
2193   ompcp = (OMProcControlPtr) data;
2194   if (ompcp == NULL) return OM_MSG_RET_ERROR;
2195   ompp = ompcp->proc;
2196   if (ompp == NULL) return OM_MSG_RET_ERROR;
2197   sip = (SeqIdPtr) ompcp->input_data;
2198   if (sip == NULL) return OM_MSG_RET_ERROR;
2199 
2200   if (sip->choice != SEQID_GI) return OM_MSG_RET_ERROR;
2201   uid = (Int4) sip->data.intvalue;
2202   if (uid < 1) return OM_MSG_RET_ERROR;
2203 
2204   str = GiRevHistSynchronousQuery (uid, 0, NULL);
2205   if (str == NULL) return OM_MSG_RET_ERROR;
2206 
2207   ptr = str;
2208   ch = *ptr;
2209   while (ch != '\0' && ch != '\n' && ch != '\r') {
2210     ptr++;
2211     ch = *ptr;
2212   }
2213   *ptr = '\0';
2214 
2215   if (StringNCmp (str, "ERROR", 5) != 0 && StringNCmp (str, "<!DOCTYPE", 9) != 0) {
2216     sid = SeqIdParse (str);
2217   }
2218   MemFree (str);
2219 
2220   if (sid == NULL) return OM_MSG_RET_ERROR;
2221 
2222   ompcp->output_data = (Pointer) sid;
2223   return OM_MSG_RET_DONE;
2224 }
2225 
2226 static Int2 LIBCALLBACK PubSeqGiForSeqIdFunc (Pointer data)
2227 
2228 {
2229   Char              buf [41];
2230   Int4              gi;
2231   OMProcControlPtr  ompcp;
2232   ObjMgrProcPtr     ompp;
2233   SeqIdPtr          sid;
2234   SeqIdPtr          sip;
2235 
2236   ompcp = (OMProcControlPtr) data;
2237   if (ompcp == NULL) return OM_MSG_RET_ERROR;
2238   ompp = ompcp->proc;
2239   if (ompp == NULL) return OM_MSG_RET_ERROR;
2240   sip = (SeqIdPtr) ompcp->input_data;
2241   if (sip == NULL) return OM_MSG_RET_ERROR;
2242 
2243   if (sip->choice == SEQID_GI) return OM_MSG_RET_ERROR;
2244   if (sip->choice == SEQID_LOCAL) return OM_MSG_RET_OK;
2245   SeqIdWrite (sip, buf, PRINTID_FASTA_SHORT, sizeof (buf));
2246   if (StringHasNoText (buf)) return OM_MSG_RET_ERROR;
2247 
2248   gi = AccnRevHistSynchronousQuery (buf);
2249   if (gi < 1) return OM_MSG_RET_ERROR;
2250 
2251   sid = ValNodeNew (NULL);
2252   if (sid == NULL) return OM_MSG_RET_ERROR;
2253   sid->choice = SEQID_GI;
2254   sid->data.intvalue = gi;
2255   sid->next = NULL;
2256 
2257   ompcp->output_data = (Pointer) sid;
2258   return OM_MSG_RET_DONE;
2259 }
2260 
2261 NLM_EXTERN Boolean PubSeqFetchEnable (void)
2262 
2263 {
2264   ObjMgrProcLoad (OMPROC_FETCH, srafetchproc, srafetchproc,
2265                   OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
2266                   SRABioseqFetchFunc, PROC_PRIORITY_DEFAULT);
2267 
2268   ObjMgrProcLoad (OMPROC_FETCH, tracefetchproc, tracefetchproc,
2269                   OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
2270                   TraceBioseqFetchFunc, PROC_PRIORITY_DEFAULT);
2271 
2272   ObjMgrProcLoad (OMPROC_FETCH, pubseqfetchproc, pubseqfetchproc,
2273                   OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
2274                   PubSeqBioseqFetchFunc, PROC_PRIORITY_DEFAULT);
2275 
2276   ObjMgrProcLoad (OMPROC_FETCH, pubseqseqidtogi, pubseqseqidtogi,
2277                   OBJ_SEQID, SEQID_GI, OBJ_SEQID, 0, NULL,
2278                   PubSeqSeqIdForGiFunc, PROC_PRIORITY_DEFAULT);
2279 
2280   ObjMgrProcLoad (OMPROC_FETCH, pubseqgitoseqid, pubseqgitoseqid,
2281                   OBJ_SEQID, 0, OBJ_SEQID, SEQID_GI, NULL,
2282                   PubSeqGiForSeqIdFunc, PROC_PRIORITY_DEFAULT);
2283 
2284   SeqMgrSetPreCache (GiRevHistLookupFarSeqIDs);
2285 
2286   SeqMgrSetSeqIdSetFunc (GiRevHistLookupSeqIdSet);
2287 
2288   return TRUE;
2289 }
2290 
2291 NLM_EXTERN Boolean PubSeqFetchEnableEx (
2292   Boolean fetch,
2293   Boolean seqidtogi,
2294   Boolean gitoseqid,
2295   Boolean precache,
2296   Boolean seqidset
2297 )
2298 
2299 {
2300   if (fetch) {
2301     ObjMgrProcLoad (OMPROC_FETCH, srafetchproc, srafetchproc,
2302                     OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
2303                     SRABioseqFetchFunc, PROC_PRIORITY_DEFAULT);
2304 
2305     ObjMgrProcLoad (OMPROC_FETCH, tracefetchproc, tracefetchproc,
2306                     OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
2307                     TraceBioseqFetchFunc, PROC_PRIORITY_DEFAULT);
2308 
2309     ObjMgrProcLoad (OMPROC_FETCH, pubseqfetchproc, pubseqfetchproc,
2310                     OBJ_SEQID, 0, OBJ_BIOSEQ, 0, NULL,
2311                     PubSeqBioseqFetchFunc, PROC_PRIORITY_DEFAULT);
2312   }
2313 
2314   if (seqidtogi) {
2315     ObjMgrProcLoad (OMPROC_FETCH, pubseqseqidtogi, pubseqseqidtogi,
2316                     OBJ_SEQID, SEQID_GI, OBJ_SEQID, 0, NULL,
2317                     PubSeqSeqIdForGiFunc, PROC_PRIORITY_DEFAULT);
2318   }
2319 
2320   if (gitoseqid) {
2321     ObjMgrProcLoad (OMPROC_FETCH, pubseqgitoseqid, pubseqgitoseqid,
2322                     OBJ_SEQID, 0, OBJ_SEQID, SEQID_GI, NULL,
2323                     PubSeqGiForSeqIdFunc, PROC_PRIORITY_DEFAULT);
2324   }
2325 
2326   if (precache) {
2327     SeqMgrSetPreCache (GiRevHistLookupFarSeqIDs);
2328   }
2329 
2330   if (seqidset) {
2331     SeqMgrSetSeqIdSetFunc (GiRevHistLookupSeqIdSet);
2332   }
2333 
2334   return TRUE;
2335 }
2336 
2337 NLM_EXTERN void PubSeqFetchDisable (void)
2338 
2339 {
2340   ObjMgrPtr      omp;
2341   ObjMgrProcPtr  ompp;
2342 
2343   omp = ObjMgrGet ();
2344   ompp = ObjMgrProcFind (omp, 0, srafetchproc, OMPROC_FETCH);
2345   if (ompp != NULL) {
2346     ObjMgrFreeUserData (0, ompp->procid, OMPROC_FETCH, 0);
2347   }
2348   ompp = ObjMgrProcFind (omp, 0, tracefetchproc, OMPROC_FETCH);
2349   if (ompp != NULL) {
2350     ObjMgrFreeUserData (0, ompp->procid, OMPROC_FETCH, 0);
2351   }
2352   ompp = ObjMgrProcFind (omp, 0, pubseqfetchproc, OMPROC_FETCH);
2353   if (ompp != NULL) {
2354     ObjMgrFreeUserData (0, ompp->procid, OMPROC_FETCH, 0);
2355   }
2356   ompp = ObjMgrProcFind (omp, 0, pubseqseqidtogi, OMPROC_FETCH);
2357   if (ompp != NULL) {
2358     ObjMgrFreeUserData (0, ompp->procid, OMPROC_FETCH, 0);
2359   }
2360   ompp = ObjMgrProcFind (omp, 0, pubseqgitoseqid, OMPROC_FETCH);
2361   if (ompp != NULL) {
2362     ObjMgrFreeUserData (0, ompp->procid, OMPROC_FETCH, 0);
2363   }
2364 
2365   SeqMgrSetPreCache (NULL);
2366 
2367   SeqMgrSetSeqIdSetFunc (NULL);
2368 }
2369 
2370 /* multiple Accession preload into cache or report function */
2371 
2372 NLM_EXTERN Int4 CacheAccnList (
2373   CharPtr str,
2374   CacheAccnListProc userfunc
2375 )
2376 
2377 {
2378   SeqIdPtr  accn;
2379   Char      buf [41];
2380   Char      ch;
2381   Int4      count = 0;
2382   Int4      gi;
2383   Int4      i;
2384   SeqIdPtr  ids;
2385   CharPtr   ptr;
2386   SeqIdPtr  sip;
2387   CharPtr   tmp;
2388 
2389   if (str == NULL) return 0;
2390 
2391   if (StringNCmp (str, "<!DOCTYPE", 9) == 0) return 0;
2392 
2393   /* parse output */
2394 
2395   i = 0;
2396   ptr = str;
2397   ch = *ptr;
2398   while (ch != '\0') {
2399     tmp = ptr;
2400     while (ch != '\0' && ch != '\n' && ch != '\r') {
2401       ptr++;
2402       ch = *ptr;
2403     }
2404     *ptr = '\0';
2405     while (ch == '\n' || ch == '\r') {
2406       ptr++;
2407       ch = *ptr;
2408     }
2409     if (StringNCmp (tmp, "ERROR", 5) != 0 &&
2410         StringNCmp (tmp, "<!DOCTYPE", 9) != 0 &&
2411         StringNCmp (tmp, "Sorry", 5) != 0 &&
2412         StringChr (tmp, '|') != NULL) {
2413       ids = SeqIdParse (tmp);
2414       if (ids != NULL) {
2415         gi = 0;
2416         accn = NULL;
2417         for (sip = ids; sip != NULL; sip = sip->next) {
2418           switch (sip->choice) {
2419             case SEQID_GI :
2420               gi = (Int4) sip->data.intvalue;
2421               break;
2422             case SEQID_GENBANK :
2423             case SEQID_EMBL :
2424             case SEQID_PIR :
2425             case SEQID_SWISSPROT :
2426             case SEQID_PATENT :
2427             case SEQID_OTHER :
2428             case SEQID_DDBJ :
2429             case SEQID_PRF :
2430             case SEQID_TPG :
2431             case SEQID_TPE :
2432             case SEQID_TPD :
2433             case SEQID_GPIPE :
2434               accn = sip;
2435               break;
2436             default :
2437               break;
2438           }
2439         }
2440         if (gi > 0 && accn != NULL) {
2441 
2442           if (userfunc != NULL) {
2443 
2444             SeqIdWrite (accn, buf, PRINTID_TEXTID_ACC_VER, sizeof (buf) - 1);
2445             if (! StringHasNoText (buf)) {
2446               userfunc (gi, buf);
2447               count++;
2448             }
2449 
2450           } else {
2451 
2452             RecordInSeqIdGiCache (gi, accn);
2453             count++;
2454           }
2455         }
2456         SeqIdSetFree (ids);
2457       }
2458     }
2459     i++;
2460   }
2461 
2462   return count;
2463 }
2464 
2465 /* multiple SeqId preload into cache function */
2466 
2467 static int LIBCALLBACK SortByInt4 (VoidPtr vp1, VoidPtr vp2)
2468 
2469 {
2470   Int4Ptr ip1 = (Int4Ptr) vp1;
2471   Int4Ptr ip2 = (Int4Ptr) vp2;
2472 
2473   if (ip1 == NULL || ip2 == NULL) return 0;
2474   if (*ip1 > *ip2) return 1;
2475   if (*ip1 < *ip2) return -1;
2476   return 0;
2477 }
2478 
2479 static Int4 IntPreLoadSeqIdGiCache (
2480   Int4 num,
2481   Int4Ptr ids
2482 )
2483 
2484 {
2485   Char      ch;
2486   Int4      count = 0;
2487   Int4      gi;
2488   Int4      i;
2489   CharPtr   ptr;
2490   SeqIdPtr  sip;
2491   CharPtr   str;
2492   CharPtr   tmp;
2493 
2494   if (num < 1 || num > 500 || ids == NULL) return 0;
2495 
2496   /* perform multiple gi to SeqId query */
2497 
2498   /* str = GiRevHistSynchronousQuery (0, num, ids); */
2499   str = GiAccVerSynchronousQuery (0, num, ids);
2500   if (str == NULL) return 0;
2501 
2502   if (StringNCmp (str, "<!DOCTYPE", 9) == 0) return 0;
2503 
2504   /* parse output */
2505 
2506   i = 0;
2507   ptr = str;
2508   ch = *ptr;
2509   while (ch != '\0') {
2510     tmp = ptr;
2511     while (ch != '\0' && ch != '\n' && ch != '\r') {
2512       ptr++;
2513       ch = *ptr;
2514     }
2515     *ptr = '\0';
2516     while (ch == '\n' || ch == '\r') {
2517       ptr++;
2518       ch = *ptr;
2519     }
2520     if (StringNCmp (tmp, "ERROR", 5) != 0 && StringNCmp (tmp, "<!DOCTYPE", 9) != 0) {
2521       gi = ids [i];
2522 
2523       sip = NULL;
2524       if (StringChr (tmp, '|') != NULL) {
2525         sip = SeqIdParse (tmp);
2526       } else {
2527         sip = SeqIdFromAccessionDotVersion (tmp);
2528       }
2529       if (sip != NULL) {
2530         RecordInSeqIdGiCache (gi, sip);
2531         SeqIdSetFree (sip);
2532         count++;
2533       }
2534     }
2535     i++;
2536   }
2537 
2538   MemFree (str);
2539 
2540   return count;
2541 }
2542 
2543 static Int4 FilterKnownGis (
2544   Int4 num,
2545   Int4Ptr uniq,
2546   Boolean filter
2547 )
2548 
2549 {
2550   BioseqPtr  bsp;
2551   Int4       gi;
2552   Int4       i;
2553   Int4       ids [501];
2554   Int4       j;
2555   ValNode    vn;
2556 
2557   if (num < 1 || num > 500 || uniq == NULL) return 0;
2558 
2559   MemSet ((Pointer) &vn, 0, sizeof (ValNode));
2560   vn.choice = SEQID_GI;
2561 
2562   /* eliminate uids we already know, load ids list with remainder */
2563 
2564   for (i = 0, j = 0; i < num; i++) {
2565     gi = uniq [i];
2566     if (gi < 1) continue;
2567 
2568     if (filter) {
2569       vn.data.intvalue = gi;
2570       bsp = BioseqFindCore (&vn);
2571       if (bsp != NULL) continue; /* already loaded */
2572 
2573       if (FetchFromSeqIdGiCache (gi, NULL)) continue; /* already cached */
2574     }
2575 
2576     ids [j] = gi;
2577     j++;
2578   }
2579 
2580   if (j < 1) return 0;
2581 
2582   return IntPreLoadSeqIdGiCache (j, ids);
2583 }
2584 
2585 static Int4 UniqPreLoadList (
2586   Int4 num,
2587   Int4Ptr srted,
2588   Boolean filter
2589 )
2590 
2591 {
2592   Int4  gi;
2593   Int4  i;
2594   Int4  j;
2595   Int4  last;
2596   Int4  uniq [501];
2597 
2598   if (num < 1 || num > 500 || srted == NULL) return 0;
2599 
2600   /* unique uid list */
2601 
2602   last = 0;
2603   for (i = 0, j = 0; i < num; i++) {
2604     gi = srted [i];
2605     if (gi != last) {
2606       uniq [j] = gi;
2607       j++;
2608     }
2609     last = gi;
2610   }
2611   num = j;
2612 
2613   return FilterKnownGis (num, uniq, filter);
2614 }
2615 
2616 static Int4 SortPreLoadList (
2617   Int4 num,
2618   Int4Ptr raw,
2619   Boolean filter
2620 )
2621 
2622 {
2623   Int4  i;
2624   Int4  uids [501];
2625 
2626   if (num < 1 || num > 500 || raw == NULL) return 0;
2627 
2628   /* copy raw uid list */
2629 
2630   for (i = 0; i < num; i++) {
2631     uids [i] = raw [i];
2632   }
2633 
2634   /* sort by gi value */
2635 
2636   HeapSort ((Pointer) uids, (size_t) num, sizeof (Int4), SortByInt4);
2637 
2638   return UniqPreLoadList (num, uids, filter);
2639 }
2640 
2641 NLM_EXTERN Int4 GiRevHistPreLoadSeqIdGiCacheEx (
2642   Int4 num,
2643   Int4Ptr uids,
2644   Boolean filter
2645 )
2646 
2647 {
2648   Int4  count;
2649   Int4  offset;
2650   Int4  rsult = 0;
2651 
2652   /* split into queries of 500 or fewer uids at a time */
2653 
2654   if (num < 1 || uids == NULL) return 0;
2655   count = (Int4) MIN (num, 500L);
2656   offset = 0;
2657   while (count > 0 && num > 0) {
2658     rsult += SortPreLoadList (count, uids + offset, filter);
2659     offset += count;
2660     num -= count;
2661     count = (Int4) MIN (num, 500L);
2662   }
2663   return rsult;
2664 }
2665 
2666 NLM_EXTERN Int4 GiRevHistPreLoadSeqIdGiCache (
2667   Int4 num,
2668   Int4Ptr uids
2669 )
2670 
2671 {
2672   return GiRevHistPreLoadSeqIdGiCacheEx (num, uids, TRUE);
2673 }
2674 
2675 static Int4 SortPreLoadAccns (
2676   Int4 num,
2677   CharPtr PNTR raw
2678 )
2679 
2680 {
2681   CharPtr  accns [501];
2682   Int4     i, rsult = 0;
2683   CharPtr  str;
2684 
2685   if (num < 1 || num > 500 || raw == NULL) return 0;
2686 
2687   /* copy raw uid list */
2688 
2689   for (i = 0; i < num; i++) {
2690     accns [i] = raw [i];
2691   }
2692   accns [i] = NULL;
2693 
2694   str = AccnListSynchronousQuery (accns);
2695   if (str == NULL) return 0;
2696 
2697   rsult = CacheAccnList (str, NULL);
2698 
2699   MemFree (str);
2700   return rsult;
2701 }
2702 
2703 NLM_EXTERN Int4 AccnListPreLoadSeqIdGiCache (
2704   CharPtr PNTR accns
2705 )
2706 
2707 {
2708   Int4  count, num, offset, rsult = 0;
2709  
2710   if (accns == NULL) return 0;
2711 
2712   for (num = 0; accns [num] != NULL; num++) continue;
2713   if (num < 1) return 0;
2714 
2715   count = (Int4) MIN (num, 500L);
2716   offset = 0;
2717 
2718   while (count > 0 && num > 0) {
2719     rsult += SortPreLoadAccns (count, accns + offset);
2720     offset += count;
2721     num -= count;
2722     count = (Int4) MIN (num, 500L);
2723   }
2724 
2725   return rsult;
2726 }
2727 
2728 typedef struct fariddata {
2729   ValNodePtr  gis;
2730   ValNodePtr  accns;
2731   ValNodePtr  strs;
2732 } FarIdData, PNTR FarIDPtr;
2733 
2734 
2735 static void ReplaceSpacesWithPluses (CharPtr str)
2736 {
2737   CharPtr cp;
2738   
2739   if (str == NULL) return;
2740   
2741   for (cp = str; *cp; cp++)
2742   {
2743     if (*cp == ' ')
2744     {
2745       *cp = '+';
2746     }
2747   }
2748 }
2749 
2750 static void LookupSegments (SeqLocPtr slp, SeqIdPtr sip, Pointer userdata)
2751 
2752 {
2753   FarIDPtr    fip;
2754   SeqLocPtr   loc;
2755   ValNodePtr  vnp;
2756 
2757   if (slp == NULL && sip == NULL) return;
2758   if (userdata == NULL) return;
2759   fip = (FarIDPtr) userdata;
2760 
2761   if (sip == NULL) {
2762     sip = SeqLocId (slp);
2763     if (sip == NULL) {
2764       loc = SeqLocFindNext (slp, NULL);
2765       if (loc != NULL) {
2766         sip = SeqLocId (loc);
2767       }
2768     }
2769   }
2770   if (sip == NULL) return;
2771 
2772   switch (sip->choice) {
2773     case SEQID_GI :
2774       vnp = ValNodeAddInt (NULL, 0, sip->data.intvalue);
2775       if (fip->gis == NULL) {
2776         fip->gis = vnp;
2777       } else {
2778         vnp->next = fip->gis;
2779         fip->gis = vnp;
2780       }
2781       break;
2782     case SEQID_GENBANK :
2783     case SEQID_EMBL :
2784     case SEQID_DDBJ :
2785     case SEQID_TPG :
2786     case SEQID_TPE :
2787     case SEQID_TPD :
2788     case SEQID_OTHER :
2789     case SEQID_GPIPE :
2790       vnp = ValNodeAddPointer (NULL, 0, sip);
2791       if (fip->accns == NULL) {
2792         fip->accns = vnp;
2793       } else {
2794         vnp->next = fip->accns;
2795         fip->accns = vnp;
2796       }
2797       break;
2798     default :
2799       break;
2800   }
2801 }
2802 
2803 static void LookupBioseqs (BioseqPtr bsp, Pointer userdata)
2804 
2805 {
2806   DeltaSeqPtr  dsp;
2807   SeqLocPtr    slp = NULL;
2808   ValNode      vn;
2809 
2810   if (bsp == NULL) return;
2811 
2812   if (bsp->repr == Seq_repr_seg) {
2813     vn.choice = SEQLOC_MIX;
2814     vn.extended = 0;
2815     vn.data.ptrvalue = bsp->seq_ext;
2816     vn.next = NULL;
2817     while ((slp = SeqLocFindNext (&vn, slp)) != NULL) {
2818       if (slp != NULL && slp->choice != SEQLOC_NULL) {
2819         LookupSegments (slp, NULL, userdata);
2820       }
2821     }
2822   } else if (bsp->repr == Seq_repr_delta) {
2823     for (dsp = (DeltaSeqPtr) (bsp->seq_ext); dsp != NULL; dsp = dsp->next) {
2824       if (dsp->choice == 1) {
2825         slp = (SeqLocPtr) dsp->data.ptrvalue;
2826         if (slp != NULL && slp->choice != SEQLOC_NULL) {
2827           LookupSegments (slp, NULL, userdata);
2828         }
2829       }
2830     }
2831   }
2832 }
2833 
2834 static void LookupLocations (SeqFeatPtr sfp, Pointer userdata)
2835 
2836 {
2837   SeqLocPtr  slp = NULL;
2838 
2839   if (sfp == NULL) return;
2840 
2841   while ((slp = SeqLocFindNext (sfp->location, slp)) != NULL) {
2842     if (slp != NULL && slp->choice != SEQLOC_NULL) {
2843       LookupSegments (slp, NULL, userdata);
2844     }
2845   }
2846 }
2847 
2848 static void LookupProducts (SeqFeatPtr sfp, Pointer userdata)
2849 
2850 {
2851   SeqLocPtr  slp = NULL;
2852 
2853   if (sfp == NULL) return;
2854 
2855   while ((slp = SeqLocFindNext (sfp->product, slp)) != NULL) {
2856     if (slp != NULL && slp->choice != SEQLOC_NULL) {
2857       LookupSegments (slp, NULL, userdata);
2858     }
2859   }
2860 }
2861 
2862 static void LookupAlignments (SeqAlignPtr sap, Pointer userdata)
2863 
2864 {
2865   DenseDiagPtr  ddp;
2866   DenseSegPtr   dsp;
2867   SeqIdPtr      sip;
2868   SeqLocPtr     slp = NULL;
2869   StdSegPtr     ssp;
2870 
2871   if (sap == NULL) return;
2872 
2873   LookupSegments (sap->bounds, NULL, userdata);
2874   if (sap->segs == NULL) return;
2875 
2876   switch (sap->segtype) {
2877     case SAS_DENDIAG :
2878       ddp = (DenseDiagPtr) sap->segs;
2879       if (ddp != NULL) {
2880         for (sip = ddp->id; sip != NULL; sip = sip->next) {
2881           LookupSegments (NULL, sip, userdata);
2882         }
2883       }
2884       break;
2885     case SAS_DENSEG :
2886       dsp = (DenseSegPtr) sap->segs;
2887       if (dsp != NULL) {
2888         for (sip = dsp->ids; sip != NULL; sip = sip->next) {
2889           LookupSegments (NULL, sip, userdata);
2890         }
2891       }
2892       break;
2893     case SAS_STD :
2894       ssp = (StdSegPtr) sap->segs;
2895       for (slp = ssp->loc; slp != NULL; slp = slp->next) {
2896         LookupSegments (slp, NULL, userdata);
2897       }
2898       break;
2899     case SAS_DISC :
2900       /* recursive */
2901       for (sap = (SeqAlignPtr) sap->segs; sap != NULL; sap = sap->next) {
2902         LookupAlignments (sap, userdata);
2903       }
2904       break;
2905     default :
2906       break;
2907   }
2908 }
2909 
2910 static void LookupHistory (BioseqPtr bsp, Pointer userdata)
2911 
2912 {
2913   SeqHistPtr  hist;
2914   SeqIdPtr    sip;
2915 
2916   if (bsp == NULL) return;
2917   hist = bsp->hist;
2918   if (hist == NULL) return;
2919   if (hist->assembly != NULL) {
2920     LookupAlignments (hist->assembly, userdata);
2921   }
2922   for (sip = hist->replace_ids; sip != NULL; sip = sip->next) {
2923     LookupSegments (NULL, sip, userdata);
2924   }
2925   for (sip = hist->replaced_by_ids; sip != NULL; sip = sip->next) {
2926     LookupSegments (NULL, sip, userdata);
2927   }
2928 }
2929 
2930 static void LookupOthers (SeqDescrPtr sdp, Pointer userdata)
2931 
2932 {
2933   SeqIdPtr    sip;
2934   SPBlockPtr  spb;
2935 
2936   if (sdp == NULL || sdp->choice != Seq_descr_sp) return;
2937   spb = (SPBlockPtr) sdp->data.ptrvalue;
2938   if (spb == NULL) return;
2939 
2940   for (sip = spb->seqref; sip != NULL; sip = sip->next) {
2941     LookupSegments (NULL, sip, userdata);
2942   }
2943 }
2944 
2945 static CharPtr inferencePrefix [] = {
2946   "",
2947   "similar to sequence",
2948   "similar to AA sequence",
2949   "similar to DNA sequence",
2950   "similar to RNA sequence",
2951   "similar to RNA sequence, mRNA",
2952   "similar to RNA sequence, EST",
2953   "similar to RNA sequence, other RNA",
2954   "profile",
2955   "nucleotide motif",
2956   "protein motif",
2957   "ab initio prediction",
2958   "alignment",
2959   NULL
2960 };
2961 
2962 static void LookupInference (SeqFeatPtr sfp, Pointer userdata)
2963 
2964 {
2965   Int2        accnv, best, j;
2966   Char        ch;
2967   FarIDPtr    fip;
2968   GBQualPtr   gbq;
2969   size_t      len;
2970   CharPtr     rest;
2971   CharPtr     str;
2972   CharPtr     tmp;
2973   ValNodePtr  vnp;
2974 
2975   if (sfp == NULL || userdata == NULL) return;
2976   fip = (FarIDPtr) userdata;
2977 
2978   for (gbq = sfp->qual; gbq != NULL; gbq = gbq->next) {
2979     if (StringICmp (gbq->qual, "inference") != 0) continue;
2980     if (StringHasNoText (gbq->val)) continue;
2981 
2982     rest = NULL;
2983     best = -1;
2984     for (j = 0; inferencePrefix [j] != NULL; j++) {
2985       len = StringLen (inferencePrefix [j]);
2986       if (StringNICmp (gbq->val, inferencePrefix [j], len) != 0) continue;
2987       rest = gbq->val + len;
2988       best = j;
2989     }
2990     if (best < 0 || inferencePrefix [best] == NULL) continue;
2991     if (rest == NULL) continue;
2992 
2993     ch = *rest;
2994     while (IS_WHITESP (ch)) {
2995       rest++;
2996       ch = *rest;
2997     }
2998     if (StringNICmp (rest, "(same species)", 14) == 0) {
2999       rest += 14;
3000     }
3001     ch = *rest;
3002     while (IS_WHITESP (ch) || ch == ':') {
3003       rest++;
3004       ch = *rest;
3005     }
3006     if (StringHasNoText (rest)) continue;
3007 
3008     str = StringSave (rest);
3009     tmp = StringChr (str, ':');
3010     if (tmp != NULL) {
3011       *tmp = '\0';
3012       tmp++;
3013       TrimSpacesAroundString (str);
3014       TrimSpacesAroundString (tmp);
3015       if (StringDoesHaveText (tmp)) {
3016         if (StringICmp (str, "INSD") == 0 || StringICmp (str, "RefSeq") == 0) {
3017           accnv = ValidateAccnDotVer (tmp);
3018           if (accnv == 0) {
3019             ReplaceSpacesWithPluses (tmp);
3020             vnp = ValNodeCopyStr (NULL, 0, tmp);
3021             if (fip->strs == NULL) {
3022               fip->strs = vnp;
3023             } else {
3024               vnp->next = fip->strs;
3025               fip->strs = vnp;
3026             }
3027           }
3028         }
3029       }
3030     }
3031     MemFree (str);
3032   }
3033 }
3034 
3035 static Boolean GiExists (
3036   Int4 gi
3037 )
3038 
3039 {
3040   ValNode  vn;
3041 
3042   if (gi < 1) return TRUE;
3043 
3044   vn.choice = SEQID_GI;
3045   vn.data.intvalue = gi;
3046   vn.next = NULL;
3047 
3048   if (BioseqFindCore (&vn) != NULL) return TRUE;
3049 
3050   if (FetchFromSeqIdGiCache (gi, NULL)) return TRUE;
3051 
3052   return FALSE;
3053 }
3054 
3055 static ValNodePtr FilterCachedGis (
3056   ValNodePtr head
3057 )
3058 
3059 {
3060   ValNodePtr    next;
3061   Pointer PNTR  prev;
3062   ValNodePtr    top;
3063   ValNodePtr    vnp;
3064 
3065   if (head == NULL) return NULL;
3066   top = head;
3067 
3068   prev = (Pointer PNTR) &top;
3069   vnp = top;
3070   while (vnp != NULL) {
3071     next = vnp->next;
3072     if (GiExists (vnp->data.intvalue)) {
3073       *(prev) = next;
3074       vnp->next = NULL;
3075       ValNodeFree (vnp);
3076     } else {
3077       prev = (Pointer PNTR) &(vnp->next);
3078     }
3079     vnp = next;
3080   }
3081 
3082 
3083   return top;
3084 }
3085 
3086 static Boolean SipExists (
3087   SeqIdPtr sip
3088 )
3089 
3090 {
3091   if (sip == NULL) return TRUE;
3092 
3093   if (BioseqFindCore (sip) != NULL) return TRUE;
3094 
3095   if (FetchFromGiSeqIdCache (sip, NULL)) return TRUE;
3096 
3097   return FALSE;
3098 }
3099 
3100 static ValNodePtr FilterCachedAccns (
3101   ValNodePtr head
3102 )
3103 
3104 {
3105   ValNodePtr    next;
3106   Pointer PNTR  prev;
3107   ValNodePtr    top;
3108   ValNodePtr    vnp;
3109 
3110   if (head == NULL) return NULL;
3111   top = head;
3112 
3113   prev = (Pointer PNTR) &top;
3114   vnp = top;
3115   while (vnp != NULL) {
3116     next = vnp->next;
3117     if (SipExists (vnp->data.ptrvalue)) {
3118       *(prev) = next;
3119       vnp->next = NULL;
3120       ValNodeFree (vnp);
3121     } else {
3122       prev = (Pointer PNTR) &(vnp->next);
3123     }
3124     vnp = next;
3125   }
3126 
3127 
3128   return top;
3129 }
3130 
3131 static ValNodePtr FilterCachedStrs (
3132   ValNodePtr head
3133 )
3134 
3135 {
3136   ValNodePtr    next;
3137   Pointer PNTR  prev;
3138   SeqIdPtr      sip;
3139   CharPtr       str;
3140   ValNodePtr    top;
3141   ValNodePtr    vnp;
3142 
3143   if (head == NULL) return NULL;
3144   top = head;
3145 
3146   prev = (Pointer PNTR) &top;
3147   vnp = top;
3148   while (vnp != NULL) {
3149     next = vnp->next;
3150     str = (CharPtr) vnp->data.ptrvalue;
3151     sip = SeqIdFromAccessionDotVersion (str);
3152     if (sip != NULL && SipExists (sip)) {
3153       *(prev) = next;
3154       vnp->next = NULL;
3155       ValNodeFree (vnp);
3156     } else {
3157       prev = (Pointer PNTR) &(vnp->next);
3158     }
3159     SeqIdFree (sip);
3160     vnp = next;
3161   }
3162 
3163 
3164   return top;
3165 }
3166 
3167 static int SeqIdSortCompare (SeqIdPtr sip1, SeqIdPtr sip2)
3168 
3169 {
3170   TextSeqIdPtr  tsip1, tsip2;
3171 
3172   if (sip1 == NULL || sip2 == NULL) return 0;
3173 
3174   if (sip1->choice > sip2->choice) {
3175     return 1;
3176   } else if (sip1->choice < sip2->choice) {
3177     return -1;
3178   }
3179 
3180   switch (sip1->choice) {
3181     case SEQID_GENBANK :
3182     case SEQID_EMBL :
3183     case SEQID_DDBJ :
3184     case SEQID_TPG :
3185     case SEQID_TPE :
3186     case SEQID_TPD :
3187     case SEQID_OTHER :
3188     case SEQID_GPIPE :
3189       tsip1 = (TextSeqIdPtr) sip1->data.ptrvalue;
3190       tsip2 = (TextSeqIdPtr) sip2->data.ptrvalue;
3191       if (tsip1 == NULL || tsip2 == NULL) return 0;
3192       if (StringDoesHaveText (tsip1->accession) && StringDoesHaveText (tsip2->accession)) {
3193         return StringICmp (tsip1->accession, tsip2->accession);
3194       }
3195       if (StringDoesHaveText (tsip1->name) && StringDoesHaveText (tsip2->name)) {
3196         return StringICmp (tsip1->name, tsip2->name);
3197       }
3198       break;
3199     default :
3200       break;
3201   }
3202 
3203   return 0;
3204 }
3205 
3206 static int LIBCALLBACK SortVnpBySeqId (VoidPtr ptr1, VoidPtr ptr2)
3207 
3208 {
3209  SeqIdPtr    sip1, sip2;
3210   ValNodePtr  vnp1, vnp2;
3211 
3212   if (ptr1 == NULL || ptr2 == NULL) return 0;
3213   vnp1 = *((ValNodePtr PNTR) ptr1);
3214   vnp2 = *((ValNodePtr PNTR) ptr2);
3215   if (vnp1 == NULL || vnp2 == NULL) return 0;
3216   sip1 = (SeqIdPtr) vnp1->data.ptrvalue;
3217   sip2 = (SeqIdPtr) vnp2->data.ptrvalue;
3218   if (sip1 == NULL || sip2 == NULL) return 0;
3219   return SeqIdSortCompare (sip1, sip2);
3220 }
3221 
3222 static ValNodePtr UniqueSeqIdValNode (ValNodePtr list)
3223 
3224 {
3225   SeqIdPtr      curr;
3226   SeqIdPtr      last;
3227   ValNodePtr    next;
3228   Pointer PNTR  prev;
3229   ValNodePtr    vnp;
3230 
3231   if (list == NULL) return NULL;
3232   last = (SeqIdPtr) list->data.ptrvalue;
3233   vnp = list->next;
3234   prev = (Pointer PNTR) &(list->next);
3235   while (vnp != NULL) {
3236     next = vnp->next;
3237     curr = (SeqIdPtr) vnp->data.ptrvalue;
3238     if (SeqIdSortCompare (last, curr) == 0) {
3239       vnp->next = NULL;
3240       *prev = next;
3241       ValNodeFree (vnp);
3242     } else {
3243       last = (SeqIdPtr) vnp->data.ptrvalue;
3244       prev = (Pointer PNTR) &(vnp->next);
3245     }
3246     vnp = next;
3247   }
3248 
3249   return list;
3250 }
3251 
3252 NLM_EXTERN Int4 LIBCALLBACK GiRevHistLookupFarSeqIDs (
3253   SeqEntryPtr sep,
3254   Boolean components,
3255   Boolean locations,
3256   Boolean products,
3257   Boolean alignments,
3258   Boolean history,
3259   Boolean inference,
3260   Boolean others
3261 )
3262 
3263 {
3264   CharPtr       accn;
3265   CharPtr PNTR  accns;
3266   Char          buf [64];
3267   Int4          gi;
3268   Int4Ptr       gis;
3269   FarIdData     fid;
3270   Int4          i, num, total = 0;
3271   SeqIdPtr      sip;
3272   ValNodePtr    vnp;
3273   SeqEntryPtr   oldsep;
3274 
3275   if (sep == NULL) return 0;
3276   MemSet ((Pointer) &fid, 0, sizeof (FarIdData));
3277 
3278   oldsep = SeqEntrySetScope (sep);
3279 
3280   if (components) {
3281     VisitBioseqsInSep (sep, (Pointer) &fid, LookupBioseqs);
3282   }
3283   if (locations) {
3284     VisitFeaturesInSep (sep, (Pointer) &fid, LookupLocations);
3285   }
3286   if (products) {
3287     VisitFeaturesInSep (sep, (Pointer) &fid, LookupProducts);
3288   }
3289   if (alignments) {
3290     VisitAlignmentsInSep (sep, (Pointer) &fid, LookupAlignments);
3291   }
3292   if (history) {
3293     VisitBioseqsInSep (sep, (Pointer) &fid, LookupHistory);
3294   }
3295   if (inference) {
3296     VisitFeaturesInSep (sep, (Pointer) &fid, LookupInference);
3297   }
3298   if (others) {
3299     VisitDescriptorsInSep (sep, (Pointer) &fid, LookupOthers);
3300   }
3301 
3302   if (fid.gis != NULL) {
3303     fid.gis = ValNodeSort (fid.gis, SortByIntvalue);
3304     fid.gis = UniqueIntValNode (fid.gis);
3305     fid.gis = FilterCachedGis (fid.gis);
3306     num = ValNodeLen (fid.gis);
3307 
3308     if (num > 0) {
3309       gis = (Int4Ptr) MemNew (sizeof (Int4) * (num + 2));
3310       if (gis != NULL) {
3311         for (vnp = fid.gis, i = 0; vnp != NULL; vnp = vnp->next, i++) {
3312           gi = (Int4) vnp->data.intvalue;
3313           if (gi < 1) continue;
3314           gis [i] = gi;
3315         }
3316         total += GiRevHistPreLoadSeqIdGiCacheEx (num, gis, FALSE);
3317         MemFree (gis);
3318       }
3319     }
3320   }
3321 
3322   if (fid.accns != NULL) {
3323     fid.accns = ValNodeSort (fid.accns, SortVnpBySeqId);
3324     fid.accns = UniqueSeqIdValNode (fid.accns);
3325     fid.accns = FilterCachedAccns (fid.accns);
3326     for (vnp = fid.accns; vnp != NULL; vnp = vnp->next) {
3327       sip = (SeqIdPtr) vnp->data.ptrvalue;
3328       if (sip == NULL) continue;
3329       SeqIdWrite (sip, buf, PRINTID_TEXTID_ACC_VER, sizeof (buf) - 1);
3330       ReplaceSpacesWithPluses (buf);
3331       vnp->data.ptrvalue = StringSave (buf);
3332     }
3333     num = ValNodeLen (fid.accns);
3334 
3335     if (num > 0) {
3336       accns = (CharPtr PNTR) MemNew (sizeof (CharPtr) * (num + 2));
3337       if (accns != NULL) {
3338         for (vnp = fid.accns, i = 0; vnp != NULL; vnp = vnp->next, i++) {
3339           accn = (CharPtr) vnp->data.ptrvalue;
3340           if (StringHasNoText (accn)) continue;
3341           accns [i] = accn;
3342         }
3343         total += AccnListPreLoadSeqIdGiCache (accns);
3344         MemFree (accns);
3345       }
3346     }
3347 
3348     for (vnp = fid.accns; vnp != NULL; vnp = vnp->next) {
3349       vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
3350     }
3351   }
3352 
3353   if (fid.strs != NULL) {
3354     fid.strs = ValNodeSort (fid.strs, SortVnpByString);
3355     fid.strs = UniqueValNode (fid.strs);
3356     fid.strs = FilterCachedStrs (fid.strs);
3357     num = ValNodeLen (fid.strs);
3358 
3359     if (num > 0) {
3360       accns = (CharPtr PNTR) MemNew (sizeof (CharPtr) * (num + 2));
3361       if (accns != NULL) {
3362         for (vnp = fid.strs, i = 0; vnp != NULL; vnp = vnp->next, i++) {
3363           accn = (CharPtr) vnp->data.ptrvalue;
3364           if (StringHasNoText (accn)) continue;
3365           accns [i] = accn;
3366         }
3367         total += AccnListPreLoadSeqIdGiCache (accns);
3368         MemFree (accns);
3369       }
3370     }
3371 
3372     for (vnp = fid.strs; vnp != NULL; vnp = vnp->next) {
3373       vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
3374     }
3375   }
3376 
3377   ValNodeFree (fid.gis);
3378   ValNodeFree (fid.accns);
3379   ValNodeFree (fid.strs);
3380 
3381   SeqEntrySetScope (oldsep);
3382   return total;
3383 }
3384 
3385 NLM_EXTERN SeqIdPtr LIBCALLBACK GiRevHistLookupSeqIdSet (
3386   Int4 gi
3387 )
3388 
3389 {
3390   return GiSeqIdSetSynchronousQuery (gi);
3391 }
3392 
3393 /* PubMed fetch functions */
3394 
3395 static PubmedEntryPtr LIBCALLBACK DoPubMedFetch (Int4 uid)
3396 
3397 {
3398   return PubMedSynchronousQuery (uid);
3399 }
3400 
3401 NLM_EXTERN Boolean PubMedFetchEnable (
3402   void
3403 )
3404 
3405 {
3406   PubMedSetFetchFunc (DoPubMedFetch);
3407   return TRUE;
3408 }
3409 
3410 NLM_EXTERN void PubMedFetchDisable (
3411   void
3412 )
3413 
3414 {
3415   PubMedSetFetchFunc (NULL);
3416 }
3417 
3418 

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.