/* vecscnapi.c * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information (NCBI) * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government do not place any restriction on its use or reproduction. * We would, however, appreciate having the NCBI and the author cited in * any work or product based on this material * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * =========================================================================== * * File Name: vecscnapi.c * * Author: Jonathan Kans * * Version Creation Date: 6/13/00 * * $Revision: 1.18 $ * * File Description: * * Modifications: * -------------------------------------------------------------------------- * * ========================================================================== */ #include #include #include #include #include #ifdef OS_MAC #include #endif static CharPtr ReadALine (CharPtr str, size_t size, FILE *fp) { Char ch; CharPtr ptr; CharPtr rsult; if (str == NULL || size < 1 || fp == NULL) return NULL; *str = '\0'; rsult = fgets (str, size, fp); if (rsult != NULL) { ptr = str; ch = *ptr; while (ch != '\0' && ch != '\n' && ch != '\r') { ptr++; ch = *ptr; } *ptr = '\0'; } return rsult; } NLM_EXTERN CONN VecScreenOpenConnection ( CharPtr query ) { /* return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 0, "/VecScreen/vecscreenQB.cgi", query, "vecscreenapp", 30, eMIME_T_NcbiData, eMIME_Fasta, eENCOD_Url, fHTTP_UrlDecodeInput | fHTTP_UrlEncodeOutput); */ StringCat (query, "\n"); return QUERY_OpenServiceQuery ("VecScreen", query, 30); } NLM_EXTERN EIO_Status VecScreenWaitForReply ( CONN conn ) { time_t currtime, starttime; time_t max = 0; EIO_Status status; STimeout timeout; #ifdef OS_MAC EventRecord currEvent; #endif if (conn == NULL) return eIO_Unknown; #ifdef OS_MAC timeout.sec = 0; timeout.usec = 0; #else timeout.sec = 100; timeout.usec = 0; #endif starttime = GetSecs (); while ((status = CONN_Wait (conn, eIO_Read, &timeout)) == eIO_Timeout && max < 300) { currtime = GetSecs (); max = currtime - starttime; #ifdef OS_MAC WaitNextEvent (0, &currEvent, 0, NULL); #endif } return status; } typedef struct VQueueTag { Char rid [64]; Char seqid [41]; time_t estTime; time_t initialTime; time_t postedTime; Int2 secondsToWait; VecScreenResultProc resultproc; VecScreenAnnounceProc announceproc; Nlm_VoidPtr userdata; QUEUE connqueue; Boolean done; struct VQueueTag* next; } VecScreenQueue, PNTR VQueuePtr; static Boolean LIBCALLBACK SecondVecScreenCallback ( CONN conn, Nlm_VoidPtr userdata, EIO_Status status ) { VQueuePtr cqp; FILE *fp; Char line [256]; Char path [PATH_MAX]; CharPtr rid; CharPtr sttus; CharPtr str; Boolean success = FALSE; Boolean waiting = FALSE; /* look for waiting, failure, or success */ cqp = (VQueuePtr) userdata; TmpNam (path); fp = FileOpen (path, "w"); QUERY_CopyResultsToFile (conn, fp); FileClose (fp); fp = FileOpen (path, "r"); str = ReadALine (line, sizeof (line), fp); while (str != NULL) { if (! StringHasNoText (line)) { if (line [0] == '>') { if (StringNICmp (line, ">Vector", 7) == 0) { rid = StringStr (line, "RID: "); if (rid != NULL) { rid += 5; sttus = StringStr (rid, " Status: "); if (sttus != NULL) { *sttus = '\0'; sttus += 9; if (StringCmp (cqp->rid, rid) != 0) { ErrPostEx (SEV_ERROR, 0, 0, "RID mismatch '%s' vs '%s'", cqp->rid, rid); cqp->done = TRUE; } else if (StringStr (sttus, "FAILED") != NULL) { cqp->done = TRUE; } else if (StringStr (sttus, "unknown") != NULL) { ErrPostEx (SEV_ERROR, 0, 0, "RID unknown '%s'", rid); cqp->done = TRUE; } else if (StringStr (sttus, "SUCCESS") != NULL) { success = TRUE; } else if (StringStr (sttus, "WAITING") != NULL) { waiting = TRUE; /* Message (MSG_POST, "WAITING"); */ } } } } else if (StringNICmp (line, ">Message", 8) == 0) { str = ReadALine (line, sizeof (line), fp); while (str != NULL && StringNCmp (line, "//", 2) != 0) { Message (MSG_POST, "%s\n", str); if (StringStr (line, "FAILURE") != NULL) { if (! waiting) { cqp->done = TRUE; } } str = ReadALine (line, sizeof (line), fp); } } } } str = ReadALine (line, sizeof (line), fp); } FileClose (fp); if (success) { cqp->resultproc (path, cqp->userdata, cqp->rid, cqp->seqid, success); cqp->done = TRUE; } else if (cqp->done) { cqp->resultproc (NULL, cqp->userdata, cqp->rid, cqp->seqid, success); } FileRemove (path); return TRUE; } static Boolean LIBCALLBACK FirstVecScreenCallback ( CONN conn, Nlm_VoidPtr userdata, EIO_Status status ) { VQueuePtr cqp; FILE *fp; Char line [256]; Char path [PATH_MAX]; CharPtr rid; CharPtr rtoe; CharPtr str; long int val; /* read rID or failure message */ cqp = (VQueuePtr) userdata; TmpNam (path); fp = FileOpen (path, "w"); QUERY_CopyResultsToFile (conn, fp); FileClose (fp); fp = FileOpen (path, "r"); str = ReadALine (line, sizeof (line), fp); while (str != NULL) { if (! StringHasNoText (line)) { if (line [0] == '>') { if (StringNICmp (line, ">Vector", 7) == 0) { rid = StringStr (line, "RID: "); if (rid != NULL) { rid += 5; rtoe = StringStr (rid, " RTOE: "); if (rtoe != NULL) { *rtoe = '\0'; rtoe += 7; StringNCpy_0 (cqp->rid, rid, sizeof (cqp->rid)); if (sscanf (rtoe, "%ld", &val) == 1) { cqp->estTime = (time_t) val; cqp->secondsToWait = (Int2) val + 2; } else { cqp->secondsToWait = 15; } if (cqp->secondsToWait > 15) { cqp->secondsToWait = 15; } if (cqp->announceproc != NULL) { cqp->announceproc (rid, cqp->seqid, (Int2) val); } } } else if (StringStr (line, "FAILED") != NULL) { cqp->done = TRUE; if (cqp->resultproc != NULL) { cqp->resultproc (NULL, cqp->userdata, cqp->rid, cqp->seqid, FALSE); } } } else if (StringNICmp (line, ">Message", 8) == 0) { str = ReadALine (line, sizeof (line), fp); while (str != NULL && StringNCmp (line, "//", 2) != 0) { Message (MSG_POST, "%s\n", str); if (StringStr (line, "FAILURE") != NULL) { cqp->done = TRUE; } str = ReadALine (line, sizeof (line), fp); } } } } str = ReadALine (line, sizeof (line), fp); } FileClose (fp); FileRemove (path); return TRUE; } static void VecScreen_AddToQueue ( VQUEUE * queue, VecScreenResultProc resultproc, VecScreenAnnounceProc announceproc, Nlm_VoidPtr userdata, CONN conn, BioseqPtr bsp ) { VQueuePtr cqp; VQueuePtr PNTR qptr; VQueuePtr tmp; if (queue == NULL || resultproc == NULL || conn == NULL || bsp == NULL) return; /* allocate queue element */ cqp = (VQueuePtr) MemNew (sizeof (VecScreenQueue)); if (cqp == NULL) return; cqp->rid [0] = '\0'; SeqIdWrite (bsp->id, cqp->seqid, PRINTID_FASTA_LONG, 40); cqp->estTime = 0; cqp->initialTime = GetSecs (); cqp->postedTime = cqp->initialTime; cqp->secondsToWait = 15; cqp->resultproc = resultproc; cqp->announceproc = announceproc; cqp->userdata = userdata; cqp->connqueue = NULL; cqp->done = FALSE; /* add to polling queue */ qptr = (VQueuePtr PNTR) queue; if (qptr != NULL) { if (*qptr != NULL) { tmp = *qptr; if (tmp != NULL) { while (tmp->next != NULL) { tmp = tmp->next; } tmp->next = cqp; } } else { *qptr = cqp; } } /* queue the request for a rID */ QUERY_AddToQueue (&(cqp->connqueue), conn, FirstVecScreenCallback, (Pointer) cqp, TRUE); } NLM_EXTERN Boolean VecScreenAsynchronousRequest ( CharPtr database, BioseqPtr bsp, VQUEUE* queue, VecScreenResultProc resultproc, VecScreenAnnounceProc announceproc, VoidPtr userdata ) { CONN conn; FILE *fp; Char path [PATH_MAX]; Char str [128]; if (bsp == NULL || queue == NULL || resultproc == NULL) return FALSE; if (StringHasNoText (database)) { database = "UniVec"; } sprintf (str, "db=%s", database); conn = VecScreenOpenConnection (str); if (conn == NULL) return FALSE; TmpNam (path); fp = FileOpen (path, "w"); BioseqToFasta (bsp, fp, ISA_na (bsp->mol)); FileClose (fp); fp = FileOpen (path, "r"); QUERY_CopyFileToQuery (conn, fp); FileClose (fp); QUERY_SendQuery (conn); VecScreen_AddToQueue (queue, resultproc, announceproc, userdata, conn, bsp); FileRemove (path); return TRUE; } static void VecScreen_RemoveFromQueue ( VQUEUE* queue, VQueuePtr freeme ) { VQueuePtr curr; VQueuePtr next; VQueuePtr PNTR prev; VQueuePtr PNTR qptr; qptr = (VQueuePtr PNTR) queue; if (qptr == NULL || *qptr == NULL || freeme == NULL) return; prev = qptr; curr = *qptr; while (curr != NULL) { next = curr->next; if (curr == freeme) { *(prev) = next; curr->next = NULL; MemFree (curr); } else { prev = &(curr->next); } curr = next; } } NLM_EXTERN Int4 VecScreenCheckQueue ( VQUEUE* queue ) { CONN conn; Nlm_Int4 count = 0; VQueuePtr curr; time_t currtime; VQueuePtr next; VQueuePtr PNTR qptr; Char str [128]; qptr = (VQueuePtr PNTR) queue; if (qptr == NULL || *qptr == NULL) return 0; curr = *qptr; while (curr != NULL) { next = curr->next; /* check for return of rID, WAITING, of SUCCESS message */ QUERY_CheckQueue (&(curr->connqueue)); if (curr->done) { VecScreen_RemoveFromQueue (queue, curr); } else { if (curr->connqueue == NULL) { currtime = GetSecs (); if (currtime - curr->postedTime < curr->secondsToWait) { } else if (! StringHasNoText (curr->rid)) { /* estimated wait time has expired, so queue another check */ if (curr->secondsToWait < 300) { curr->secondsToWait *= 2; if (curr->secondsToWait > 300) { curr->secondsToWait = 300; } } curr->postedTime = GetSecs (); sprintf (str, "req=%s", curr->rid); conn = VecScreenOpenConnection (str); QUERY_SendQuery (conn); QUERY_AddToQueue (&(curr->connqueue), conn, SecondVecScreenCallback, (Pointer) curr, TRUE); } } count++; } curr = next; } return count; } NLM_EXTERN Int4 PrintVecScreenQueue ( VQUEUE* queue, FILE *fp ) { Nlm_Int4 count = 0; VQueuePtr curr; time_t currtime; VQueuePtr next; VQueuePtr PNTR qptr; qptr = (VQueuePtr PNTR) queue; if (qptr == NULL || *qptr == NULL || fp == NULL) return 0; currtime = GetSecs (); curr = *qptr; while (curr != NULL) { next = curr->next; if (! curr->done) { fprintf (fp, "%s\t%s\t%d\t%d\n", curr->rid, curr->seqid, (int) (currtime - curr->initialTime), (int) curr->estTime); count++; } curr = next; } return count; }