home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / EXTRAS / WINWAIS / IR / MAIN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-18  |  27.6 KB  |  1,010 lines

  1. //================================================================
  2. //
  3. //  Wide Area Information Servers (WAIS)
  4. //  Windows Visual Basic Interface
  5. //
  6. //================================================================*/
  7.  
  8. #include <windows.h>
  9. #include <dos.h>
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <math.h>
  13.  
  14. #undef TRUE
  15. #undef FALSE
  16. #undef IGNORE
  17.  
  18. #include "cdialect.h"
  19. #include "wprot.h"
  20. #include "zutil.h"
  21. #include "ctype.h"
  22. #include "ui.h"
  23. #include "docid.h"
  24.  
  25. #define FD_SETSIZE 2
  26. #include "sockets.h"
  27.  
  28. #define MAX_DBNAME_LEN 50
  29. #define MAX_SERVER_LEN 30
  30. #define MAX_HEADLINE_LEN 100
  31. #define MAX_TYPE_LEN 100
  32. #define MAX_DOCID_LEN 600
  33.  
  34. // STRUCTURE DEFINITIONS
  35.  
  36. struct fdc
  37. {
  38.     long length;
  39.     int port;
  40.     int score;
  41.     int lines;
  42.     int source;
  43.     char *type;
  44.     any *ID;
  45.     char server[MAX_SERVER_LEN];
  46.     char dbname[MAX_DBNAME_LEN];
  47.     char headline[MAX_HEADLINE_LEN];
  48. };
  49.  
  50. typedef struct
  51. {
  52.   int score;
  53.   int source;
  54.   long length;
  55.   char type[MAX_TYPE_LEN];
  56.   char headline[MAX_HEADLINE_LEN];
  57. } DOC;
  58.  
  59. typedef struct
  60. {
  61.   long ch_start;
  62.   long ch_end;
  63.   long doc_size;
  64.   char type[MAX_TYPE_LEN];
  65.   char doc_bytes[MAX_DOCID_LEN];
  66. } REF;
  67.  
  68. // FUNCTION PROTOTYPE DEFINITIONS
  69.  
  70. int far pascal _export get_docid (int, REF*);
  71. int far pascal _export reference_titles (int, int, REF*);
  72. int far pascal _export query_titles (int, int, char*, char*, char*, long);
  73. int far pascal _export get_document (int, char*);
  74. int far pascal _export get_next_or_prev (char*, DOC*);
  75.  
  76. int far pascal _export set_tcp_stack(int);
  77. int far pascal _export dos_driver_loaded(char*);
  78. int far pascal _export set_ip_suffix(char*);
  79. int far pascal _export set_maxdocs(int);
  80. int far pascal _export set_path(char*, char*);
  81. long far pascal _export get_alloc_mem(void);
  82. int far pascal _export coprocessor_status(void);
  83.  
  84. // GLOBAL VARIABLES
  85.  
  86. unsigned int vb_data = 0;
  87. long allocated_memory = 0;
  88.  
  89. long host;
  90. int maxdocs;
  91.  
  92. #define MAXDOCS_LIMIT 100
  93. #define CURRDOC MAXDOCS_LIMIT * 2
  94.  
  95. struct fdc *srchinfo[MAXDOCS_LIMIT*2+1];
  96.  
  97. DocObj **Doc;
  98.  
  99. char far *inBuf;
  100. char far *outBuf;
  101.  
  102. char db_path[255];
  103. char temp_path[255];
  104.  
  105. char far *ip_suffix = "";
  106.  
  107. int count=0;
  108. int lcount=0;
  109.  
  110. SOCKET connection;
  111. int recv_bufsize;
  112. int send_bufsize;
  113.  
  114. int cmp(a,b)
  115. struct fdc **a,**b;
  116. {
  117.     return((*b)->score-(*a)->score);
  118. }
  119.  
  120. //*********************************************************************
  121. // Return a DocID from a source description to be used in future
  122. // relevance feedback functions
  123. //*********************************************************************
  124.  
  125. int far pascal _export
  126. get_docid(docno, ref_ptr)
  127. int docno;
  128. REF *ref_ptr;
  129. {
  130.     if (lcount == 0)
  131.       return (8); // No documents found
  132.     
  133.     if (docno > lcount - 1)
  134.       return (7); // Invalid document number
  135.     
  136.     if (srchinfo[docno]->ID->size > MAX_DOCID_LEN)
  137.       return(9);  // Docid too long
  138.  
  139.     ref_ptr->doc_size = srchinfo[docno]->ID->size;
  140.     memcpy(ref_ptr->doc_bytes, srchinfo[docno]->ID->bytes, ref_ptr->doc_size);
  141.     strncpy(ref_ptr->type, srchinfo[docno]->type, MAX_TYPE_LEN);
  142.  
  143.     return(0);
  144. }
  145.  
  146. //**********************************************************************
  147. //  Build a list of documents to use for relevance feedback when
  148. //  query_titles is called.
  149. //**********************************************************************
  150.  
  151. int far pascal _export
  152. reference_titles (refno, tot_ref, ref_ptr)
  153. int refno;
  154. int tot_ref;
  155. REF *ref_ptr;
  156. {
  157.     int i;
  158.     any* DocAny;
  159.     
  160.     if (refno == 0)
  161.     {
  162.       if (Doc != NULL)
  163.       {
  164.         for (i = 0; Doc[i] != NULL; i++)
  165.         {
  166.           Doc[i]->DocumentID->bytes = NULL; // bytes/type passed by VB, so
  167.           Doc[i]->Type = NULL;              // don't free bytes; DO free the
  168.           freeDocObj(Doc[i]);               // any and docobj
  169.         }
  170.         s_free(Doc);
  171.       }
  172.       Doc = (DocObj**) s_malloc((long)((tot_ref+1) * sizeof(char*)));
  173.     }
  174.  
  175.     DocAny = makeAny(ref_ptr->doc_size, ref_ptr->doc_bytes);
  176.  
  177.     if (ref_ptr->ch_start < 0)
  178.         Doc[refno] = makeDocObjUsingWholeDocument(DocAny, ref_ptr->type);
  179.     else
  180.         Doc[refno] = makeDocObjUsingLines(DocAny,
  181.                                           ref_ptr->type,
  182.                                           ref_ptr->ch_start,
  183.                                           ref_ptr->ch_end);
  184.  
  185.     Doc[refno + 1] = NULL;
  186.     return(0);
  187. }
  188.  
  189. //**********************************************************************
  190. //  Use a server_name, database and port to query servers and store
  191. //  returned titles.
  192. //**********************************************************************
  193.  
  194. int far pascal _export
  195. query_titles(func, tot_ref, server_name, database, keywords, port)
  196. int  func;
  197. int  tot_ref;
  198. char *server_name;
  199. char *database;
  200. char *keywords;
  201. long port;
  202. {
  203.     int i;
  204.     long max_length, inBuf_length;
  205.     static int source_id = -1;
  206.  
  207.     SearchResponseAPDU *query_response;
  208.     WAISSearchResponse *query_info;
  209.  
  210.     if (func == 0)
  211.     {
  212.       source_id = -1;
  213.       count = lcount = 0;
  214.     }
  215.  
  216.     source_id++;
  217.  
  218.     if (0 == strcmp(keywords,""))
  219.         keywords = NULL;
  220.     
  221.     if ((tot_ref == 0) && (Doc != NULL))
  222.     {
  223.         for (i = 0; Doc[i] != NULL; i++)
  224.         {
  225.           Doc[i]->DocumentID->bytes = NULL;  // bytes/type passed by VB, so 
  226.           Doc[i]->Type = NULL;               // don't free bytes, DO free the
  227.           freeDocObj(Doc[i]);                // any and docobj
  228.         }
  229.         s_free(Doc);
  230.         Doc = NULL;
  231.     }
  232.     
  233.     if (NULL == (connection = connect_to_server(server_name,port)))
  234.       return(2); // Server connection failed
  235.  
  236.     if (0 > (max_length=init_connection(inBuf,outBuf,(long)MAX_MESSAGE_LEN,connection)))
  237.     {  
  238.       close_connection_to_server(connection);
  239.       connection = NULL;
  240.       return(2);
  241.     }
  242.  
  243.     inBuf_length = max_length;
  244.  
  245.     if (NULL == generate_search_apdu((inBuf + HEADER_LENGTH),
  246.                                      (long *)&inBuf_length,
  247.                                      keywords,
  248.                                      database,
  249.                                      (long)Doc, // relevant documents
  250.                                      (long)maxdocs))
  251.     {    
  252.       close_connection_to_server(connection);
  253.       connection = NULL;
  254.       return(3); // Request too large
  255.     }
  256.  
  257.     if (0L == interpret_message(inBuf,
  258.                                 (long)(max_length - inBuf_length),
  259.                                 outBuf,
  260.                                 (long)max_length,
  261.                                 connection,
  262.                                 false))
  263.     {    
  264.       close_connection_to_server(connection);
  265.       connection = NULL;
  266.       return (4); // Returned message too large
  267.     }
  268.       
  269.     close_connection_to_server(connection);
  270.     connection = NULL;
  271.     
  272.     readSearchResponseAPDU(&query_response, outBuf + HEADER_LENGTH);
  273.  
  274.     query_info = (WAISSearchResponse *)query_response->DatabaseDiagnosticRecords;
  275.  
  276.     if(query_info->Diagnostics!=NULL)
  277.       return (5);
  278.  
  279.     if(query_response->NumberOfRecordsReturned > 0)
  280.       copy_query(query_info, server_name, database, port, source_id);
  281.     
  282.     freeWAISSearchResponse(query_response->DatabaseDiagnosticRecords);
  283.     freeSearchResponseAPDU(query_response);
  284.  
  285.     qsort(srchinfo, count, sizeof(struct fdc *), cmp);
  286.  
  287.     while (count > maxdocs)
  288.     {                                              
  289.       if (srchinfo[count] != NULL)                 
  290.       {                                             
  291.         if (srchinfo[count]->type != NULL)          
  292.           s_free(srchinfo[count]->type);            
  293.         if (srchinfo[count]->ID != NULL)
  294.           freeAny(srchinfo[count]->ID);
  295.         s_free(srchinfo[count]);            
  296.         srchinfo[count] = NULL;                     
  297.       }
  298.       count--;                                      
  299.     }                                               
  300.  
  301.     if (func == 2)
  302.     {
  303.       lcount = count;
  304.       count = 0;
  305.       source_id = -1;
  306.     }
  307.     
  308.     return (0);
  309. }
  310.  
  311. //**********************************************************************
  312. //  Get titles that were stored in response to query_titles()
  313. //**********************************************************************
  314.  
  315. int far pascal _export
  316. get_titles(docno, doc_ptr)
  317. int docno;
  318. DOC *doc_ptr;
  319. {
  320.     if (lcount == 0)
  321.         return (8); // No documents found
  322.     
  323.     if (docno > lcount - 1)
  324.         return (7); // Invalid document number
  325.     
  326.     doc_ptr->length = srchinfo[docno]->length;
  327.     doc_ptr->source = srchinfo[docno]->source;
  328.     doc_ptr->score = srchinfo[docno]->score;
  329.     strncpy(doc_ptr->type, srchinfo[docno]->type, MAX_TYPE_LEN);
  330.     strncpy(doc_ptr->headline, srchinfo[docno]->headline, MAX_HEADLINE_LEN);
  331.  
  332.     if (docno == (lcount-1))
  333.         return(1); // Last document number
  334.     
  335.     return(0);
  336. }
  337.  
  338. //**********************************************************************
  339. //  Get a document using the supplied document number and type
  340. //**********************************************************************
  341.  
  342. int far pascal _export
  343. get_document(docno, dtype)
  344. int docno;
  345. char *dtype;
  346. {
  347.     FILE *fp;
  348.     SearchResponseAPDU *retrieval_response;
  349.     diagnosticRecord **diag;
  350.     char server_name[MAX_SERVER_LEN];
  351.     char database[MAX_DBNAME_LEN];
  352.     long port;
  353.     long inBuf_length, max_length;
  354.     long len, tmplen, buf_pos;
  355.     long a, b;
  356.     long ch_start, ch_end;
  357.     long entry_no;
  358.     any* DocAny;
  359.     char work_file[255];
  360.     
  361.     char *oldType = NULL;
  362.     any  *oldID = NULL;
  363.  
  364.     int retcode = 0;
  365.  
  366.     if ( docno > lcount-1 && docno != CURRDOC)
  367.         return (7); // Invalid document number
  368.  
  369.     strncpy(server_name, srchinfo[docno]->server, MAX_SERVER_LEN);
  370.     strncpy(database, srchinfo[docno]->dbname, MAX_DBNAME_LEN);
  371.     port = srchinfo[docno]->port;
  372.     
  373.     if (NULL == (connection = connect_to_server(server_name, port)))
  374.       return(2); // Server connection failed
  375.  
  376.     if (0 > (max_length = init_connection(inBuf,
  377.                                           outBuf,
  378.                                           (long)MAX_MESSAGE_LEN,
  379.                                           connection)))
  380.     {  
  381.       close_connection_to_server(connection);
  382.       connection = NULL;
  383.       return(2);
  384.     }
  385.     
  386.     inBuf_length = (long)max_length;
  387.  
  388.     strcpy(work_file, temp_path);
  389.     strcat(work_file, "\\wais.$$$");
  390.     fp=fopen(work_file, "wb");
  391.  
  392.     entry_no = 0;
  393.  
  394.     //tmplen = srchinfo[docno]->length;
  395.     tmplen = CHARS_PER_PAGE;
  396.  
  397.     //for(buf_pos = 0L; buf_pos * CHARS_PER_PAGE < tmplen; buf_pos++)
  398.     for(buf_pos = 0L ;; buf_pos++)
  399.     {
  400.       char *type;
  401.  
  402.       inBuf_length = (long)max_length;
  403.       ch_start = (long)buf_pos * CHARS_PER_PAGE;
  404.       
  405.       //ch_end = MIN((buf_pos + 1) * CHARS_PER_PAGE, tmplen);
  406.       ch_end = (long)(buf_pos + 1) * CHARS_PER_PAGE;
  407.       
  408.       DocAny = makeAny(srchinfo[docno]->ID->size,
  409.                        srchinfo[docno]->ID->bytes); 
  410.       if (0L == generate_retrieval_apdu(inBuf + HEADER_LENGTH,
  411.                                         (long *)&inBuf_length,
  412.                                         DocAny,
  413.                                         (long)CT_byte,
  414.                                         (long)ch_start,
  415.                                         (long)ch_end,
  416.                                         dtype,
  417.                                         srchinfo[docno]->dbname))
  418.       {    
  419.         close_connection_to_server(connection);
  420.         connection = NULL;
  421.         return(3); // Request too large
  422.       }
  423.        
  424.       s_free(DocAny);
  425.  
  426.       if (0L == (len = interpret_message(inBuf,
  427.                                         (long)(max_length - inBuf_length),
  428.                                         outBuf,
  429.                                         (long)max_length,
  430.                                         connection,
  431.                                         false)))
  432.       {    
  433.         close_connection_to_server(connection);
  434.         connection = NULL;
  435.         return (4); // Returned message too large
  436.       }
  437.         
  438.       readSearchResponseAPDU(&retrieval_response, outBuf + HEADER_LENGTH);
  439.  
  440.       if (NULL == ((WAISSearchResponse *)retrieval_response->
  441.                                          DatabaseDiagnosticRecords)->
  442.                                          Text)
  443.         break;
  444.  
  445.       if(0 == strncmp(dtype,"TEXT",4) || 0 == strncmp(dtype,"WSRC",4))
  446.       {  
  447.         save_text_record_completely(((WAISSearchResponse *)retrieval_response->
  448.                                     DatabaseDiagnosticRecords)->Text[0],
  449.                                     false,
  450.                                     fp,
  451.                                     entry_no++);
  452.       }
  453.       else
  454.       {
  455.           save_binary_record_completely(((WAISSearchResponse *)retrieval_response->
  456.                                         DatabaseDiagnosticRecords)->Text[0],
  457.                                         fp);
  458.       }
  459.         
  460.       diag = ((WAISSearchResponse *)retrieval_response->
  461.               DatabaseDiagnosticRecords)->Diagnostics;
  462.         
  463.       if (diag != NULL)
  464.       {
  465.         if (0 != strncmp(diag[0]->DIAG, "SF", 2))
  466.           retcode = 5;
  467.         break;
  468.       }
  469.  
  470. //      if(len < CHARS_PER_PAGE)
  471. //        break;
  472.     }
  473.  
  474.     fclose(fp);
  475.     freeWAISSearchResponse(retrieval_response->DatabaseDiagnosticRecords);
  476.     freeSearchResponseAPDU(retrieval_response);
  477.     
  478.     close_connection_to_server(connection);
  479.     connection = NULL;
  480.  
  481.     if(retcode == 0)
  482.     {
  483.       if(srchinfo[CURRDOC] == NULL)
  484.         srchinfo[CURRDOC] = (struct fdc *)s_malloc((long)sizeof(struct fdc));
  485.       else
  486.       {
  487.         oldID = srchinfo[CURRDOC]->ID;  
  488.         oldType = srchinfo[CURRDOC]->type;
  489.       }
  490.       
  491.       srchinfo[CURRDOC]->ID = duplicateAny(srchinfo[docno]->ID);
  492.       srchinfo[CURRDOC]->type = s_strdup(srchinfo[docno]->type);
  493.       srchinfo[CURRDOC]->length = srchinfo[docno]->length;
  494.       srchinfo[CURRDOC]->port = srchinfo[docno]->port;
  495.       strncpy(srchinfo[CURRDOC]->server, srchinfo[docno]->server,
  496.               MAX_SERVER_LEN);   
  497.       strncpy(srchinfo[CURRDOC]->dbname, srchinfo[docno]->dbname,
  498.               MAX_DBNAME_LEN);   
  499.       srchinfo[CURRDOC]->score = srchinfo[docno]->score;
  500.       srchinfo[CURRDOC]->source = srchinfo[docno]->source;
  501.       strncpy(srchinfo[CURRDOC]->headline, srchinfo[docno]->headline,
  502.               MAX_HEADLINE_LEN);   
  503.     
  504.       if(oldID != NULL)
  505.         freeAny(oldID);
  506.       if(oldType != NULL)
  507.         s_free(oldType);
  508.     }
  509.  
  510.     return(retcode);
  511. }
  512.  
  513. //**********************************************************************
  514. //  Get next or previous
  515. //**********************************************************************
  516.  
  517. int far pascal _export
  518. get_next_or_prev(dtype, doc_ptr)
  519. char *dtype;
  520. DOC *doc_ptr; 
  521. {
  522.     SearchResponseAPDU *query_response;
  523.     WAISSearchResponse *query_info;
  524.     
  525.     char server_name[MAX_SERVER_LEN];
  526.     char database[MAX_DBNAME_LEN];
  527.     long port;
  528.     long source;
  529.     
  530.     long inBuf_length, max_length;
  531.     int save_count;
  532.  
  533.     static DocObj *thisDoc[2] = {NULL, NULL};
  534.     
  535.     if (thisDoc[0] != NULL)
  536.     {  
  537.       thisDoc[0]->Type = NULL;        // don't free, belongs to VB
  538.       thisDoc[0]->DocumentID = NULL;  // belongs to srchinfo[CURRDOC]
  539.       freeDocObj(thisDoc[0]);
  540.     }
  541.    
  542.     thisDoc[0] = makeDocObjUsingWholeDocument(srchinfo[CURRDOC]->ID, dtype); 
  543.     
  544.     strncpy(server_name, srchinfo[CURRDOC]->server, MAX_SERVER_LEN);
  545.     strncpy(database, srchinfo[CURRDOC]->dbname, MAX_DBNAME_LEN);
  546.     port = srchinfo[CURRDOC]->port;
  547.     source = srchinfo[CURRDOC]->source;
  548.  
  549.     if (NULL == (connection = connect_to_server(server_name, port)))
  550.       return(2); // Server connection failed
  551.  
  552.     if (0 > (max_length = init_connection(inBuf,
  553.                                           outBuf,
  554.                                           (long)MAX_MESSAGE_LEN,
  555.                                           connection)))
  556.     {  
  557.       close_connection_to_server(connection);
  558.       connection = NULL;
  559.       return(2);
  560.     }
  561.     
  562.     inBuf_length = (long) max_length;
  563.  
  564.     if (0L == generate_search_apdu(inBuf + HEADER_LENGTH,
  565.                                    (long *)&inBuf_length,
  566.                                    "foo",
  567.                                    database,
  568.                                    thisDoc, 
  569.                                    1L))
  570.     {    
  571.       close_connection_to_server(connection);
  572.       connection = NULL;
  573.       return(3); // Request too large
  574.     }
  575.         
  576.     if (0L == interpret_message(inBuf,
  577.                                 (long)(max_length - inBuf_length),
  578.                                 outBuf,
  579.                                 (long)max_length,
  580.                                 connection,
  581.                                 false))
  582.     {    
  583.       close_connection_to_server(connection);
  584.       connection = NULL;
  585.       return (4); // Returned message too large
  586.     }
  587.         
  588.     close_connection_to_server(connection);
  589.     connection = NULL;
  590.     
  591.     readSearchResponseAPDU(&query_response, outBuf + HEADER_LENGTH);
  592.  
  593.     query_info = (WAISSearchResponse *)query_response->
  594.                  DatabaseDiagnosticRecords;
  595.  
  596.     if(query_info->Diagnostics != NULL)
  597.       return(5);
  598.  
  599.     if(query_response->NumberOfRecordsReturned > 0)
  600.     {
  601.       save_count = count;
  602.       count = CURRDOC;
  603.       copy_query(query_info, server_name, database, port, source); 
  604.       count = save_count;
  605.     }
  606.  
  607.     doc_ptr->length = srchinfo[CURRDOC]->length;
  608.     doc_ptr->source = srchinfo[CURRDOC]->source;
  609.     doc_ptr->score = srchinfo[CURRDOC]->score;
  610.     strncpy(doc_ptr->type, srchinfo[CURRDOC]->type, MAX_TYPE_LEN);
  611.     strncpy(doc_ptr->headline, srchinfo[CURRDOC]->headline, MAX_HEADLINE_LEN);
  612.     
  613.     freeWAISSearchResponse(query_response->DatabaseDiagnosticRecords);
  614.     freeSearchResponseAPDU(query_response);
  615.     
  616.     return(0);
  617. }
  618.  
  619. copy_query(query_info, server_name, database, port, source_id)
  620. WAISSearchResponse *query_info;
  621. char *server_name;
  622. char *database;
  623. long port;
  624. int source_id;
  625. {
  626.     int tcnt;
  627.     char multi_types[MAX_TYPE_LEN];
  628.     int i=0;
  629.     
  630.     while(query_info->DocHeaders[i] != 0L)
  631.     {
  632.       if (query_info->DocHeaders[i]->DocumentLength != 0L)
  633.       {
  634.         if(srchinfo[count] ==NULL)
  635.           srchinfo[count] = (struct fdc *)s_malloc((long)sizeof(struct fdc));
  636.         else
  637.         {
  638.           if (srchinfo[count]->type != NULL)
  639.             s_free(srchinfo[count]->type);
  640.           if (srchinfo[count]->ID != NULL)
  641.             freeAny(srchinfo[count]->ID);
  642.         }
  643.         
  644.         srchinfo[count]->length = query_info->DocHeaders[i]->DocumentLength;
  645.  
  646.         if(srchinfo[count]->length != 0L)
  647.             srchinfo[count]->ID = duplicateAny(query_info->DocHeaders[i]->DocumentID);
  648.         strncpy(srchinfo[count]->dbname, database, MAX_DBNAME_LEN);
  649.         strncpy(srchinfo[count]->server, server_name, MAX_SERVER_LEN);
  650.         srchinfo[count]->port = port;
  651.         strncpy(srchinfo[count]->headline, trim_junk(query_info->DocHeaders[i]->Headline),MAX_HEADLINE_LEN);
  652.         srchinfo[count]->score = query_info->DocHeaders[i]->Score;
  653.         srchinfo[count]->source = source_id;
  654.  
  655.         if(query_info->DocHeaders[i]->Types == NULL)
  656.           srchinfo[count]->type = s_strdup("TEXT");
  657.         else
  658.         {
  659.           multi_types[0] = '\0';
  660.           for (tcnt = 0; query_info->DocHeaders[i]->Types[tcnt] != NULL; tcnt++) 
  661.           {
  662.             strcat(multi_types, query_info->DocHeaders[i]->Types[tcnt]);
  663.             strcat(multi_types, ",");
  664.           }
  665.           multi_types[strlen(multi_types)-1] = '\0';
  666.           srchinfo[count]->type = s_strdup(multi_types);
  667.         }
  668.         ++count;
  669.         if(count == 200)
  670.             break;
  671.       }
  672.       ++i;
  673.     }
  674. }
  675.  
  676. void msgbox(msg)
  677. char* msg;
  678. {
  679.   char buf[50];
  680.  
  681.   sprintf(buf, msg, WSAGetLastError());
  682.   MessageBox(GetFocus(), buf, "WinSock Error", MB_OK);
  683. }
  684.  
  685. int printf(ch, va_list)
  686. char *ch;              
  687. {                      
  688.     return(0);         
  689. }                      
  690.  
  691. int vprintf(fl, ch, va_list)
  692. FILE *fl;                   
  693. char *ch;                   
  694. {                           
  695.     return(0);              
  696. }                           
  697.  
  698. //*******************************************************************
  699. //
  700. //  MAP DRAWING ROUTINES
  701. //
  702. //*******************************************************************
  703.  
  704. #define PI      3.1415926535898
  705. #define TWOPI   6.2831853071796
  706. #define DEG2RAD .01745329251994
  707. #define MIN2RAD DEG2RAD / 60
  708.  
  709. typedef struct WDB
  710. {
  711.   int rec_type;
  712.   int lat;
  713.   int lon;
  714. } WDB;
  715.  
  716. int far pascal _export draw_map(int hDC, int globe, int grid, 
  717.            double ref_center_x, double ref_center_y, 
  718.            double ref_radius, double center_lon_rad, 
  719.            double sin_center_lat, double cos_center_lat);
  720.  
  721. void do_grid (int hDC, double ref_center_x, double ref_center_y, 
  722.            double ref_radius, double center_lon_rad, 
  723.            double sin_center_lat, double cos_center_lat);
  724.  
  725. int ortho (double inlat, double inlon, double* outx, double* outy, 
  726.            double ref_radius, double center_lon_rad, 
  727.            double sin_center_lat, double cos_center_lat);
  728.  
  729. int far pascal _export draw_map(hDC, globe, grid, ref_center_x, ref_center_y, ref_radius, center_lon_rad, sin_center_lat, cos_center_lat)
  730. int hDC;
  731. int globe;
  732. int grid;
  733. double ref_center_x;
  734. double ref_center_y;
  735. double ref_radius;
  736. double center_lon_rad;
  737. double sin_center_lat;
  738. double cos_center_lat;
  739. {
  740.     double atmp, outx, outy, inlat, inlon;
  741.     int oldx, oldy, x, y;
  742.     int i, first;
  743.     FILE *wdbfile;
  744.     WDB *wdb;
  745.  
  746.     // draw the outer circle for the globe into pixmap
  747.  
  748.     if (globe)
  749.     {
  750.       oldx = ref_center_x + ref_radius;
  751.       oldy = ref_center_y;
  752.  
  753.       for (i = 3; i < 360; i += 3)
  754.       {
  755.         atmp = i * DEG2RAD;
  756.         x = (cos(atmp) * ref_radius) + ref_center_x;
  757.         y = (sin(atmp) * ref_radius) + ref_center_y;
  758.         
  759.         SetTextColor(hDC, 0x00c0c0c0);
  760.         MoveTo(hDC, oldx, oldy);
  761.         LineTo(hDC, x, y);
  762.  
  763.         oldx = x;
  764.         oldy = y;
  765.       }
  766.     }
  767.  
  768.     // draw (10 degree) grid
  769.  
  770.     if (grid)
  771.       do_grid (hDC, ref_center_x, ref_center_y, ref_radius, center_lon_rad, sin_center_lat, cos_center_lat);
  772.     
  773.     // open World Data Bank II reference file
  774.  
  775.     if (NULL == (wdbfile = fopen("WDBIIDOS", "rb")))
  776.       return (1);
  777.  
  778.     wdb = s_malloc((long)sizeof(wdb));
  779.  
  780.     // draw World Data Bank II into pixmap
  781.  
  782.     first = TRUE;
  783.     
  784.     for (i = 0; i < 9182; i++)
  785.     {
  786.       fread (wdb, sizeof(int), 3, wdbfile);
  787.       
  788.       if (wdb->rec_type > 5)
  789.         first = TRUE;
  790.       
  791.       inlat = wdb->lat * MIN2RAD;
  792.       inlon = wdb->lon * MIN2RAD;
  793.  
  794.       if (0 == ortho(inlat, inlon, &outx, &outy, 
  795.                      ref_radius, center_lon_rad, 
  796.                      sin_center_lat, cos_center_lat))
  797.       {
  798.         x = outx + ref_center_x;
  799.         y = ref_center_y - outy;
  800.         if (first != TRUE)
  801.         {
  802.           SetTextColor(hDC, 0);
  803.           MoveTo(hDC, oldx, oldy);
  804.           LineTo(hDC, x, y);
  805.         }
  806.         first = FALSE;
  807.         oldx = x;
  808.         oldy = y;
  809.       }
  810.       else
  811.         first = TRUE;
  812.     }  
  813.       
  814.     fclose(wdbfile);
  815.     s_free(wdb);
  816.  
  817.     return(0);
  818. }
  819.     
  820. void do_grid (hDC, ref_center_x, ref_center_y, ref_radius, center_lon_rad, sin_center_lat, cos_center_lat)
  821. int hDC;
  822. double ref_center_x;
  823. double ref_center_y;
  824. double ref_radius;
  825. double center_lon_rad;
  826. double sin_center_lat;
  827. double cos_center_lat;
  828. {
  829.     double inlat, inlon, outx, outy;
  830.     int oldx, oldy, x, y;
  831.     int lat, longitude, pen_up;
  832.     
  833.     HPEN pen, old_pen;
  834.     
  835.     pen = CreatePen(PS_DOT, 1, 0x00c0c0c0);
  836.     old_pen = SelectObject(hDC, pen);
  837.     pen_up = TRUE;
  838.     
  839.     for (lat = 90; lat >= -90; lat -= 10)
  840.     {
  841.       inlat = lat * DEG2RAD;
  842.       for (longitude = -180; longitude <= 180; longitude += 5)
  843.       {  
  844.         inlon = longitude * DEG2RAD;
  845.         
  846.         if (0 == ortho(inlat, inlon, &outx, &outy, 
  847.                        ref_radius, center_lon_rad, 
  848.                        sin_center_lat, cos_center_lat))
  849.         {
  850.           x = outx + ref_center_x;
  851.           y = ref_center_y - outy;
  852.           if (!pen_up)
  853.           {
  854.             MoveTo(hDC, oldx, oldy);
  855.             LineTo(hDC, x, y);
  856.           }
  857.           oldx = x;
  858.           oldy = y;
  859.           pen_up = FALSE;
  860.         }
  861.         else
  862.           pen_up = TRUE;
  863.       }   
  864.       pen_up = TRUE;
  865.     }
  866.     
  867.     pen_up = TRUE;
  868.     
  869.     for (longitude = 180; longitude >= -180; longitude -= 10)
  870.     {
  871.       inlon = longitude * DEG2RAD;
  872.       for (lat = -90; lat <= 90; lat++)
  873.       {
  874.         inlat = lat * DEG2RAD;
  875.         if (0 == ortho(inlat, inlon, &outx, &outy, 
  876.                        ref_radius, center_lon_rad, 
  877.                        sin_center_lat, cos_center_lat))
  878.         {
  879.           x = outx + ref_center_x;
  880.           y = ref_center_y - outy;
  881.           if (!pen_up)
  882.           {
  883.             MoveTo(hDC, oldx, oldy);
  884.             LineTo(hDC, x, y);
  885.           }
  886.           oldx = x;
  887.           oldy = y;
  888.           pen_up = FALSE;
  889.         }
  890.         else
  891.           pen_up = TRUE;
  892.       }  
  893.       
  894.       pen_up = TRUE;
  895.     }
  896.     SelectObject(hDC, old_pen);
  897.     DeleteObject(pen);
  898. }    
  899.  
  900. int ortho (inlat, inlon, outx, outy, ref_radius, center_lon_rad, sin_center_lat, cos_center_lat)
  901. double inlat;
  902. double inlon;
  903. double *outx;
  904. double *outy;
  905. double ref_radius;
  906. double center_lon_rad;
  907. double sin_center_lat;
  908. double cos_center_lat;
  909. {
  910.  
  911.     double delta, cosL, cosC, sin_inlat, cos_inlat;
  912.  
  913.     delta = inlon - center_lon_rad;
  914.     
  915.     if (delta < -PI)
  916.       delta += TWOPI;
  917.     else if (delta > PI)
  918.       delta -= TWOPI;
  919.     
  920.     sin_inlat = sin(inlat);
  921.     cos_inlat = cos(inlat);
  922.     
  923.     cosL = cos(delta) * cos_inlat;
  924.     cosC = (sin_center_lat * sin_inlat) + (cos_center_lat * cosL);
  925.     
  926.     if (cosC >= 0) 
  927.     {
  928.       *outx = cos_inlat * sin(delta) * ref_radius;
  929.       *outy = ((cos_center_lat * sin_inlat) - (sin_center_lat * cosL)) * ref_radius;
  930.       return(0);
  931.     }
  932.  
  933.     return (-1);
  934. }
  935.  
  936.  
  937. //*******************************************************************
  938. //
  939. //  MISCELLANEOUS SUPPORT ROUTINES
  940. //
  941. //*******************************************************************
  942.  
  943. int far pascal _export set_maxdocs(int maximum)
  944. {
  945.     if (maximum <= MAXDOCS_LIMIT)
  946.       maxdocs = maximum;
  947.     else
  948.       maxdocs = MAXDOCS_LIMIT;
  949.     return(0);
  950. }
  951.  
  952. int far pascal _export set_path(path1, path2)
  953. char* path1;
  954. char* path2;
  955. {
  956.     strncpy(db_path, path1, sizeof(db_path));
  957.     strncpy(temp_path, path2, sizeof(temp_path));
  958.     vb_data = FP_SEG(db_path);
  959.     return(0);
  960. }
  961.  
  962. long far pascal _export get_alloc_mem()
  963. {
  964.   return(allocated_memory);
  965. }
  966.  
  967. int far pascal _export coprocessor_status()
  968. {
  969.   int stat;
  970.   
  971.   asm mov ax, 0e00h
  972.   asm int 31h  
  973.   asm mov stat, ax        
  974.   
  975.   return(stat & 4);
  976. }
  977.  
  978. //*******************************************************************
  979. //
  980. //  DLL ENTRY AND EXIT ROUTINES
  981. //
  982. //*******************************************************************
  983.  
  984. int far pascal LibMain (Instance, DataSeg, HeapSize, CmdLine)
  985. HANDLE Instance;
  986. WORD   DataSeg;
  987. WORD   HeapSize;
  988. LPSTR  CmdLine;
  989. {
  990.     Doc = NULL;
  991.     
  992.     s_meminit(3);
  993.     inBuf = s_malloc((long)MAX_MESSAGE_LEN); 
  994.     outBuf = s_malloc((long)MAX_MESSAGE_LEN);
  995.  
  996.     return(1);
  997. }
  998.  
  999. int far pascal WEP (iParam)
  1000. int iParam; 
  1001. {
  1002.   close_all_connections();
  1003.   s_free(inBuf);
  1004.   s_free(outBuf);
  1005.   s_memterm();
  1006.   return(1);
  1007. }
  1008.  
  1009.  
  1010.