Changeset 1191 for branches


Ignore:
Timestamp:
2000-05-25T11:28:32+12:00 (24 years ago)
Author:
johnmcp
Message:

Checkpoint: z39.50 collections can now connect and query (and show query
results). Todo: get individual documents, and get working under fast-cgi.

Location:
branches/z3950-branch/gsdl/src/recpt
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • branches/z3950-branch/gsdl/src/recpt/parse.fl

    r1174 r1191  
    2828    int string_len;
    2929
    30 {COMMENT}       lineno++;yylval.string=yytext;
     30{COMMENT}       lineno++;/*yylval.string=yytext;*/yyleng=0;
    3131,           return (',');
    3232:           return (':');
     
    6666\"          {string=NULL;BEGIN(STRINGCOND);}
    6767<STRINGCOND>{
    68   ([^\"\\])*        {/* append this to our current string */
     68  ([^\"\\\n])*      {/* append this to our current string EXC NEWLINE */
     69            if (string==NULL) string_len=0; else
     70            string_len=strlen(string);
     71            string=realloc(string,string_len+strlen(yytext)+1);
     72            /* +1 is for trailing \0 */
     73            strcpy(string+string_len,yytext);
     74            }
     75  ([^\"\\])*\n      {/* append this to our current string - INC NEWLINE */
     76            lineno++;
    6977            if (string==NULL) string_len=0; else
    7078            string_len=strlen(string);
     
    8896            }
    8997}
    90 [[:alnum:]@\.]+     yylval.string=strdup(yytext);return (DATA);
     98[[:alnum:]@\.-]+    yylval.string=strdup(yytext);return (DATA);
    9199(" "|\t)        ;
    92100(\n|\r)         lineno++;
  • branches/z3950-branch/gsdl/src/recpt/z3950proto.cpp

    r1174 r1191  
    55#include "z3950proto.h"
    66#include "comtypes.h"
    7 #include <stdio.h>
     7#include "browsefilter.h"
     8#include "queryfilter.h"
     9#include "filter.h"
    810// z39.50 yaz stuff
    9 
    10 
     11#include <stdio.h> // for (FILE *) type for yyin and fopen.
    1112// config file parsing stuff
    1213#include "z3950cfg.h" // for reading in config files -
     
    1718}
    1819
     20
     21
     22
    1923z3950proto::z3950proto() {
    2024  zserver_count=0;
     
    2428}
    2529
    26 void z3950proto::add_server (const z3950_server& zserver) {
     30void z3950proto::add_server (z3950_server& zserver) {
    2731
    2832  // append the new server
    2933  zserver_count++;
    30   zservers.push_back(zserver);
     34  zservers.push_back(&zserver);
    3135}
    3236
     
    6771    if (here->smallicon!=NULL)
    6872      zserver->setMeta("iconcollectionsmall",here->smallicon);
    69     if (0) {
    70       cerr << "creating metadata:\n\tcolname is " << here->longname
    71        << "\n\ticoncollection is " << here->icon
    72        << "\n  and\ticoncollectionsmall is " << here->smallicon
    73        << "\n";
    74     }
     73   
     74    /*    filterclass *filter = new filterclass ();
     75      zserver->add_filter (filter);
     76      browsefilterclass *browsefilter = new browsefilterclass();
     77      zserver->add_filter (browsefilter);
     78      queryfilterclass *queryfilter = new queryfilterclass();
     79      zserver->add_filter (queryfilter);
     80    */
    7581
    7682    // About list
     
    8086
    8187      while (about_here!=NULL) {
    82     // problem with default lang (null):
     88    // problem with default lang (null): can't add ("",..)
    8389    if (about_here->lang==NULL)
    84       zserver->addAbout("en",about_here->text);
     90      zserver->addcfgAbout("en",about_here->text);
    8591    else
    86       zserver->addAbout(about_here->lang, about_here->text);
     92      zserver->addcfgAbout(about_here->lang, about_here->text);
    8793    oldabout=about_here;
    8894    about_here=about_here->next;
     
    103109    free(oldhere);
    104110
    105 
    106111    add_server(*zserver);
    107     /* assume that the push_back operator creates a copy.
    108        BUT: doesn't create copies of structures pointed to... only
    109        creates a copy of the pointer (to the same location!) */
    110112  } // end of while loop.
    111113
     
    155157  z3950_server_array::iterator end = zservers.end();
    156158  while (here != end) {
    157     collist.push_back(here->getName());
     159    collist.push_back((*here)->getName());
    158160    //const ShortColInfo_t *info=here->getInfo();
    159161    //collist.push_back(info->name);
     
    167169  z3950_server_array::iterator end = zservers.end();
    168170  while (here != end) {
    169     if(here->getName()==collection) {
     171    if((*here)->getName()==collection) {
    170172      hascollection=true;
    171173      return;
     
    192194  z3950_server_array::iterator end = zservers.end();
    193195  while (here != end) {
    194     if(here->getName()==collection) {
     196    if((*here)->getName()==collection) {
    195197      break;
    196198    }
     
    208210  }
    209211
    210   const ShortColInfo_t *colinfo=here->getInfo();
     212  const ShortColInfo_t *colinfo=(*here)->getInfo();
    211213  collectinfo.shortInfo.name=colinfo->name;
    212214  collectinfo.shortInfo.host=colinfo->host;
     
    219221  // leave ccsCols empty (no cross-coll. searching - for now)
    220222  /*collectinfo.ccsCols=(text_tarray);*/ //not like this!!!
    221   // This info is available from the config file -- johnmcp */
    222   collectinfo.languages.push_back("en");
    223   collectinfo.languages.push_back("fr");
     223  // This info is available from the config file -- johnmcp
     224  /*******collectinfo.languages.push_back("en");
     225      collectinfo.languages.push_back("fr");********/
    224226  collectinfo.numDocs=0;
    225227  collectinfo.numWords=0;
     
    227229  // copy the text maps over.
    228230  //  collectinfo.collectionmeta; // text_tmap
    229   collectinfo.collectionmeta=*(here->getMeta());
     231  collectinfo.collectionmeta=*((*here)->getMeta());
    230232  /* collectinfo.format; //text_tmap
    231233    collectinfo.building; //text_tmap
     
    239241
    240242void z3950proto::get_filterinfo (const text_t &/*collection*/,
    241                  InfoFiltersResponse_t &/*response*/,
     243                 InfoFiltersResponse_t &response,
    242244                 comerror_t &/*err*/, ostream &/*logout*/) {
    243 
     245  // we'll fake it here, and say we have set up some filters
     246  response.filterNames.insert("BrowseFilter");
     247  response.filterNames.insert("QueryFilter");
     248  response.filterNames.insert("NullFilter");
     249
     250}
     251
     252void z3950proto::get_filteroptions (const text_t &/*collection*/,
     253                    const InfoFilterOptionsRequest_t &/*req*/,
     254                    InfoFilterOptionsResponse_t &response,
     255                    comerror_t &err, ostream &/*logout*/) {
     256  // for now, assume all servers have the same characteristics
     257  /*  if (request.filterName=="QueryFilter") { }
     258      else if (request.filterName=="BrowseFilter") { }
     259      else if (request.filterName=="NullFilter") {  } */
     260  response.filterOptions["Index"].type=FilterOption_t::stringt;
     261  response.filterOptions["Index"].repeatable=FilterOption_t::onePerQuery;
     262  response.filterOptions["Index"].defaultValue="any";
     263  response.filterOptions["Index"].validValues.push_back(".any");
     264  response.filterOptions["Index"].validValues.push_back(".title");
     265  response.filterOptions["Index"].validValues.push_back(".author");
     266  // and maybe ["Language"] option as well?
     267  err=noError;
    244268}
    245269
     
    262286
    263287  // cerr now goes to errout.txt in etc directory
     288  err=noError;
    264289
    265290  // get relevant "collection"
     
    267292  z3950_server_array::iterator zend = zservers.end();
    268293  while (zserver != zend) {
    269     if(zserver->getName()==collection) {
     294    if((*zserver)->getName()==collection) {
    270295      break;
    271296    }
     
    276301  //  ColInfoResponse_t *info = new ColInfoResponse_t;
    277302  ColInfoResponse_t info;
    278   ResultDocInfo_t *docInfo=new ResultDocInfo_t;
     303  ResultDocInfo_t *docInfo;
    279304 
    280 
    281305  // leave response.termInfo empty
    282   // leave response.docInfo empty
    283   /* got the following for first query:
    284      request.filterResultOptions=FRmetadata;
    285      request.getParents=getParents
    286      request.fields=metadata
    287      request.docSet (includes OID);
    288   */
    289 
    290306  // response.termInfo.push_back(""); ??????? (should be empty if not req.)
    291307
    292 
    293308  // See if this is for a query action
    294   /*** johnmcp **********
    295        this is not enough, as FROID is set for the about action,
    296        and furthermore, the number of docInfo's (+1?) seems to imply the number
    297        of search methods.
    298        ** ABOUT ACTION
    299        * OIDtools.get_children()
    300        .   FRmetadata, FilterOptions ParentNode=''
    301        * OIDtools.get_info()
    302        .   FRmetadata
    303        ** QUERY ACTION
    304        * OIDtools.get_info() <- receptionist.define_general_macros()
    305        .    FRmetadata, no OptionValues
    306        * queryaction.search_single_collection
    307        .  FRmetadata | FROID | FRtermFreq, fltrOps Term/QueryType/Casefold/..
    308   */
    309   if (request.filterResultOptions & /*FROID*/FRtermFreq) {
    310     // Pretty bad hack: this is assuming
    311     // FRtermFreq is only set for query action, not about action.
    312 
    313     //  what about:
    314     // OptionValue_tarray filterOptions
    315     // docSet
    316     // requestParams
    317     // refParams
    318     // fields -- requested metadata fields.
    319   /*
    320     if (!request.requestParams.empty())
    321     cout << "RequestParams: " << request.requestParams.getcstr() << "\n";
    322     if (!request.refParams.empty())
    323     cout << "RefParams: " << request.refParams.getcstr() << "\n";
    324   */    OptionValue_tarray::iterator ov_here=request.filterOptions.begin();
    325   OptionValue_tarray::iterator ov_end=request.filterOptions.end();
    326   while (ov_here != ov_end) {
    327     cout << "OV pair: `" << ov_here->name.getcstr() << "'=`"
    328      << ov_here->value.getcstr() << "'\n";
    329     ov_here++;
    330   }/*
    331     cout << "end\n\n";
    332   */
    333 
     309  /*** johnmcp **** - could check filterName??????? ********/
     310  /*    if (!request.requestParams.empty())
     311    cout << "RequestParams: " << request.requestParams.getcstr() << "\n";
     312    if (!request.refParams.empty())
     313    cout << "RefParams: " << request.refParams.getcstr() << "\n";
     314  */   
     315  /* cout << "filterOptions:\n";
     316     OptionValue_tarray::iterator ov_here=request.filterOptions.begin();
     317     OptionValue_tarray::iterator ov_end=request.filterOptions.end();
     318     while (ov_here != ov_end) {
     319     cout << "OV pair: `" << ov_here->name.getcstr() << "'=`"
     320     << ov_here->value.getcstr() << "'\n";
     321     ov_here++;
     322     }*/
     323 
     324  // fields is type text_tset;
     325  /* cout << "Fields:\n";
     326     text_tset::iterator fields_h=request.fields.begin();
     327     text_tset::iterator fields_e=request.fields.end();
     328     while (fields_h != fields_e) {
     329     cout << "Field: " << fields_h->getcstr() << "\n";
     330     fields_h++;
     331     }*/
     332 
     333
     334  // if this is true, we assume query action.
     335  //  if (request.filterResultOptions & /*FROID*/FRtermFreq) {
     336  if (request.filterName=="QueryFilter") {
    334337    /* Sample OptionValue pairs
    335338      `StartResults'=`1'
     
    342345      `Maxdocs'=`50'
    343346     */
    344     docInfo->metadata["Title"].values.push_back("dummy title");
    345     docInfo->result_num=1;
     347    // go through options
     348    text_t opt_term;
     349    int opt_start=1, opt_end=20; // default values
     350    int nummatches=0, maxdocs=50; // default values
     351    OptionValue_tarray::iterator ov_here=request.filterOptions.begin();
     352    OptionValue_tarray::iterator ov_end=request.filterOptions.end();
     353    while (ov_here != ov_end) {
     354      //      cout << "OV pair: `" << ov_here->name.getcstr() << "'=`"
     355      //   << ov_here->value.getcstr() << "'\n";
     356      if (ov_here->name=="Term") {
     357    opt_term=ov_here->value;
     358      } else if (ov_here->name=="StartResults") {
     359    opt_start=ov_here->value.getint();
     360      } else if (ov_here->name=="EndResults") {
     361    opt_end=ov_here->value.getint();
     362      } else if (ov_here->name=="Maxdocs") {
     363    maxdocs=ov_here->value.getint();
     364      }
     365      ov_here++;
     366    }
     367    err=noError;
     368    text_tarray *titles=(*zserver)->getbriefrecords(opt_term,
     369                            opt_start,
     370                            opt_end-opt_start, //count
     371                            &nummatches,err);
     372    if (err!=noError) {
     373      // can we return an err msg in a response, or just use
     374      // the more drastic Greenstone error mechanism?
     375      docInfo=new ResultDocInfo_t;
     376      response.docInfo.push_back(*docInfo);
     377      logout << "z3950 filter query: error connecting to server\n";
     378      return;
     379    }
     380    // check if (titles==NULL) - only happens on error?
     381
     382    text_tarray::iterator titles_here=titles->begin();
     383    text_tarray::iterator titles_end=titles->end();
     384    int counter=1;
     385    while (titles_here!=titles_end) {
     386     docInfo=new ResultDocInfo_t;
     387      docInfo->metadata["Title"].values.push_back(*titles_here);
     388      docInfo->result_num=counter;
     389      // we need to give some OID, so we'll just use counter for now...
     390      // make it the number into the whole possible retrieved set.
     391      docInfo->OID=counter+opt_start-1;
     392      response.docInfo.push_back(*docInfo);
     393      counter++;
     394      titles_here++;
     395    }
    346396
    347397    if (request.filterResultOptions & FRtermFreq) {
    348       response.numDocs=2;
    349       response.isApprox=Exact; // Exact | Approximate | MoreThan
    350     }
    351 
    352   response.docInfo.push_back(*docInfo);
    353   // create a 2nd dummy record
    354   docInfo=new ResultDocInfo_t;
    355   docInfo->metadata["Title"].values.push_back("another title");
    356   docInfo->result_num=2;
    357   response.docInfo.push_back(*docInfo);
    358  
     398      if (nummatches>maxdocs) {
     399        response.numDocs=maxdocs; // eg "more than 50" (if Maxdocs==50)
     400    response.isApprox=MoreThan;
     401      } else {
     402    response.numDocs=nummatches; // eg "36 documents"
     403    response.isApprox=Exact; // Exact | Approximate | MoreThan
     404      }
     405    } // end of if (... & FRtermFreq)
     406   
    359407  } // end of if (... & FROID)
    360408  else {
     
    364412    request.filterOptions[0].name=="ParentNode") {
    365413      // don't want to return anything
    366       //delete (docInfo);
     414      return;
     415      /*    } else if (request.docSet.size() &&
     416        request.docSet[0]!="collection") {
     417        // documentaction
     418        // if docSet is not empty, it is either "collection", or an array
     419        // of OIDs
     420        docInfo=new ResultDocInfo_t;
     421        response.docInfo.push_back(*docInfo);
     422      */
    367423    } else {
    368424      // in case we need to return only metadata
     425      docInfo=new ResultDocInfo_t;
    369426      response.docInfo.push_back(*docInfo);
    370427    }
     
    395452      if (it!=info.collectionmeta.end())
    396453        docs_here->metadata[*fields_here].values.push_back((*it).second);
    397       else {
     454      else if (*fields_here=="Title") {
     455        text_t title;
     456        int i;
     457        // check that docSet isn't empty!!!@!!!
     458        i=request.docSet[0].getint();
     459        text_t doctext="unneeded";
     460        (*zserver)->getfullrecord(i, title, doctext,err);
     461        // check err value!
     462        docInfo->metadata["Title"].values.push_back(title);     
     463      } else {
    398464        docs_here->metadata[*fields_here].values.push_back("");
    399465        /////// cerr << " (not found)";
     
    416482    colmeta_here++;
    417483      }
    418       // get data from target.
     484
    419485      // check if "collectionextra" metadata is set. If it isn't, we should
    420486      // create connection to target to get it.
    421487      if (info.collectionmeta.find("collectionextra")==colmeta_end) {
    422     // it doesn't exist.
    423     text_t *abouttext;
    424     // this gets the server's name and id, plus MOTD, etc.
    425     abouttext=zserver->connect_getAbout();
    426     // add in the text we read in from config file.
     488    // it hasn't been set yet...
     489    text_t abouttext="<B>Server Online</B><br>\n";
     490    abouttext+=(*zserver)->getzAbout();
     491    // add in the "About" text we read in from config file.
    427492    // how do we incorporate multi-lingual metadata?
    428     (*abouttext)+="<P>\n";
    429     (*abouttext)+=zserver->getAbout("en");
    430     zserver->setMeta("collectionextra",*abouttext);
    431     response.docInfo[0].metadata["collectionextra"].values.push_back(*abouttext);
    432     delete (abouttext);
     493    abouttext+="<P>\n";
     494    text_t tmpabout;
     495
     496    if ((*zserver)->getcfgAbout("en", tmpabout)==true)
     497      abouttext+=tmpabout;
     498
     499    (*zserver)->setMeta("collectionextra",abouttext);
     500    response.docInfo[0].metadata["collectionextra"].values.push_back(abouttext);
    433501      }
    434502    } // end of else
    435    
     503
     504    // do indices' names, regardless of whether asked for or not...
     505    response.docInfo[0].metadata[".author"].values.push_back("author fields");
     506    response.docInfo[0].metadata[".title"].values.push_back("title fields");
     507    response.docInfo[0].metadata[".any"].values.push_back("any fields");
    436508  } //end of  if (... & FRmetadata) ...
    437 
    438 
     509}
     510
     511
     512
     513void z3950proto::get_document (const text_t &collection,
     514                   const DocumentRequest_t &request,
     515                   DocumentResponse_t &response,
     516                   comerror_t &err, ostream &logout) {
    439517
    440518  err=noError;
    441 }
    442 
    443 void z3950proto::get_document (const text_t &/*collection*/,
    444                    const DocumentRequest_t &/*request*/,
    445                    DocumentResponse_t &/*response*/,
    446                    comerror_t &err, ostream &logout) {
    447 
     519
     520  // get relevant "collection"
     521  z3950_server_array::iterator zserver = zservers.begin();
     522  z3950_server_array::iterator zend = zservers.end();
     523  while (zserver != zend) {
     524    if((*zserver)->getName()==collection) {
     525      break;
     526    }
     527    zserver++;
     528  }
     529  // now have collection in zserver.
     530
     531  /*  cout << "get document:\n\tOID: " << request.OID.getcstr()
     532      << "\n\tdocType: " << request.docType.getcstr()
     533      << "\n\tdocFormat: " << request.docFormat.getcstr() <<"\n";
     534  */
     535
     536  /* docresponse consists of
     537     text_t response.doc */
     538  text_t title="unneeded";
     539  text_t doctext;
     540  (*zserver)->getfullrecord(request.OID.getint(),title,doctext,err);
     541  // check return value of above? (false=>not connected)
     542  if (err==noError)
     543    response.doc=doctext;
     544  else {
     545    // could print out different messages based on error type....
     546    response.doc="<h2>Error</h2>There was an error while connecting to the ";
     547    response.doc+="z39.50 server (ie target). Most likely this was a \n";
     548    response.doc+="\"Connection Refused\" error.\n";
     549
     550  }
    448551  if (0) {
    449552    err=protocolError;
  • branches/z3950-branch/gsdl/src/recpt/z3950proto.h

    r1174 r1191  
    2020  */
    2121 
    22   void add_server(const z3950_server& zserver);
     22  void add_server(z3950_server& zserver);
    2323
    2424  void read_config_file(const text_t &filename);
     
    5050      FilterResponse_t &response, ostream &logout);
    5151  */
     52
     53  void get_filteroptions (const text_t &collection,
     54                          const InfoFilterOptionsRequest_t &request,
     55                          InfoFilterOptionsResponse_t &response,
     56                          comerror_t &err, ostream &logout);
    5257 
    5358  void filter (const text_t &collection,
  • branches/z3950-branch/gsdl/src/recpt/z3950server.cpp

    r1174 r1191  
    1414z3950_server::z3950_server() {
    1515  info=NULL;
     16  connected=false;
     17  titles=NULL;
     18  // for now, assume that all records will have text associated with them.
     19  meta["hastxt"]="1";
    1620}
    1721
     
    2832}
    2933
    30 void z3950_server::addAbout(const text_t &lang, const text_t &abouttext) {
     34void z3950_server::addcfgAbout(const text_t &lang, const text_t &abouttext) {
    3135    about[lang]=abouttext;
    3236}
    3337
    34 const text_t &z3950_server::getAbout(const text_t &lang) {
     38bool z3950_server::getcfgAbout(const text_t &lang, text_t &abouttxt) {
    3539  text_tmap::iterator it;
    3640  it=about.find(lang);
    37   return ((*it).second);
     41  if (it==about.end()) return (false);
     42  abouttxt=((*it).second);
     43  return (true);
    3844}
    3945
    40 text_t *z3950_server::connect_getAbout() {
    41   // Assume we have not yet connected, so that must be done here.
    42   text_t *returned;
    43   returned=new text_t;
     46
     47// now functions that actually talk over the tcp connection.
     48
     49// create a tcp connection to the associated target. Currently, this will
     50// re-initialise if we are already connected.
     51bool z3950_server::connect() {
     52  text_t server_and_port;
     53  char *zserverinfo;
     54
     55  server_and_port=info->host+":"+info->port;
     56  // remember that info.name is the database name
    4457
    4558  z_initialize();
    46   text_t server_and_port;
    47   server_and_port=info->host+":"+info->port;
    48   // remember that info.name is the database name
    49   if (z_cmd_open(server_and_port.getcstr(),info->name.getcstr())==1) {
     59
     60  if (z_cmd_open(server_and_port.getcstr(),info->name.getcstr())==1)
    5061    // we got a connection error
    51     returned->setcstr("<H2>Server offline</H2>Error - could not connect to server <B>");
    52     (*returned) += info->host.getcstr();
    53     (*returned) += "</B> on port ";
    54     (*returned) += info->port;
    55     (*returned) += "\n";
    56     return (returned);
     62    return false;
     63
     64  // get initialisation response.
     65  z_getnextAPDU();
     66  zserverinfo=z_get_initResponse();
     67  if (zserverinfo!=NULL) {
     68    z_initstr.appendcstr(zserverinfo);
     69  }
     70  free(zserverinfo);
     71
     72  connected=true;
     73  return true;
     74}
     75
     76text_tarray *z3950_server::getbriefrecords(const text_t &query,
     77                       int first, int count,
     78                       int *nummatches, comerror_t &err) {
     79  char **c_str_titles;
     80  int i;
     81  int last;
     82  if (titles!=NULL) delete (titles);
     83  titles=new text_tarray;
     84
     85  if (connected==false)
     86    if (connect()==false) {
     87      // we could not connect.
     88      err=protocolError;
     89      return (NULL);
     90    }
     91 
     92
     93  // We need to format the query string into RPN -
     94  // by just passing it like this, it will only work for simple queries.
     95  /* check if connected */
     96  /*  titles->push_back("first dummy title");
     97      titles->push_back("Second dummy title");
     98      return titles;
     99  */
     100  // following functions defined in yaz_zclient.c
     101  *nummatches=z_cmd_dosearch(query.getcstr()); // returns # found, -1 on err.
     102  // could just check if (*nummatches)==0.
     103
     104  // could do a sort eventually, eg on date, title, etc.
     105  // (non-existent function)    z_sort(field, asc|desc);
     106  /* min of (count, first + (*nummatches) ) */
     107  c_str_titles=z_getbriefrecords(first,count);
     108  if (c_str_titles==NULL) {
     109    // an error occurred. we need a logout/err as an arg
     110    return (NULL);
     111  }
     112  if (c_str_titles[0]==0) {
     113    // no matches.
     114    return (NULL);
     115  }
     116  last=(int)c_str_titles[0];
     117  for (i=1;i<=last;i++) {
     118    titles->push_back(c_str_titles[i]);
     119    free(c_str_titles[i]);
     120  }
     121  free(c_str_titles);
     122  return (titles);
     123 
     124}
     125
     126bool z3950_server::getfullrecord(const int ID, text_t &rettitle,
     127                text_t &rettext, comerror_t &err) {
     128  if (connected==false) {
     129    if (connect()==false) {
     130      // error connecting...
     131      err=protocolError;
     132      return (false);
     133    }
     134    // since we have just re-connected, we need to do the
     135    // query again.
    57136  }
    58137
    59   z_getnextAPDU(0);
    60   (*returned)+="Internet server: <b>";
    61   (*returned)+=info->host;
    62   (*returned)+="</b> on port ";
    63   (*returned)+=info->port;
    64   (*returned)+=".<br>\n";
    65   (*returned)+=z_get_initResponse();
    66   if (returned==NULL) {
    67     cerr << "Null was returned\n";
     138  if (rettitle!="unneeded") {
     139    /*char **c_str_titles;
     140      int dummy;
     141      c_str_titles=z_getbriefrecords("the",ID,1,&dummy); // check this return value.
     142      if (c_str_titles!=NULL && (int)c_str_titles[0]==1) {
     143      rettitle.setcstr(c_str_titles[1]); // and check this
     144      free (c_str_titles);
     145    */
     146    //    rettitle=(*titles)[ID]; // this isn't quite right, as ID isn't the offset
     147    rettitle="Dummy Title";
    68148  }
    69   // should close
    70   z_cmd_close(0);
    71   return (returned);
     149 
     150  if (rettext!="unneeded") {
     151    // get the text
     152    rettext="Dummy Text. This is here as a placeholder until I work out";
     153    rettext+=" a way to get the query again when running in simple cgi\n";
     154    rettext+="as after each page is completed, the connection is lost to the";
     155    rettext+=" server, and we forget what the query was\n";
     156  }
     157  return (true);
    72158}
     159
     160text_t &z3950_server::getzAbout() {
     161  text_t zserverresp;
     162
     163  // Assume we have not yet connected, so that must be done here.
     164  if (connected==true)
     165    return (z_initstr);
     166 
     167  // we need to create the tcp connection to the target (server) 
     168  //  z_initstr=new text_t;
     169 
     170  if (connect()==false) {
     171    z_initstr.setcstr("<H2>Server offline</H2>Error - could not connect to server <B>");
     172    z_initstr += info->host.getcstr();
     173    z_initstr += "</B> on port ";
     174    z_initstr += info->port;
     175    z_initstr += "\n";
     176    return (z_initstr);
     177  }
     178 
     179  // z_initstr currently contains the target's response. We want to
     180  // PREPEND the following information.
     181  zserverresp=z_initstr;
     182  z_initstr="Internet server: <b>";
     183  z_initstr+=info->host;
     184  z_initstr+="</b> on port ";
     185  z_initstr+=info->port;
     186  z_initstr+=".<br>\n";
     187  z_initstr+=zserverresp;
     188
     189  // should close /******* WHAT IF DOING A QUERY!??!?!? ********/
     190  // z_cmd_close(0);
     191  // connected=false;
     192  return (z_initstr);
     193}
     194
  • branches/z3950-branch/gsdl/src/recpt/z3950server.h

    r1174 r1191  
    88 protected:
    99  text_t title;    // Descriptive name
     10  text_t z_initstr; // a string returned when the connection is initialised.
    1011  text_tmap meta;  // metadata for this collection (ie server/database pair)
    1112  text_tmap about; // langauge/abouttext pair for collection.
    1213  ShortColInfo_t *info; // has  (database) name, host and port
     14  text_tarray *titles;
     15  bool connect();
     16  bool connected; // tcp connection to the z39.50 server (target)
    1317
    1418 public:
     
    2125  void setInfo(ShortColInfo_t *newinfo) {info=newinfo;}
    2226  const ShortColInfo_t *getInfo() {return info;}
    23   void addAbout(const text_t &lang, const text_t &abouttext);
    24   const text_t &getAbout(const text_t &lang);
    25   // now the functions that actually talk to the target (ie zserver)
    26   // over tcp
    27   text_t *connect_getAbout();
     27  void addcfgAbout(const text_t &lang, const text_t &abouttext);
     28  bool getcfgAbout(const text_t &lang, text_t &abouttext);
     29  // now the functions that actually talk to the target (ie zserver) over tcp
     30  text_t &getzAbout(); // gets any name, id, MOTD, etc from server.
     31  text_tarray *getbriefrecords(const text_t &query,
     32                   const int first, const int count,
     33                   int *nummatches, comerror_t &err);
     34  /* only get one record at a time? (Eventually we could buffer them, but
     35     for now... */
     36  bool getfullrecord(const int ID, text_t &rettitle,
     37             text_t &rettext,comerror_t &err);
    2838};
    2939
    30 typedef  vector<z3950_server>  z3950_server_array;
     40typedef  vector<z3950_server *>  z3950_server_array;
    3141
    3242#endif
  • branches/z3950-branch/gsdl/src/recpt/zparse.y

    r1174 r1191  
    1818/* defined in parse.fl */
    1919extern int lineno;
     20
     21#ifndef YYRECOVERING
     22int YYRECOVERING=0; /* this is supposed to already be defined as a macro */
     23#endif
    2024
    2125/* defined in z3950proto.cpp */
     
    7276%type <cfg>      zserver zserverlist
    7377%type <number>  port
    74 %type <string>   icon smallicon lang
     78%type <string>   icon smallicon lang name
    7579%type <about>    about aboutLang aboutList
    7680%%
     
    8589              | zserver ;
    8690
    87 zserver       : DATA DATA port DATA STRING icon smallicon about {
    88              if(($$=malloc(sizeof(struct z3950cfg)))==NULL)
    89                fprintf(stderr,"malloc failed\n");
    90              $$->shortname=$1;
    91              $$->hostname=$2;
    92              $$->port=$3;
    93              $$->dbname=$4;
    94              $$->longname=$5;
    95              $$->icon=$6;
    96              $$->smallicon=$7;
    97              $$->about=$8;
     91zserver       : DATA DATA port DATA name icon smallicon about
     92                   {
     93             if (YYRECOVERING)
     94               {$$=NULL;YYRECOVERING=0;}
     95             else {
     96               if(($$=malloc(sizeof(struct z3950cfg)))==NULL)
     97             fprintf(stderr,"malloc failed\n");
     98               $$->shortname=$1;
     99               $$->hostname=$2;
     100               $$->port=$3;
     101               $$->dbname=$4;
     102               $$->longname=$5;
     103               $$->icon=$6;
     104               $$->smallicon=$7;
     105               $$->about=$8;
     106             }
    98107           }
    99               | error {$$=NULL;}
     108              | error {$$=NULL;printf("discarding zserver\n");}
    100109              ;
     110
     111name          : STRING {;}
     112              | {errormsg("Database name needs to be followed by a short "
     113              "descriptive name (enclosed in \" marks)");
     114             $$=NULL;
     115             YYRECOVERING=1;} /* we should scrap this server */
    101116
    102117port          : ':' DATA {$$=atoi($2);}
Note: See TracChangeset for help on using the changeset viewer.