/********************************************************************
* wilkinson
* 3.30VMS
* 1995/09/25 14:40
* gopher_root1:[gopher.g2.vms2_13.gopherd]waisgopher.c,v
* Exp
*
* Paul Lindner, University of Minnesota CIS.
*
* Copyright 1991, 1992 by the Regents of the University of Minnesota
* see the file "Copyright" in the distribution for conditions of use.
*********************************************************************
* MODULE: waisgopher.c
* Routines to translate from gopher protocol to wais protocol
*********************************************************************
* Revision History:
* waisgopher.c,v
* Revision 3.30VMS 1995/09/25 14:40 wilkinson
* Consolodate VMS/Unix source code for server as well as client
*
* Revision 3.30 1995/02/16 22:32:41 lindner
* HTML icon support
*
* Revision 3.29 1995/02/01 21:41:48 lindner
* Fix for FreeWAIS 0.4
*
* Revision 3.28 1995/01/04 17:36:31 lindner
* Fix for freewais-sf on linux
*
* Revision 3.27 1994/11/05 03:20:02 lindner
* Add logging, add period output to wais-gopher gateway
*
* Revision 3.26 1994/10/13 05:17:50 lindner
* Compiler complaint fixes
*
* Revision 3.25 1994/07/19 20:23:44 lindner
* Use local Locale.h
*
* Revision 3.24 1994/06/29 05:22:14 lindner
* Add Gticket
*
* Revision 3.23 1994/05/02 07:41:17 lindner
* Mods to use setlocale()
*
* Revision 3.22 1994/04/25 20:49:12 lindner
* Fix for debug code
*
* Revision 3.21 1994/03/17 21:14:19 lindner
* Fix for pid load limiting
*
* Revision 3.20 1994/03/17 04:11:56 lindner
* Add Sockets.h
*
* Revision 3.19 1994/03/08 15:56:11 lindner
* gcc -Wall fixes
*
* Revision 3.18 1994/01/21 03:38:35 lindner
* Update function definitions (alanc)
*
* Revision 3.17 1994/01/03 18:04:47 lindner
* bug fix..
*
* Revision 3.16 1993/12/30 04:12:04 lindner
* Fix for number of arguments bug
*
* Revision 3.15 1993/11/02 06:02:41 lindner
* HTML Mods
*
* Revision 3.14 1993/10/04 06:40:19 lindner
* casting error
*
* Revision 3.13 1993/09/22 04:47:58 lindner
* bug fix for waishits patch
*
* Revision 3.12 1993/09/22 04:30:27 lindner
* Add option to conf.h for Max WAIS documents
*
* Revision 3.11 1993/09/20 23:15:09 lindner
* Updates for multibyte wais docids
*
* Revision 3.10 1993/09/01 21:46:59 lindner
* Fix problem with g0 client for wais gateway searches
*
* Revision 3.9 1993/08/11 02:27:43 lindner
* Fix for wais gateway and Unix client
*
* Revision 3.8 1993/07/29 21:21:53 lindner
* Fix for excess dots in text files
*
* Revision 3.7 1993/07/27 05:28:03 lindner
* Mondo Debug overhaul from Mitra
*
* Revision 3.6 1993/07/26 15:31:12 lindner
* mods for application/gopher-menu
*
* Revision 3.5 1993/07/23 03:16:34 lindner
* Yet another fix for gplus
*
* Revision 3.4 1993/07/20 23:55:04 lindner
* Fix gopher+ bug in gateway
*
* Revision 3.3 1993/07/07 19:37:18 lindner
* *** empty log message ***
*
* Revision 3.2 1993/03/26 19:46:55 lindner
* First crack at gopherplussing Indexing
*
* Revision 3.1.1.1 1993/02/11 18:02:53 lindner
* Gopher+1.2beta release
*
* Revision 1.2 1993/01/30 23:57:44 lindner
* Moved inputline parsing to gopherd.c
*
* Revision 1.1 1992/12/10 23:13:27 lindner
* gopher 1.1 release
*
*
*********************************************************************/
/* Wais to gopher gateway code.
Paul Lindner, March 1992
<
[email protected]>
*/
/* WIDE AREA INFORMATION SERVER SOFTWARE:
No guarantees or restrictions. See the readme file for the full standard
disclaimer.
[email protected]
*/
#if defined(WAISSEARCH) /*** Only compile this if we have WAIS ***/
#include "gopherd.h"
#include "command.h"
#include "Debug.h"
#if defined(_AIX)
#define ANSI_LIKE
#endif
#include "Locale.h"
#include <ctype.h>
#include <ui.h>
#include <docid.h>
#define MAIN
#define sockets_h
#include "wais.h"
#include "Sockets.h"
#define WAISSEARCH_DATE "Fri Sep 13 1991"
#define DOCIDSIZE 5120
/*** Need for freewais-sf on some platforms ***/
#ifndef MIN
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
#endif
/**** Needed by wais-8-b5... Ick... ***/
char *sdir=NULL;
char *cdir=NULL;
/**** For FreeWAIS 0.4 ****/
#ifdef FREEWAIS_0_4
# define init_connection FW_init_connection
# define close_connection FW_close_connection
#endif
/* encode a variable length integer - used by gopher_to_docid */
static unsigned char*
integer_encode(cp,value)
register unsigned char* cp;
register unsigned int value;
{
char buf[100];
char* bp = buf-1;
if(value < 128) {
*cp++=(unsigned char)value;
return cp;
}
while(value >127) {
*++bp = (unsigned char)(value&0x7f);
value >>=7;
}
*cp++=(unsigned char)(value | 0x80);
while(bp > (buf)) {
*cp++=(*bp--) | 0x80;
}
*cp++=*bp;
return cp;
}
/**** Used by something in the source reading routines. ***/
void
PrintStatus(str)
char * str;
{
return;
}
void find_value(source, key, value, value_size)
char *source, *key, *value;
int value_size;
{
char ch;
long position = 0; /* position in value */
char *pos =strstr(source, key); /* address into source */
value[0] = '\0'; /* initialize to nothing */
if(NULL == pos)
return;
pos = pos + strlen(key);
ch = *pos;
/* skip leading quotes and spaces */
while((ch == '\"') || (ch == ' ')) {
pos++; ch = *pos;
}
for(position = 0; pos < source + strlen(source); pos++){
if((ch = *pos) == ' ') {
value[position] = '\0';
return;
}
value[position] = ch;
position++;
if(position >= value_size){
value[value_size - 1] = '\0';
return;
}
}
value[position] = '\0';
}
/****/
void ZapTabs(in)
char *in;
{
/** replace tabs with a space... **/
while (*in != '\0') {
if (*in == '\t')
*in = ' ';
in ++;
}
}
void
Send_binary_record(record, sockfd)
WAISDocumentText *record;
int sockfd;
{
writen(sockfd, record->DocumentText->bytes, record->DocumentText->size);
}
/*** Modified from ../ir/ui.c to add \r\n at the ends of the line... ***/
void
Mydisplay_text_record_completely(record,quote_string_quotes, sockfd)
WAISDocumentText *record;
boolean quote_string_quotes;
int sockfd;
{
long count;
unsigned char ch;
unsigned char output[512];
int outputptr = 0;
for(count = 0; count < record->DocumentText->size; count++){
ch = (unsigned char)record->DocumentText->bytes[count];
switch (ch) {
case 27:
/* then we have an escape code */
/* if the next letter is '(' or ')', then ignore two letters */
if('(' == record->DocumentText->bytes[count + 1] ||
')' == record->DocumentText->bytes[count + 1])
count += 1; /* it is a term marker */
else count += 4; /* it is a paragraph marker */
break;
case '\t':
output[outputptr++] = ch;
break;
case '\r':
if ('\n' == record->DocumentText->bytes[count + 1])
break;
case '\n':
Debugmsg("Got a return\n");
output[outputptr++] = '\r';
output[outputptr++] = '\n';
break;
default:
if (isprint(ch)){
if(quote_string_quotes && ch == '"') {
output[outputptr++] = '/';
output[outputptr++] = '/';
}
output[outputptr++] = ch;
}
}
if (outputptr >500) {
output[outputptr++] = '\0';
writestring(sockfd, output);
outputptr = 0;
}
}
/*** Write out the rest of the buffer... ***/
output[outputptr++] = '\0';
writestring(sockfd, output);
}
/* modified from Jonny G's version in ui/question.c */
void showDiags(d)
diagnosticRecord **d;
{
long i;
for (i = 0; d[i] != NULL; i++) {
if (d[i]->ADDINFO != NULL) {
printf("Code: %s, %s\n", d[i]->DIAG, d[i] ->ADDINFO);
}
}
}
int
acceptable(foo)
char foo;
{
if (foo == '\t' || foo == '\r' || foo == '\n' || foo == '\0')
return(0);
else if (!isprint(foo))
return(0);
else
return(1);
}
static char * hex = "0123456789ABCDEF";
/*
* DocId_to_Gopher transforms a docid into a character string suitable for
* transmission
*/
char *DocId_to_Gopher(docid, docsize)
any *docid;
int docsize;
{
static char GopherString[DOCIDSIZE];
char *q = GopherString;
char *p;
int l, i;
/** First lets stick on the size of the document first **/
sprintf(GopherString, "%d", docsize);
q += strlen(GopherString);
*q++ = ':';
for (p=docid->bytes; (p < docid->bytes + docid->size) && q<&GopherString[DOCIDSIZE];) {
if (*p >= 10) {
; /* Bad thing happened, can't understand docid, punt */
return(NULL);
}
*q++ = (*p++) + '0'; /* Record Type */
*q++ = '='; /* Seperate */
/* patch by ses: l might be a multibyte integer, so deal with it*/
l = 0;
while(1) {
int c;
c = *p++;
if(c &~0x7f) {
l |= (c&0x7f);
l <<= 7;
} else {
l |= c;
break;
}
}
for (i=0; i<l; i++, p++) {
if (acceptable(*p)==0) {
*q++ = '%';
*q++ = hex[(*p) >> 4];
*q++ = hex[(*p) & 15];
}
else *q++ = *p;
}
*q++ = ';';
}
*q++ = 0;
return(GopherString);
}
int
hex_to_int( c)
char c;
{
if(isdigit(c)) {
return c - '0';
} else {
return (tolower(c) - 'a')+10;
}
}
/*
* Gstring is a name produced by DocID_to_Gopher
*/
any *Gopher_to_DocId(Gstring, DocSize)
char *Gstring;
int *DocSize;
{
static any docid;
char *outptr;
char *inptr;
char *sor;
char *eqptr;
int size;
int type;
char tmp[DOCIDSIZE];
/* Strip off the Document size first.... */
inptr = strchr(Gstring, ':');
if (inptr == NULL)
return(NULL);
*DocSize = atoi(Gstring);
Gstring = inptr +1;
if(docid.bytes) {
free(docid.bytes);
}
docid.bytes = s_malloc(DOCIDSIZE);
docid.size=DOCIDSIZE;
sor = docid.bytes;
while(1) {
if(*Gstring == 0) {
break; /* we've finished */
}
outptr = tmp;
type = (*Gstring++)-'0'; /* get the field id*/
Gstring++; /* skip over the '=' sign*/
eqptr = Gstring;
size = 0; /* set the size to 0 */
while(1) {
if(*Gstring == ';') {
Gstring++;
break;
}
if(*Gstring == '%') {
Gstring++;
*outptr = hex_to_int(*Gstring++);
*outptr <<= 4;
*outptr += hex_to_int(*Gstring++);
} else {
*outptr = *Gstring++;
}
size++;
outptr++;
}
if(DEBUG) {
printf("type = %d, size = %d\n",type,size);
}
*sor++ = type; /* set the type identifer*/
sor = (char*)integer_encode(sor,size);
bcopy(tmp,sor,size);
sor += size;
}
docid.size = sor - docid.bytes;
return(&docid);
}
/*-----------------------------------------------------------------*/
/* modified from tracy shen's version in wutil.c
* displays either a text record of a set of headlines.
*/
void
display_search_response(response, hostname, port, dbname, SourceName,
sockfd, view, isgplus)
SearchResponseAPDU *response;
char *hostname, *port, *dbname, *SourceName;
int sockfd;
char *view;
boolean isgplus;
{
WAISSearchResponse *info;
long i, k;
GopherObj *gs = NULL;
GopherDirObj *gd = NULL;
char gopherpath[1024];
gs = GSnew();
gd = GDnew(64);
if ( response->DatabaseDiagnosticRecords != 0 ) {
info = (WAISSearchResponse *)response->DatabaseDiagnosticRecords;
i =0;
if (info->Diagnostics != NULL)
showDiags(info->Diagnostics);
if ( info->DocHeaders != 0 ) {
k =0;
while (info->DocHeaders[k] != 0 ) {
i++;
ZapCRLF(info->DocHeaders[k]->Headline);
ZapTabs(info->DocHeaders[k]->Headline);
GSinit(gs);
GSsetTitle(gs, info->DocHeaders[k]->Headline);
sprintf(gopherpath, "waisdocid:%s:%s:%s",
SourceName,
info->DocHeaders[k]->Types[0],
DocId_to_Gopher(info->DocHeaders[k]->DocumentID,
info->DocHeaders[k]->DocumentLength));
GSsetPath(gs, gopherpath);
GSsetHost(gs, Zehostname);
GSsetPort(gs, GopherPort);
if (strcmp(info->DocHeaders[k]->Types[0], "TEXT") == 0) {
GSsetType(gs, A_FILE);
}
else if (strcmp(info->DocHeaders[k]->Types[0],"GIF")==0) {
GSsetType(gs, A_GIF);
}
else if (strcmp(info->DocHeaders[k]->Types[0],"PICT")==0) {
GSsetType(gs, A_IMAGE);
}
else if (strcmp(info->DocHeaders[k]->Types[0],"WSRC")==0) {
GSsetType(gs, A_INDEX);
}
else
GSsetType(gs, A_UNIXBIN);
GDaddGS(gd, gs);
k++;
}
if (view == NULL)
GDtoNet(gd, sockfd, GSFORM_G0, Gticket, NULL);
else {
if (isgplus)
GSsendHeader(sockfd, -1);
if (strcasecmp(view, "application/gopher+-menu")==0)
GDplustoNet(gd, sockfd, NULL, Gticket);
else
GDtoNet(gd, sockfd, GSFORM_G0, Gticket, NULL);
}
}
if ( info->Text != 0 ) {
k =0;
while ((info->Text[k] != 0) ) {
i++;
printf("\n Text record %2d, ", i);
Mydisplay_text_record_completely( info->Text[k++], false, sockfd);
}
}
}
writestring(sockfd, ".\r\n");
}
/*** Find server, database, and service
*** This routine recognizes the hack where the filename is
*** (server database service)
***/
void
MyReadSource(Moo, filename, sockfd)
Source Moo;
char *filename;
int sockfd;
{
FILE *dotsrc;
char *cp;
if (filename == NULL)
Abortoutput(sockfd, "No Filename!");
if (*filename == '(' && filename[strlen(filename)-1] == ')') {
cp = strchr(filename, ' ');
if (cp==NULL)
Abortoutput(sockfd, "malformed filename");
*cp = '\0';
strcpy(Moo->server, filename+1);
*cp = ' ';
filename = cp+1;
cp = strchr(filename, ' ');
if (cp==NULL)
Abortoutput(sockfd, "malformed filename");
*cp = '\0';
strcpy(Moo->database, filename);
*cp = ' ';
filename = cp +1;
filename[strlen(filename)] = '\0';
strcpy(Moo->service, filename);
}
else {
dotsrc = rfopen(filename, "r");
if (dotsrc == NULL) {
char tmpstr[256];
sprintf(tmpstr, "File '%s' does not exist", filename);
Abortoutput(sockfd, tmpstr), gopherd_exit(-1);
}
ReadSource(Moo, dotsrc);
fclose(dotsrc);
}
}
#define MAX_KEYWORDS_LENGTH 1000
#define MAX_SERVER_LENGTH 1000
#define MAX_DATABASE_LENGTH 1000
#define MAX_SERVICE_LENGTH 1000
#ifndef WAISMAXHITS
#define WAISMAXHITS 40
#endif
/******************************************************************/
void SearchRemoteWAIS(sockfd, SourceName, cmd, view)
int sockfd;
char *SourceName;
CMDobj *cmd;
char *view;
{
char *keywords = CMDgetSearch(cmd);
char* request_message = NULL; /* arbitrary message limit */
char* response_message = NULL; /* arbitrary message limit */
long request_buffer_length; /* how of the request is left */
SearchResponseAPDU *query_response;
SearchResponseAPDU *retrieval_response;
char server_name[MAX_SERVER_LENGTH + 1];
char service[MAX_SERVICE_LENGTH + 1];
char database[MAX_DATABASE_LENGTH + 1];
FILE *connection;
Source Moo;
boolean isgplus = CMDisGplus(cmd);
server_name[0] = '\0'; /* null it out */
database[0] = '\0'; /* null it out */
service[0] = '\0'; /* null it out */
/**
** Next load up the name of the source...
*/
if (keywords == NULL) {
/** An error occured, probably old client software... **/
writestring(sockfd, ".\r\n");
}
Moo = (Source)malloc(sizeof(_Source));
bzero(Moo, sizeof(_Source));
MyReadSource(Moo, SourceName, sockfd);
strcpy(server_name, Moo->server);
strcpy(database, Moo->database);
strcpy(service, Moo->service);
if (server_name[0] == 0)
connection = NULL;
else if ((connection=connect_to_server(server_name,atoi(service))) == NULL)
{
char Errorstr[256];
sprintf(Errorstr,"Error openning connection to %s via service %s.",
server_name, service);
Abortoutput(sockfd, Errorstr);
gopherd_exit(-1);
}
request_message = (char*)s_malloc((size_t)MAX_MESSAGE_LEN * sizeof(char));
response_message = (char*)s_malloc((size_t)MAX_MESSAGE_LEN * sizeof(char));
{
char userInfo[256];
sprintf(userInfo, "waisgopher %s, from host: %s", VERSION, Zehostname);
init_connection(request_message, response_message,
MAX_MESSAGE_LEN,
connection,
userInfo);
}
request_buffer_length = MAX_MESSAGE_LEN; /* how of the request is left */
if(NULL ==
generate_search_apdu(request_message + HEADER_LENGTH,
&request_buffer_length,
keywords, database, NULL, WAISMAXHITS))
Abortoutput(sockfd, "request too large");
if(0 ==
interpret_message(request_message,
MAX_MESSAGE_LEN - request_buffer_length,
response_message,
MAX_MESSAGE_LEN,
connection,
false /* true verbose */
)) { /* perhaps the server shut down on us, let's see: */
if ( connection != NULL) {
fclose(connection);
if ((connection=connect_to_server(server_name,atoi(service))) == NULL)
{
char Errorstr[256];
sprintf(Errorstr, "Error openning connection to %s via service %s.\n",
server_name, service);
Abortoutput(sockfd, Errorstr);
}
if(0 ==
interpret_message(request_message,
MAX_MESSAGE_LEN - request_buffer_length,
response_message,
MAX_MESSAGE_LEN,
connection,
false /* true verbose */
))
Abortoutput(sockfd, "really couldn't deliver message");
}
else
Abortoutput(sockfd, "returned message too large");
}
readSearchResponseAPDU(&query_response, response_message + HEADER_LENGTH);
LOGGopher(sockfd, "search %s for %s", database, keywords);
display_search_response(query_response, server_name, service, database, SourceName, sockfd, view, isgplus);
if (retrieval_response) {
freeWAISSearchResponse(query_response->DatabaseDiagnosticRecords);
freeSearchResponseAPDU( query_response);
} else {
/** retrieval response was null **/;
}
/*** close it down ***/
close_connection(connection);
s_free(request_message);
s_free(response_message);
}
/*******************************************************/
void
Fetchdocid(sockfd, cmd)
int sockfd;
CMDobj *cmd;
{
char *inputline = CMDgetSelstr(cmd) + 10;
any *docid;
int DocLen;
int count;
char* request_message = NULL; /* arbitrary message limit */
char* response_message = NULL; /* arbitrary message limit */
long request_buffer_length; /* how of the request is left */
char server_name[MAX_SERVER_LENGTH + 1];
char service[MAX_SERVICE_LENGTH + 1];
char database[MAX_DATABASE_LENGTH + 1];
SearchResponseAPDU *retrieval_response;
FILE *connection;
char *SourceName;
Source Moo;
char *DocIdString;
char *type;
char *searchwords;
boolean senddotcrlf = false;
server_name[0] = '\0'; /* null it out */
database[0] = '\0'; /* null it out */
service[0] = '\0'; /* null it out */
DocIdString = strchr(inputline, ':');
if (DocIdString == NULL) {
Abortoutput(sockfd, "Malformed docid");
return;
}
else {
*DocIdString = '\0';
DocIdString++;
type = DocIdString;
DocIdString = strchr(type, ':') + 1;
*(DocIdString-1) = '\0';
searchwords = strrchr(DocIdString, '\t');
if (searchwords != NULL) {
*(searchwords) = '\0';
searchwords++;
}
}
SourceName = inputline;
Moo = (Source)malloc(sizeof(_Source));
bzero(Moo, sizeof(_Source));
MyReadSource(Moo, SourceName);
strcpy(server_name, Moo->server);
strcpy(database, Moo->database);
strcpy(service, Moo->service);
if (server_name[0] == 0)
connection = NULL;
else if ((connection=connect_to_server(server_name,atoi(service))) == NULL)
{
char Errorstr[256];
sprintf(Errorstr,"Error openning connection to %s via service %s.",
server_name, service);
Abortoutput(sockfd, Errorstr);
return;
}
request_message = (char*)s_malloc((size_t)MAX_MESSAGE_LEN * sizeof(char));
response_message = (char*)s_malloc((size_t)MAX_MESSAGE_LEN * sizeof(char));
docid = Gopher_to_DocId(DocIdString, &DocLen);
/*** First let's transform the first word into a docid ***/
/*** What we need from net: DocumentLength, Types: (TEXT!), docid, **/
for(count = 0;
count * CHARS_PER_PAGE <
DocLen;
count++){
request_buffer_length = MAX_MESSAGE_LEN; /* how of the request is left */
if(0 ==
generate_retrieval_apdu(request_message + HEADER_LENGTH,
&request_buffer_length,
docid,
CT_byte,
count * CHARS_PER_PAGE,
MIN((count + 1) * CHARS_PER_PAGE,
DocLen),
type,
database
))
panic("request too long");
if(0 ==
interpret_message(request_message,
MAX_MESSAGE_LEN - request_buffer_length,
response_message,
MAX_MESSAGE_LEN,
connection,
false /* true verbose */
)) { /* perhaps the server shut down on us, let's see: */
if ( connection != NULL) {
fclose(connection);
if ((connection=connect_to_server(server_name,atoi(service))) == NULL)
{
fprintf (stderr, "Error openning connection to %s via service %s.\n",
server_name, service);
gopherd_exit(-1);
}
if(0 ==
interpret_message(request_message,
MAX_MESSAGE_LEN - request_buffer_length,
response_message,
MAX_MESSAGE_LEN,
connection,
false /* true verbose */
))
panic("really couldn't deliver message");
}
else
panic("returned message too large");
}
readSearchResponseAPDU(&retrieval_response,
response_message + HEADER_LENGTH);
/* display_search_response(retrieval_response); the general thing */
if(NULL == ((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Text){
display_search_response(retrieval_response);
panic("No text was returned");
}
if (strncmp(type, "TEXT", 4) == 0) {
int k;
k = 0;
Debugmsg("Displaying text\n");
while (((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Text[k] != 0) {
Mydisplay_text_record_completely
(((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Text[k++], false, sockfd);
}
senddotcrlf = true;
}
else if (strncmp(type, "WSRC", 4) == 0) {
char searchline[512];
char tempfile[64];
int tempdotsrc;
Source Moo;
/*** It's a search! **/
Debugmsg("Searching!\n");
/*** Dump out the contents of the text record on the server ***/
/*** then call SearchRemoteWAIS(), then delete file ***/
rchdir("/");
mkdir("tmp",0755);
sprintf(tempfile, "/tmp/waissearch.%d", getpid());
tempdotsrc = ropen(tempfile, O_RDWR|O_CREAT,0755);
if (tempdotsrc < 0) {
writestring(sockfd, "3couldn't make temp file\r\n.\r\n");
return;
}
Mydisplay_text_record_completely
(((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Text[0], false, tempdotsrc);
close(tempdotsrc);
Moo = (Source) malloc(sizeof(_Source));
bzero(Moo, sizeof(_Source));
MyReadSource(Moo, tempfile);
sprintf(searchline, "(%s %s %s)\t%s", Moo->server, Moo->database, Moo->service, searchwords);
Debug("waisgopher %s\n", searchline);
rchdir("/");
SearchRemoteWAIS(sockfd, searchline, cmd, "");
unlink(tempfile);
}
else {
int recs =0;
Debugmsg("Displaying Binary\n");
while (1) {
if (((WAISSearchResponse*)retrieval_response->DatabaseDiagnosticRecords)->Text[recs] == NULL)
break;
Send_binary_record(((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Text[recs++], sockfd);
}
}
}
if (senddotcrlf)
writestring(sockfd, ".\r\n");
freeWAISSearchResponse( retrieval_response->DatabaseDiagnosticRecords);
freeSearchResponseAPDU( retrieval_response);
/*** close it down ***/
close_connection(connection);
s_free(request_message);
s_free(response_message);
}
#else /* defined(WAISSEARCH) */
#include "command.h"
#ifdef VMS_SERVER
#include "gopherd.h"
#endif
void
SearchRemoteWAIS(sockfd, SourceName, cmd, view)
int sockfd;
char *SourceName;
CMDobj *cmd;
char *view;
{
#ifndef VMS_SERVER
Abortoutput(sockfd, "No wais stuff in the server!!");
#else
char *selstr = CMDgetSelstr(cmd);
LOGGopher(sockfd, "WAIS request %s", selstr-strlen("waissrc:"));
SetAbrtFile(RangeErr, NULL, KeepAbrtGS, NULL);
Abortoutput(sockfd, "Sorry, no WAIS documents supported by this server");
#endif
}
void
Fetchdocid(sockfd, cmd)
int sockfd;
CMDobj *cmd;
{
#ifndef VMS_SERVER
Abortoutput(sockfd, "No wais stuff in the server!!");
#else
char *selstr = CMDgetSelstr(cmd);
LOGGopher(sockfd, "WAIS request %s", selstr-strlen("waisdocid:"));
SetAbrtFile(RangeErr, NULL, KeepAbrtGS, NULL);
Abortoutput(sockfd, "Sorry, no WAIS documents supported by this server");
#endif
}
#endif