home *** CD-ROM | disk | FTP | other *** search
- /* WIDE AREA INFORMATION SERVER SOFTWARE:
- No guarantees or restrictions. See the readme file for the full standard
- disclaimer.
-
- Brewster@think.com
- */
-
- #include <ctype.h>
- #include <errno.h>
- #include <string.h>
- #include <dos.h>
-
- #include "ui.h"
- #include "sockets.h"
-
- #define MAX_TEXT_LENGTH 120
-
- extern char db_path[255];
- extern int recv_bufsize;
- extern int send_bufsize;
-
- /* returns a pointer in the buffer of the first free byte.
- if it overflows, then NULL is returned
- */
-
- char * generate_search_apdu(buff, buff_len, seed_words, database_name,
- docobjs, maxDocsRetrieved)
- char* buff; /* buffer to hold the apdu */
- long *buff_len; /* length of the buffer changed to reflect new data written */
- char *seed_words; /* string of the seed words */
- char *database_name;
- DocObj** docobjs;
- long maxDocsRetrieved;
- {
- /* local variables */
-
- SearchAPDU *search3;
- char *end_ptr;
- static char *database_names[2] = {
- "", 0 };
- any refID;
- WAISSearch *query;
- refID.size = 1L;
- refID.bytes = "3";
-
- database_names[0] = database_name;
-
- query = makeWAISSearch(seed_words,
- docobjs, /* DocObjsPtr */
- 0L,
- 1L, /* DateFactor */
- 0L, /* BeginDateRange */
- 0L, /* EndDateRange */
- maxDocsRetrieved);
-
- search3 = makeSearchAPDU(30L,
- 5000L, /* should be large */
- 30L,
- 1L, /* replace indicator */
- (long)NULL, /* result set name */
- database_names, /* database name */
- (long)QT_RelevanceFeedbackQuery, /* query_type */
- 0L, /* element name */
- (long)NULL, /* reference ID */
- query);
-
- end_ptr = writeSearchAPDU(search3, buff, buff_len);
-
- CSTFreeWAISSearch(query);
- freeSearchAPDU(search3);
- return(end_ptr);
- }
-
-
- /* returns a pointer into the buffer of the next free byte.
- if it overflowed, then NULL is returned
- */
-
- char *
- generate_retrieval_apdu(buff,
- buff_len,
- docID,
- chunk_type,
- start,
- end,
- type,
- database_name)
- char *buff;
- long *buff_len; /* length of the buffer changed to reflect new data written */
- any *docID;
- long chunk_type;
- long start;
- long end;
- char *type;
- char *database_name;
- {
- SearchAPDU *search;
- char *end_ptr;
-
- static char *database_names[2];
- static char *element_names[3];
- any refID;
-
- DocObj *DocObjs[2];
- any *query; /* changed from char* by brewster */
-
- if(NULL == type)
- type = s_strdup("TEXT");
-
- database_names[0] = database_name;
- database_names[1] = NULL;
-
- element_names[0] = " ";
- element_names[1] = ES_DocumentText;
- element_names[2] = NULL;
-
- refID.size = 1L;
- refID.bytes = "3";
-
- switch(chunk_type){
- case CT_line:
- DocObjs[0] = makeDocObjUsingLines(docID, type, start, end);
- break;
- case CT_byte:
- DocObjs[0] = makeDocObjUsingBytes(docID, type, start, end);
- break;
- }
- DocObjs[1] = NULL;
-
- query = makeWAISTextQuery(DocObjs);
-
- search = makeSearchAPDU( 10L, 16L, 15L,
- 1L, /* replace indicator */
- "FOO", /* result set name */
- database_names, /* database name */
- QT_TextRetrievalQuery, /* query_type */
- element_names, /* element name */
- &refID, /* reference ID */
- query);
-
- end_ptr = writeSearchAPDU(search, buff, buff_len);
- CSTFreeWAISTextQuery(query);
- freeSearchAPDU(search);
- return(end_ptr);
- }
-
- static boolean isnumber _AP((char* string));
-
- static boolean isnumber(string)
- char *string;
- {
- long count;
- for(count = 0L; count < strlen(string); count++){
- if(!isdigit(string[count])){
- return(false);
- }
- }
- return(true);
- }
-
-
- /* this will negotiate with server, and returs the maximum buffer size
- the server can handle.
- */
-
- long init_connection(inBuffer, outBuffer, bufferSize, connection)
- char *inBuffer, *outBuffer;
- long bufferSize;
- SOCKET connection;
- {
- InitAPDU* init = NULL;
- InitResponseAPDU* reply = NULL;
- long result;
- /* construct an init */
- init = makeInitAPDU(true,false,false,false,false,bufferSize,bufferSize,
- NULL,defaultImplementationID(),
- defaultImplementationName(),
- defaultImplementationVersion(),NULL,NULL);
- /* write it to the buffer */
- result = (long)(writeInitAPDU(init,inBuffer+HEADER_LENGTH,(long *)&bufferSize) - inBuffer);
- if(result < 0L){
- freeInitAPDU(init);
- return(-1L);
- }
- if (0 == interpret_message(inBuffer,
- (long)(result - HEADER_LENGTH),
- outBuffer,
- bufferSize,
- connection,
- false)) /* true verbose */
- {
- /* error making a connection */
- return (-1L);
- }
- if (readInitResponseAPDU(&reply,outBuffer + HEADER_LENGTH) == NULL){
- freeWAISInitResponse((WAISInitResponse*)reply->UserInformationField);
- freeInitResponseAPDU(reply);
- return(-1L);
- }
- if (reply->Result == false)
- { /* the server declined service */
- freeWAISInitResponse((WAISInitResponse*)reply->UserInformationField);
- freeInitResponseAPDU(reply);
- return(-1L);
- }
- else /* we got a response back */
- {
- result = reply->MaximumRecordSize;
- freeWAISInitResponse((WAISInitResponse*)reply->UserInformationField);
- freeInitResponseAPDU(reply);
- return(result);
- }
- }
-
- /* this is a safe version of unix 'read' it does all the checking
- * and looping necessary
- * to those trying to modify the transport code to use non-UNIX streams:
- * This is the function to modify!
- */
-
- long read_from_stream(d,buf,nbytes)
- SOCKET d; /* this is the stream */
- char *buf;
- long nbytes;
- {
-
- int didRead, max;
- int status;
-
- long totalRead = 0;
- unsigned long toRead = nbytes;
-
- while(toRead > 0)
- {
- didRead = 0;
- max = toRead < recv_bufsize ? toRead : recv_bufsize;
-
- if (SOCKET_ERROR == (didRead = recv(d, buf, max, 0)))
- {
- msgbox("RECV Error: %d");
- return(-1);
- }
-
- buf[didRead] = '\0';
- toRead -= didRead;
- buf += didRead;
- totalRead += didRead;
- }
-
- if(totalRead != nbytes) /* we overread for some reason */
- return(- totalRead); /* bad news */
-
- return(totalRead);
- }
-
- /* returns the length of the response, 0 if an error */
-
- long
- transport_message(connection, request_message, request_length, response_message, response_buffer_length)
- SOCKET connection;
- char *request_message;
- long request_length;
- char *response_message;
- long response_buffer_length;
- {
-
- WAISMessage header;
- long response_length;
- int didSend, max;
- char bf[20];
- FILE *fp;
-
- int status;
-
- long toSend = request_length + HEADER_LENGTH;
- long totalSend = 0;
-
- /* Write out message. Read back header. Figure out response length. */
-
- while (toSend > 0)
- {
- max = toSend < send_bufsize ? toSend : send_bufsize;
- if (SOCKET_ERROR == (didSend = send(connection, request_message, max, 0)))
- {
- msgbox("SEND Error: %d");
- return(0L);
- }
- toSend -= didSend;
- request_message += didSend;
- totalSend += didSend;
- }
-
- if (request_length + HEADER_LENGTH != totalSend)
- return 0L;
-
- /* read for the first '0' */
-
- while(1)
- {
- if(0L > read_from_stream(connection, response_message, 1L))
- return 0L;
- if('0' == response_message[0])
- break;
- }
-
- if(0L > read_from_stream(connection,
- response_message + 1,
- (long)(HEADER_LENGTH - 1L)))
- return 0L;
-
- readWAISPacketHeader(response_message, &header);
- {
- char length_array[11];
- strncpy(length_array, header.msg_len, 10);
- length_array[10] = '\0';
- response_length = atol(length_array);
- if(response_length > response_buffer_length)
- {
- /* we got a message that is too long,
- therefore empty the message out,
- and return 0
- */
- long i;
- for(i = 0L; i < response_length; i++)
- {
- read_from_stream(connection,
- response_message + HEADER_LENGTH,
- 1L);
- }
- return(0L);
- }
- }
-
- if(0L > read_from_stream(connection,
- response_message + HEADER_LENGTH,
- response_length))
- return 0L;
-
- return(response_length);
- }
-
- /* returns the number of bytes writeen. 0 if an error */
- long
- interpret_message(request_message,request_length, response_message, response_buffer_length, connection, verbose)
- char *request_message;
- long request_length; /* length of the buffer */
- char *response_message;
- long response_buffer_length;
- SOCKET connection;
- boolean verbose;
- {
- long response_length;
-
- writeWAISPacketHeader(request_message,
- request_length,
- (long)'z', /* Z39.50 */
- "wais ", /* server name */
- (long)NO_COMPRESSION, /* no compression */
- (long)NO_ENCODING,
- (long)HEADER_VERSION);
-
- if(connection != NULL)
- {
- if(0L == (response_length = transport_message(connection,
- request_message,
- request_length,
- response_message,
- response_buffer_length)))
- return(0L);
- }
- else
- {
- return(0L);
- }
-
- return(response_length);
- }
-
- /* this closes the connection to the socket.
- * the mythology is that this is cleaner than exiting
- */
-
- long close_connection(connection)
- SOCKET connection;
- {
- // if(connection != NULL)
- // {
- // sock_close(connection);
- // return(-1L);
- // }
-
- return(0L);
- }
-
-
- save_text_record_completely(record,quote_string_quotes,fp,entry_no)
- WAISDocumentText *record;
- boolean quote_string_quotes;
- FILE *fp;
- long entry_no;
- {
-
- static long lcnt;
- long count;
-
- if (entry_no == 0)
- lcnt = 0;
-
- for(count = 0L; count < record->DocumentText->size; count++){
-
- unsigned char ch = (unsigned char)record->DocumentText->bytes[count];
- if(27 == ch)
- {
- if('(' == record->DocumentText->bytes[count + 1L] ||
- ')' == record->DocumentText->bytes[count + 1L])
- count += 1L; /* it is a term marker */
- else count += 4L; /* it is a paragraph marker */
- }
- else if (ch == '\t') /* a TAB! */
- {
- putc(0x20, fp); /* change it to a space */
- lcnt++;
- }
- else if (isprint(ch))
- {
- if(quote_string_quotes && ch == '"')
- {
- putc('\\', fp);
- lcnt++;
- }
- putc(ch, fp);
- lcnt++;
- }
- else if (ch == '\n' || ch == '\r')
- {
- lcnt = lcnt % MAX_TEXT_LENGTH;
- for ( ; lcnt < MAX_TEXT_LENGTH; lcnt++)
- putc(0x20,fp);
- lcnt = 0;
- }
- }
- }
-
- save_binary_record_completely(record,fp)
- WAISDocumentText *record;
- FILE *fp;
- {
-
- long count;
-
- for(count = 0L; count < record->DocumentText->size; count++)
- {
- putc((unsigned char)record->DocumentText->bytes[count],fp);
- }
- }
-
- /* modifies the string to exclude all seeker codes. sets length to
- the new length. */
-
- char *delete_seeker_codes(string,length)
- char *string;
- long *length;
- {
- long original_count; /* index into the original string */
- long new_count = 0L; /* index into the collapsed string */
- for(original_count = 0L; original_count < *length; original_count++){
- if(27 == string[original_count]){
- /* then we have an escape code */
- /* if the next letter is '(' or ')', then ignore two letters */
- if('(' == string[original_count + 1] ||
- ')' == string[original_count + 1])
- original_count += 1; /* it is a term marker */
- else original_count += 4; /* it is a paragraph marker */
- }
- else string[new_count++] = string[original_count];
- }
- *length = new_count;
- return(string);
- }
-
- /* returns a pointer to a string with good stuff */
-
- char *trim_junk(headline)
- char *headline;
- {
- long length = strlen(headline) + 1; /* include the trailing null */
- long i;
- headline = delete_seeker_codes(headline, &length);
- /* delete leading spaces */
- for(i=0L; i < strlen(headline); i++){
- if(isprint(headline[i])){
- break;
- }
- }
-
- headline = headline + i;
-
- /* delete trailing stuff */
- if (strlen(headline) > 0)
- {
- for(i=strlen(headline) - 1 ; i > 0; i--)
- {
- if(isprint(headline[i]))
- break;
- headline[i] = '\0';
- }
- }
- return(headline);
- }
-
-