home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Unix / gopher+1.2b4 / gopherd / Waisindex.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-09  |  11.6 KB  |  461 lines

  1. /********************************************************************
  2.  * lindner
  3.  * 3.3
  4.  * 1993/04/09 16:24:03
  5.  * /home/mudhoney/GopherSrc/CVS/gopher+/gopherd/Waisindex.c,v
  6.  * Exp
  7.  *
  8.  * Paul Lindner, University of Minnesota CIS.
  9.  *
  10.  * Copyright 1991, 1992 by the Regents of the University of Minnesota
  11.  * see the file "Copyright" in the distribution for conditions of use.
  12.  *********************************************************************
  13.  * MODULE: Waisindex.c
  14.  * Routines to translate wais indexes on disk to gopher
  15.  *********************************************************************
  16.  * Revision History:
  17.  * Waisindex.c,v
  18.  * Revision 3.3  1993/04/09  16:24:03  lindner
  19.  * Hacks to support WAIS GIF, TIFF, DVI types
  20.  *
  21.  * Revision 3.2  1993/03/26  19:46:52  lindner
  22.  * First crack at gopherplussing Indexing
  23.  *
  24.  * Revision 3.1.1.1  1993/02/11  18:02:50  lindner
  25.  * Gopher+1.2beta release
  26.  *
  27.  * Revision 1.5  1993/01/30  23:55:36  lindner
  28.  * Better error messages, changed a uchdir to a rchdir
  29.  *
  30.  * Revision 1.4  1993/01/05  02:41:28  lindner
  31.  * .cap files are now ignored by the indexer
  32.  *
  33.  * Revision 1.3  1993/01/01  00:12:41  lindner
  34.  * Fixed parameters to GDnew()
  35.  *
  36.  * Revision 1.2  1992/12/21  20:36:44  lindner
  37.  * Added #include for cutil.h (from dgg)
  38.  *
  39.  * Revision 1.1  1992/12/10  23:13:27  lindner
  40.  * gopher 1.1 release
  41.  *
  42.  *
  43.  *********************************************************************/
  44.  
  45. #if defined(WAISSEARCH)
  46.  
  47. /* WIDE AREA INFORMATION SERVER SOFTWARE
  48.    No guarantees or restrictions.  See the readme file for the full standard
  49.    disclaimer.    
  50.    Brewster@think.com
  51.  
  52.    Heavily hacked by Paul Lindner (lindner@boombox.micro.umn.edu)
  53.    Do you even recognize this Brewster? :-)
  54.  
  55. */
  56.  
  57. int ShowDate = 0;
  58.  
  59. #define _search_c
  60.  
  61. #include "gopherd.h"
  62.  
  63.  
  64. #if defined(_AIX)
  65. #define ANSI_LIKE
  66. #endif
  67.  
  68. #include "../ir/irext.h"
  69. #include "../ir/irsearch.h"
  70. #include "../ir/docid.h"
  71. #include "../ir/irtfiles.h"
  72. #include "../ir/cutil.h"    /** fix for -DBIO wais needs.. **/
  73. #include <math.h>
  74.  
  75.  
  76. FILE *logfile = NULL; /* the logfile */
  77. char *log_file_name = NULL;
  78.  
  79. static char *DefaultDB = "index";
  80. static char *MonthStr[] = {
  81.      "Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Sept", "Oct",
  82.       "Nov", "Dec"
  83. };
  84.  
  85. #if defined(void)
  86. #undef void
  87. #endif
  88.  
  89.  
  90.  
  91. int
  92. Process_Veronica(besthit, gs)
  93.   hit *besthit;
  94.   GopherObj *gs;
  95. {
  96.      FILE *ZeFile;
  97.      char veronicabuf[1024];
  98.      char *data, *cp;
  99.  
  100.      /*** Open up the file and seek to the right position ***/
  101.  
  102.      ZeFile = ufopen(besthit->filename, "r");
  103.  
  104.      if (ZeFile == NULL)
  105.       return(-1);
  106.  
  107.      fseek(ZeFile, besthit->start_character, 0);
  108.  
  109.      bzero(veronicabuf, sizeof(veronicabuf));
  110.      fread(veronicabuf, 1, besthit->end_character - besthit->start_character,
  111.        ZeFile);
  112.      veronicabuf[besthit->end_character - besthit->start_character+1] = '\0';
  113.      
  114.      
  115.      data = veronicabuf;
  116.      GSsetType(gs, *data);
  117.      
  118.      ZapCRLF(data);
  119.      
  120.      cp = strchr(data, '\t');
  121.      *cp = '\0';
  122.      GSsetTitle(gs, data+1);
  123.      
  124.      data = cp+1;
  125.      cp = strchr(data, '\t');
  126.      *cp = '\0';
  127.      GSsetPath(gs, data);
  128.      
  129.      data = cp + 1;
  130.      cp = strchr(data, '\t');
  131.      *cp = '\0';
  132.      GSsetHost(gs, data);
  133.      
  134.      GSsetPort(gs, atoi(cp+1));
  135.  
  136.      fclose(ZeFile);
  137.      return(0);
  138. }
  139.  
  140. void
  141. WaisIndexQuery(sockfd, index_directory, SearchWords, new_db_name, INDEXHost, INDEXPort, INDEXPath, isgplus, view)
  142.   int sockfd;
  143.   char *index_directory;
  144.   char *SearchWords;
  145.   char *new_db_name;
  146.   char *INDEXHost;
  147.   int  INDEXPort;
  148.   char *INDEXPath;
  149.   boolean isgplus;
  150.   char *view;
  151.      database*            db;
  152.      long                 maxRawScore, normalScore, i;
  153.      char                 *cp, *Selstrout;
  154.      char                 dateline[10];
  155.      query_parameter_type parameters;
  156.      boolean              search_result;
  157.      char                 score[6];
  158.      char                 ReturnLine[512];
  159.      boolean              plusdirs=FALSE;
  160.                                         
  161.      char                 * sidename;    /* mtm 11-23-92 */
  162.      FILE                 * SideFile = NULL;  /* mtm 11-23-92 */
  163.  
  164.      GopherDirObj         *gd;
  165.      GopherObj            *gs;
  166.      
  167.  
  168.      gs = GSnew();
  169.      gd = GDnew(32);
  170.  
  171.      if (DEBUG)  {
  172.       fprintf(stderr, "IndexPath: %s\n", INDEXPath);
  173.       logfile = stderr;   /** Log wais error messages to console **/
  174.      }     else {
  175.       logfile = ufopen("/dev/null", "w+");
  176.      }
  177.  
  178.      if (new_db_name == NULL) {
  179.       new_db_name = DefaultDB;
  180.      }
  181.      if (view != NULL) {
  182.       if (strcasecmp(view, "Directory+")==0)
  183.            plusdirs = TRUE;
  184.      }
  185.  
  186.  
  187.      if (rchdir(index_directory)) {
  188.       char tmpstr[512];
  189.  
  190.       sprintf(tmpstr, "Couldn't change to index directory '%s'",index_directory);
  191.       Abortoutput(sockfd, tmpstr);
  192.       return;
  193.      }
  194.  
  195.      if (SearchWords != NULL && strlen(SearchWords) == 0) {
  196.       EveryWAISdocument(new_db_name);
  197.       return;
  198.      }
  199.  
  200.      db = openDatabase(new_db_name, false, true);
  201.      
  202.      if (db == NULL) {
  203.       sprintf(ReturnLine, "Failed to open database %s in index dir %s", new_db_name, index_directory);
  204.       Abortoutput(sockfd, ReturnLine);
  205.       writestring(sockfd, ".\r\n"); /** be polite **/
  206.       return;
  207.      }
  208.      
  209. #ifdef BIO            /* dgg */
  210. {
  211.      char *cp= read_delimiters( db);  /* use data-specific delim, available */
  212.  
  213.      if (cp != NULL) {
  214.       strcpy( gDelimiters, cp);
  215.       wordDelimiter= wordbreak_user;
  216.      }
  217.      else
  218.       wordDelimiter= wordbreak_notalnum;
  219. }
  220. #endif
  221.  
  222.      parameters.max_hit_retrieved = 256;
  223.  
  224.      set_query_parameter(SET_MAX_RETRIEVED_MASK, ¶meters);
  225.      
  226.      search_result = false;
  227.      search_result |= search_for_words(SearchWords, db, 0);
  228.      
  229.      if (search_result == true) {
  230.       /* the search went ok */
  231.       hit best_hit;
  232.       
  233.       finished_search_word(db);
  234.       if (DEBUG)
  235.            printf("After finished_search\n");
  236.  
  237.       uchdir(Data_Dir); /* necessary to find side files */
  238.  
  239.       if (view != NULL)
  240.            GSsendHeader(sockfd, -1);
  241.  
  242.       for (i = 0; i < parameters.max_hit_retrieved; i++){ 
  243.            if (0 != next_best_hit(&best_hit, db))
  244.             break;        /* out of hits */
  245.            if (i == 0)
  246.             maxRawScore = best_hit.weight;
  247.            if (best_hit.weight > 0 && 
  248.            strstr(best_hit.filename, ".cache")==NULL &&
  249.            strstr(best_hit.filename, ".cap/")==NULL){
  250.             long lines,length;
  251.  
  252.             char** type = NULL;
  253.             
  254.             normalScore = (long)floor((((double)best_hit.weight) /
  255.                            ((double)maxRawScore)) *    
  256.                           (MAX_NORMAL_SCORE + 1));
  257.  
  258.             if (normalScore > MAX_NORMAL_SCORE)
  259.              normalScore = MAX_NORMAL_SCORE;
  260.             
  261.  
  262.             /*** Strip off the first part of the path in the filename*/
  263.             /*** Plus it gets rid of weird automount things... ***/
  264.             Selstrout =strstr(best_hit.filename, INDEXPath);
  265.             if (Selstrout == NULL)
  266.              Selstrout = "Error in Hostdata!";
  267.             else
  268.              Selstrout += strlen(INDEXPath);
  269.             
  270.  
  271.                     sprintf(score,"%3d ",best_hit.weight);
  272.  
  273.                     waislog(0,99,"%s: Score %3d:%s",SearchWords,best_hit.weight,Selstrout);
  274.             
  275.             /** Make the outgoing string **/
  276.  
  277.             ZapCRLF(best_hit.headline);
  278.             
  279.             /*** Remove the gopher data directory pathname if
  280.                  it's there from the headline
  281.             ***/
  282.  
  283.             if ((cp = strstr(best_hit.headline, INDEXPath)) != NULL) {
  284.              /*** Dangerous.... ***/
  285.              strcpy(cp, cp+strlen(INDEXPath));
  286.             } 
  287.              
  288.             if ((strstr(best_hit.type, "PS") != NULL)
  289.             || (strstr(best_hit.type, "DVI") != NULL)
  290.             || (strstr(best_hit.type, "GIF") != NULL)
  291.             || (strstr(best_hit.type, "TIFF") != NULL))
  292.              GSsetType(gs, A_IMAGE);
  293.             else
  294.              GSsetType(gs, A_FILE);
  295.  
  296.             GSsetTitle(gs, best_hit.headline);
  297.             GSsetHost(gs, INDEXHost);
  298.             GSsetPort(gs, INDEXPort);
  299.  
  300.                  /* removed "/" from following line (before %s) . 
  301.                 Was getting double slash at least with w8b5bio; 
  302.                 mtm 11-23-92 */
  303.  
  304.             sprintf(ReturnLine, "R%d-%d-%s",
  305.                 best_hit.start_character, best_hit.end_character,
  306.                 Selstrout);
  307.             
  308.             if (!MacIndex)
  309.             GSsetPath(gs, ReturnLine);
  310.             else
  311.             GSsetPath(gs, Selstrout);
  312.             GSsetWeight(gs, best_hit.weight);
  313.             
  314.                     /* 
  315.              * Find and process sidefile. 
  316.              * Allow worst case name length. 
  317.              */
  318.  
  319.             if((sidename = (char *) malloc((unsigned) 
  320.                 strlen(Selstrout) + 
  321.                     strlen("/.cap/") + 1)) != NULL) {
  322.               if((cp = mtm_basename(Selstrout)) != Selstrout) {
  323.             /*  turn "/foo/bar/baz" into "/foo/bar/.cap/baz" */
  324.             strncpy(sidename,Selstrout,(cp - Selstrout));
  325.             *(sidename + (cp - Selstrout)) = '\0';
  326.             strcat(sidename,".cap/");
  327.             strcat(sidename,cp);
  328.               }
  329.               else {
  330.               /* root of the gopher tree, this is easier... */
  331.             strcpy(sidename,"/.cap/");
  332.             strcat(sidename,Selstrout);
  333.               }
  334.               if ((SideFile = rfopen(sidename, "r")) != NULL) {
  335.             if (DEBUG == TRUE)
  336.               printf("Side file name: %s\n", sidename);
  337.             Process_Side(SideFile, gs);
  338.               }
  339.               free(sidename);
  340.             }
  341.             
  342.             if (DEBUG) printf("Doc type is %s\n", best_hit.type);
  343.             if (strcmp(best_hit.type, "GOPHER")==0) {
  344.             if (DEBUG) printf("Got a veronica style thing %s\n",best_hit.headline);
  345.             Process_Veronica(&best_hit, gs);
  346.            }            
  347.             
  348.             if (isgplus)
  349.              GSplustoNet(gs, sockfd, NULL);
  350.             else
  351.              GStoNet(gs,sockfd);
  352.            }
  353.            
  354.            
  355.            if (DEBUG) {
  356.             printf("%s\n", ReturnLine);
  357.             printf("End Byte   = %d\n", best_hit.end_character);
  358.             printf("Doc length = %d\n", best_hit.document_length);
  359.             printf("#lines     = %d\n", best_hit.number_of_lines);
  360.            }
  361.       }
  362.      }
  363.      else {
  364.       /* something went awry in the search */
  365.       LOGGopher(sockfd, "Something went wrong in the search!\r\n");
  366.       writestring(sockfd, ".\r\n"); /*** be polite, don't screw up the client**/
  367.       return;
  368.      }
  369.      finished_best_hit(db);
  370.  
  371.      writestring(sockfd, ".\r\n");
  372.  
  373.      /* free everything */
  374.      closeDatabase(db);
  375.      return;
  376. }
  377.  
  378. EveryWAISdocument(sockfd, db, INDEXHost, INDEXPort, INDEXPath)
  379.   int sockfd;
  380.   char *db;
  381.   char *INDEXHost;
  382.   int  INDEXPort;
  383.   char *INDEXPath;
  384. {
  385.      FILE         *dbcatalog;
  386.      char         db_name[MAXPATHLEN];
  387.      char         inputline[512];
  388.      String       *Headline;
  389.      String       *Filename;
  390.      int          StartByte, EndByte;
  391.      GopherObj    *gs;
  392.      GopherDirObj *gd;
  393.      boolean      Headlineset = FALSE;
  394.      boolean      DocIDset    = FALSE;
  395.  
  396.      gs = GSnew();
  397.      gd = GDnew(32);
  398.      Headline = STRnew();
  399.      Filename = STRnew();
  400.  
  401.      strcpy(db_name, db);
  402.      strcat(db_name, ".cat");
  403.  
  404.      dbcatalog = rfopen(db_name, "r");
  405.      
  406.      while (fgets(inputline, sizeof(inputline), dbcatalog) != NULL) {
  407.       if (strncmp(inputline, "Headline: ", 10)==0) {
  408.            STRset(Headline, inputline +10);
  409.            Headlineset = TRUE;
  410.       }
  411.       else if (strncmp(inputline, "DocID: ", 7)==0) {
  412.            char *cp;
  413.  
  414.            StartByte = atoi(inputline);
  415.            cp = strchr(inputline+7, ' ');
  416.            if (cp == NULL) break;
  417.  
  418.            cp++;
  419.            EndByte = atoi(cp);
  420.  
  421.            cp = strchr(inputline+7, ' ');
  422.            cp++;
  423.            if (cp == NULL) break;
  424.  
  425.            cp =strstr(cp, INDEXPath);
  426.            if (cp == NULL) break;
  427.            
  428.            STRset(Filename, cp);
  429.  
  430.            DocIDset = TRUE;
  431.       }
  432.       
  433.       if (DocIDset == TRUE && Headlineset == TRUE) {
  434.            char tmppath[512];
  435.            Extobj *ext = EXnew();
  436.  
  437.            if (GDCBlockExtension(Config, STRget(Filename), ext)) {
  438.             GSsetType(gs, EXgetObjtype(ext));
  439.            } else
  440.             GSsetType(gs, '0');
  441.             
  442.            EXdestroy(ext);
  443.  
  444.            sprintf(tmppath, "R%d-%d-%s", StartByte, EndByte, STRget(Filename));
  445.  
  446.            GSsetTitle(gs, STRget(Headline));
  447.            GSsetHost(gs, INDEXHost);
  448.            GSsetPort(gs, INDEXPort);
  449.            GSsetPath(gs, tmppath);
  450.  
  451.            GDaddGS(gd, gs);
  452.  
  453.            DocIDset = FALSE;
  454.            Headlineset = FALSE;
  455.       }
  456.      }      
  457. }
  458.  
  459. #endif /** WAISSEARCH **/
  460.