home *** CD-ROM | disk | FTP | other *** search
- /* Wais to gopher gateway code.
-
- Paul Lindner, March 1992
- <lindner@boombox.micro.umn.edu>
- */
-
- /* WIDE AREA INFORMATION SERVER SOFTWARE:
- No guarantees or restrictions. See the readme file for the full standard
- disclaimer.
-
- Brewster@think.com
- */
-
- #if defined(WAISSEARCH) /*** Only compile this if we have WAIS ***/
-
- #include <ctype.h>
- #include <string.h>
- #include <ui.h>
- #include <docid.h>
-
- #define MAIN
- #include "wais.h"
-
- #define WAISSEARCH_DATE "Fri Sep 13 1991"
-
- #include "gopherd.h"
-
- /**** Needed by wais-8-b5... Ick... ***/
-
- char *sdir=NULL;
- char *cdir=NULL;
-
- /**** 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 ++;
- }
- }
-
- /*** 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;
- {
- long count;
- long ch;
- char output[512];
- int outputptr = 0;
-
- for(count = 0; count < record->DocumentText->size; count++){
-
- ch = (unsigned char)record->DocumentText->bytes[count];
-
- if(27 == ch){
- /* 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 */
- }
- else if (ch == '\t') /* a TAB! */
- output[outputptr++] = ch;
- else if (isprint(ch)){
- if(quote_string_quotes && ch == '"') {
- output[outputptr++] = '/';
- output[outputptr++] = '/';
- }
- output[outputptr++] = ch;
- }
- else if (ch == '\n' || ch == '\r') {
- output[outputptr++] = '\r';
- output[outputptr++] = '\n';
- }
-
- 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[512];
- 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[512];) {
- if (*p >= 10) {
- ; /* Bad thing happened, can't understand docid, punt */
- return(NULL);
- }
-
- *q++ = (*p++) + '0'; /* Record Type */
- *q++ = '='; /* Seperate */
- l = *p++; /* Length */
- 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);
- }
-
- /*
- * 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;
- char *semiptr;
- int size;
-
- /* Strip off the Document size first.... */
-
- inptr = strchr(Gstring, ':');
- if (inptr == NULL)
- return;
-
- *DocSize = atoi(Gstring);
-
- Gstring = inptr +1;
-
- for (size=0, inptr=Gstring; *inptr; inptr++) {
- size ++;
- if (*inptr == ';')
- size--;
- else if (*inptr == '%')
- size -=2;
-
- }
-
- docid.size = size;
-
- docid.bytes = (char *) malloc(docid.size);
- outptr = docid.bytes;
-
- for (inptr = Gstring; *inptr;) {
- *outptr++ = *inptr++ - '0'; /* Record Type */
- eqptr = strchr(inptr, '=');
- if (!eqptr)
- return(0);
- semiptr = strchr(inptr, ';');
- if (!semiptr)
- return(0);
- sor = outptr;
- outptr++;
-
- for (inptr = eqptr+1; *inptr!=';' ; ) {
- if (*inptr == '%') {
- char c;
- unsigned int b;
-
- inptr++;
- c = *inptr++;
- b = from_hex(c);
- c = *inptr++;
- if (!c) break;
- *outptr++ = (b<<4) + from_hex(c);
- } else {
- *outptr++ = *inptr++;
- }
- }
-
- *sor = (outptr-sor-1);
- inptr++;
- }
-
- 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)
- SearchResponseAPDU *response;
- char *hostname, *port, *dbname, *SourceName;
- int sockfd;
- {
- WAISSearchResponse *info;
- long i, k;
- struct sockaddr_in serv_addr;
- int length = sizeof(serv_addr);
- 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);
- GSsetType(gs, '0');
- GSsetTitle(gs, info->DocHeaders[k]->Headline);
-
- sprintf(gopherpath, "waisdocid:%s:%s",
- SourceName,
- DocId_to_Gopher(info->DocHeaders[k]->DocumentID,
- info->DocHeaders[k]->DocumentLength));
- GSsetPath(gs, gopherpath);
- GSsetHost(gs, Zehostname);
- GSsetPort(gs, GopherPort);
-
- GDaddGS(gd, gs);
- k++;
- }
-
- GDtoNet(gd, sockfd);
- writestring(sockfd, ".\r\n");
- }
-
- 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);
- }
- }
- }
- }
-
-
-
- #define MAX_KEYWORDS_LENGTH 1000
- #define MAX_SERVER_LENGTH 1000
- #define MAX_DATABASE_LENGTH 1000
- #define MAX_SERVICE_LENGTH 1000
- #define MAXDOCS 40
-
- /******************************************************************/
-
- void SearchRemoteWAIS(sockfd, inputline)
- int sockfd;
- char *inputline;
- {
- 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;
- WAISSearchResponse *query_info, *retrieval_info;
- char server_name[MAX_SERVER_LENGTH + 1];
- char service[MAX_SERVICE_LENGTH + 1];
- char database[MAX_DATABASE_LENGTH + 1];
- long count;
- FILE *connection;
- char *keywords;
- FILE *Dotsrcfile;
- char *SourceName;
- char *WaisGatePort=NULL;
- Source Moo;
- char *cp;
-
-
- 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...
- */
-
- cp = strchr(inputline, '\t');
- keywords = cp + 1;
-
- if (cp == NULL) {
- /** An error occured, probably old client software... **/
- writestring(sockfd, ".\r\n");
- } else
- *cp = '\0';
-
- SourceName= inputline;
-
- Moo = (Source)malloc(sizeof(_Source));
-
- Dotsrcfile = rfopen(SourceName, "r");
- if (Dotsrcfile == NULL) {
- char tmpstr[256];
- sprintf(tmpstr, "File '%s' does not exist", SourceName);
- Abortoutput(sockfd, tmpstr), exit(-1);
- }
-
- ReadSource(Moo, Dotsrcfile);
- 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);
- 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, MAXDOCS))
- 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("returned message too large");
- }
-
- readSearchResponseAPDU(&query_response, response_message + HEADER_LENGTH);
-
- display_search_response(query_response, server_name, service, database, SourceName, sockfd);
-
- freeWAISSearchResponse(query_response->DatabaseDiagnosticRecords);
- freeSearchResponseAPDU( query_response);
-
- /*** close it down ***/
-
- close_connection(connection);
-
- s_free(request_message);
- s_free(response_message);
-
- }
-
-
-
-
- /*******************************************************/
-
- void
- Fetchdocid(sockfd, inputline)
- int sockfd;
- char *inputline;
- {
- 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;
- char *WaisGatePort=NULL;
- Source Moo;
- char *DocIdString;
- FILE *Dotsrcfile;
-
-
- 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++;
- }
-
- SourceName = inputline;
-
- Moo = (Source)malloc(sizeof(_Source));
-
- Dotsrcfile = rfopen(SourceName, "r");
- if (Dotsrcfile == NULL) {
- char tempstr[256];
-
- sprintf(tempstr, "File '%s' does not exist", SourceName);
- Abortoutput(sockfd, tempstr);
- exit(-1);
- }
-
- ReadSource(Moo, Dotsrcfile);
- 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++){
-
- char *type;
- /* if(query_info->DocHeaders[1]->Types == NULL)*/
- type = s_strdup("TEXT");
- /* else
- type = s_strdup(query_info->DocHeaders[1]->Types[0]);*/
- 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);
- 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");
- }
- Mydisplay_text_record_completely
- (((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Text[0], false, sockfd);
- }
-
- freeWAISSearchResponse( retrieval_response->DatabaseDiagnosticRecords);
- freeSearchResponseAPDU( retrieval_response);
-
- /*** close it down ***/
-
- close_connection(connection);
-
- s_free(request_message);
- s_free(response_message);
-
- writestring(sockfd, ".\r\n");
- }
-
- #else /* defined(WAISSEARCH) */
-
- void
- SearchRemoteWAIS(sockfd, selstr)
- int sockfd;
- char *selstr;
- {
- Abortoutput(sockfd, "No wais stuff in the server!!");
- }
-
-
- void
- Fetchdocid(sockfd, selstr)
- int sockfd;
- char *selstr;
- {
- Abortoutput(sockfd, "No wais stuff in the server!!");
- }
-
- #endif
-