2010-03-08 04:55:21 -06:00
|
|
|
/* WorldWideWeb - Wide Area Informaion Server Access HTWAIS.c
|
|
|
|
** ==================================================
|
|
|
|
**
|
|
|
|
** This module allows a WWW server or client to read data from a
|
|
|
|
** remote WAIS
|
|
|
|
** server, and provide that data to a WWW client in hypertext form.
|
|
|
|
** Source files, once retrieved, are stored and used to provide
|
|
|
|
** information about the index when that is acessed.
|
|
|
|
**
|
|
|
|
** Authors
|
|
|
|
** BK Brewster Kahle, Thinking Machines, <Brewster@think.com>
|
|
|
|
** TBL Tim Berners-Lee, CERN <timbl@info.cern.ch>
|
|
|
|
**
|
|
|
|
** History
|
|
|
|
** Sep 91 TBL adapted shell-ui.c (BK) with HTRetrieve.c from WWW.
|
|
|
|
** Feb 91 TBL Generated HTML cleaned up a bit (quotes, escaping)
|
2013-03-09 18:59:42 -06:00
|
|
|
** Refers to lists of sources.
|
|
|
|
** Mar 93 TBL Lib 2.0 compatible module made.
|
2010-03-08 04:55:21 -06:00
|
|
|
**
|
|
|
|
** Bugs
|
|
|
|
** Uses C stream i/o to read and write sockets, which won't work
|
|
|
|
** on VMS TCP systems.
|
|
|
|
**
|
|
|
|
** Should cache connections.
|
|
|
|
**
|
|
|
|
** ANSI C only as written
|
|
|
|
**
|
|
|
|
** WAIS comments:
|
|
|
|
**
|
|
|
|
** 1. Separate directories for different system's .o would help
|
|
|
|
** 2. Document ids are rather long!
|
|
|
|
**
|
|
|
|
** WWW Address mapping convention:
|
|
|
|
**
|
|
|
|
** /servername/database/type/length/document-id
|
|
|
|
**
|
|
|
|
** /servername/database?word+word+word
|
|
|
|
*/
|
|
|
|
/* WIDE AREA INFORMATION SERVER SOFTWARE:
|
|
|
|
No guarantees or restrictions. See the readme file for the full standard
|
|
|
|
disclaimer.
|
|
|
|
|
|
|
|
Brewster@think.com
|
|
|
|
*/
|
|
|
|
#include "../config.h"
|
|
|
|
#ifdef DIRECT_WAIS
|
|
|
|
|
|
|
|
#define BIG 10000
|
|
|
|
|
|
|
|
/* From WAIS
|
|
|
|
** ---------
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <ui.h>
|
|
|
|
|
|
|
|
#define MAX_MESSAGE_LEN 100000
|
|
|
|
#define CHARS_PER_PAGE 4096 /* number of chars retrieved in each request */
|
|
|
|
|
|
|
|
|
|
|
|
/* FROM WWW
|
|
|
|
** --------
|
|
|
|
*/
|
|
|
|
#define HEX_ESCAPE '%'
|
|
|
|
|
|
|
|
#include "HTUtils.h"
|
|
|
|
#include "tcp.h"
|
|
|
|
#include "HTParse.h"
|
|
|
|
#include "HTAccess.h" /* We implement a protocol */
|
|
|
|
#include "HTML.h" /* The object we will generate */
|
|
|
|
#include "HTFile.h"
|
|
|
|
#include "HTAlert.h"
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
/* #include "ParseWSRC.h" */
|
|
|
|
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
extern int www2Trace;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
extern int WWW_TraceFlag; /* Control diagnostic output */
|
|
|
|
extern FILE * logfile; /* Log file output */
|
|
|
|
/*char *log_file_name = "/dev/null";*/
|
|
|
|
extern char *log_file_name; /* change for freeWAIS-0.5 - DXP */
|
|
|
|
|
|
|
|
PRIVATE char line[2048]; /* For building strings to display */
|
|
|
|
/* Must be able to take id */
|
|
|
|
|
|
|
|
|
|
|
|
#include "HTFormat.h"
|
|
|
|
#include "HTTCP.h"
|
|
|
|
/* #include "HTWSRC.h" */ /* Need some bits from here */
|
|
|
|
|
|
|
|
/* Hypertext object building machinery
|
|
|
|
*/
|
|
|
|
#include "HTML.h"
|
|
|
|
|
|
|
|
#define PUTC(c) (*target->isa->put_character)(target, c)
|
|
|
|
#define PUTBLOCK(c, len) (*target->isa->put_block)(target, c, len)
|
|
|
|
#define PUTS(s) (*target->isa->put_string)(target, s)
|
|
|
|
#define START(e) (*target->isa->start_element)(target, e, 0, 0)
|
|
|
|
#define END(e) (*target->isa->end_element)(target, e)
|
|
|
|
#define END_TARGET (*target->isa->end_document)(target)
|
|
|
|
#define FREE_TARGET (*target->isa->free)(target)
|
|
|
|
|
|
|
|
struct _HTStructured {
|
|
|
|
WWW_CONST HTStructuredClass * isa;
|
|
|
|
/* ... */
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _HTStream {
|
|
|
|
WWW_CONST HTStreamClass * isa;
|
|
|
|
/* ... */
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* showDiags
|
|
|
|
*/
|
|
|
|
/* modified from Jonny G's version in ui/question.c */
|
|
|
|
|
|
|
|
void showDiags ARGS2(
|
|
|
|
HTStream *, target,
|
|
|
|
diagnosticRecord **, d)
|
|
|
|
{
|
|
|
|
long i;
|
|
|
|
|
|
|
|
for (i = 0; d[i] != NULL; i++) {
|
|
|
|
if (d[i]->ADDINFO != NULL) {
|
|
|
|
PUTS("Diagnostic code is ");
|
|
|
|
PUTS(d[i]->DIAG);
|
|
|
|
PUTC(' ');
|
|
|
|
PUTS(d[i]->ADDINFO);
|
|
|
|
PUTC('\n'); ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Matrix of allowed characters in filenames
|
|
|
|
** -----------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
PRIVATE BOOL acceptable[256];
|
|
|
|
PRIVATE BOOL acceptable_inited = NO;
|
|
|
|
|
|
|
|
PRIVATE void init_acceptable NOARGS
|
|
|
|
{
|
|
|
|
unsigned int i;
|
2013-03-09 18:59:42 -06:00
|
|
|
char * good =
|
2010-03-08 04:55:21 -06:00
|
|
|
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./-_$";
|
|
|
|
for(i=0; i<256; i++) acceptable[i] = NO;
|
|
|
|
for(;*good; good++) acceptable[(unsigned int)*good] = YES;
|
|
|
|
acceptable_inited = YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Transform file identifier into WWW address
|
|
|
|
** ------------------------------------------
|
|
|
|
**
|
|
|
|
**
|
|
|
|
** On exit,
|
|
|
|
** returns nil if error
|
|
|
|
** pointer to malloced string (must be freed) if ok
|
|
|
|
*/
|
|
|
|
char * WWW_from_archie ARGS1 (char *, file)
|
|
|
|
{
|
|
|
|
char * end;
|
|
|
|
char * result;
|
|
|
|
char * colon;
|
|
|
|
for(end=file; *end > ' '; end++); /* assumes ASCII encoding*/
|
|
|
|
result = (char *)malloc(10 + (end-file));
|
|
|
|
if (!result) return result; /* Malloc error */
|
|
|
|
strcpy(result, "file://");
|
|
|
|
strncat(result, file, end-file);
|
|
|
|
colon = strchr(result+7, ':'); /* Expect colon after host */
|
|
|
|
if (colon) {
|
|
|
|
for(; colon[0]; colon[0]=colon[1], colon++); /* move down */
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
} /* WWW_from_archie */
|
|
|
|
|
|
|
|
/* Transform document identifier into URL
|
|
|
|
** --------------------------------------
|
|
|
|
**
|
|
|
|
** Bugs: A static buffer of finite size is used!
|
|
|
|
** The format of the docid MUST be good!
|
|
|
|
**
|
|
|
|
** On exit,
|
|
|
|
** returns nil if error
|
|
|
|
** pointer to malloced string (must be freed) if ok
|
|
|
|
*/
|
|
|
|
PRIVATE char hex [17] = "0123456789ABCDEF";
|
|
|
|
extern char from_hex PARAMS((char a)); /* In HTWSRC @@ */
|
|
|
|
|
|
|
|
PRIVATE char * WWW_from_WAIS ARGS1(any *, docid)
|
|
|
|
{
|
|
|
|
static unsigned char buf[BIG];
|
|
|
|
char num[10];
|
|
|
|
unsigned char * q = buf;
|
|
|
|
char * p = (docid->bytes);
|
|
|
|
int i, l;
|
|
|
|
#ifndef DISABLE_TRACE
|
2013-03-09 18:59:42 -06:00
|
|
|
if (www2Trace)
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
fprintf(stderr, "WAIS id (%d bytes) is ", (int)docid->size);
|
2013-03-09 18:59:42 -06:00
|
|
|
for (p = docid->bytes; p < docid->bytes + docid->size; p++)
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
if ((*p >= ' ') && (*p<= '~')) /* Assume ASCII! */
|
|
|
|
fprintf(stderr, "%c", *p);
|
|
|
|
else
|
|
|
|
fprintf(stderr, "<%x>", (unsigned)*p);
|
|
|
|
}
|
|
|
|
fprintf(stderr, "\n");
|
2013-03-09 18:59:42 -06:00
|
|
|
}
|
2010-03-08 04:55:21 -06:00
|
|
|
#endif
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
for (p = docid->bytes;
|
|
|
|
(p < docid->bytes+docid->size) &&
|
|
|
|
(q < &buf[BIG]);)
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace) fprintf(stderr, " Record type %d, length %d\n",
|
|
|
|
p[0], p[1]);
|
|
|
|
#endif
|
|
|
|
sprintf(num, "%d", (int)*p);
|
|
|
|
/*
|
|
|
|
bcopy(num, q, strlen(num));
|
|
|
|
*/
|
|
|
|
memcpy(q, num, strlen(num));
|
|
|
|
q += strlen(num);
|
|
|
|
p++;
|
|
|
|
*q++ = '='; /* Separate */
|
|
|
|
l = (int)((unsigned char)*p);
|
|
|
|
p++;
|
|
|
|
if (l > 127)
|
|
|
|
{
|
|
|
|
l = (l - 128) * 128;
|
|
|
|
l = l + (int)((unsigned char)*p);
|
|
|
|
p++;
|
|
|
|
}
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
for (i = 0; i < l; i++, p++)
|
|
|
|
{
|
2013-03-09 18:59:42 -06:00
|
|
|
if (!acceptable[(unsigned char)*p])
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
*q++ = HEX_ESCAPE;
|
|
|
|
*q++ = hex[((unsigned char)*p) >> 4];
|
|
|
|
*q++ = hex[((unsigned char)*p) & 15];
|
|
|
|
}
|
|
|
|
else *q++ = (unsigned char)*p;
|
|
|
|
}
|
|
|
|
*q++= ';'; /* Terminate field */
|
|
|
|
}
|
|
|
|
*q++ = 0; /* Terminate string */
|
|
|
|
#ifndef DISABLE_TRACE
|
2013-03-09 18:59:42 -06:00
|
|
|
if (www2Trace)
|
|
|
|
fprintf(stderr, "WWW form of id: %s\n", buf);
|
2010-03-08 04:55:21 -06:00
|
|
|
#endif
|
|
|
|
|
|
|
|
{
|
|
|
|
char * result = (char *)malloc (strlen (buf) + 1);
|
|
|
|
strcpy (result, buf);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
} /* WWW_from_WAIS */
|
|
|
|
|
|
|
|
|
|
|
|
/* Transform URL into WAIS document identifier
|
|
|
|
** -------------------------------------------
|
|
|
|
**
|
|
|
|
** On entry,
|
|
|
|
** docname points to valid name produced originally by
|
|
|
|
** WWW_from_WAIS
|
|
|
|
** On exit,
|
|
|
|
** docid->size is valid
|
|
|
|
** docid->bytes is malloced and must later be freed.
|
|
|
|
*/
|
|
|
|
PRIVATE any * WAIS_from_WWW ARGS2 (any *, docid, char *, docname)
|
|
|
|
{
|
|
|
|
char *z; /* Output pointer */
|
|
|
|
char *sor; /* Start of record - points to size field. */
|
|
|
|
char *p; /* Input pointer */
|
|
|
|
char *q; /* Poisition of "=" */
|
|
|
|
char *s; /* Position of semicolon */
|
|
|
|
int n; /* size */
|
|
|
|
|
|
|
|
#ifndef DISABLE_TRACE
|
2013-03-09 18:59:42 -06:00
|
|
|
if (www2Trace)
|
|
|
|
fprintf(stderr, "WWW id (to become WAIS id): %s\n", docname);
|
2010-03-08 04:55:21 -06:00
|
|
|
#endif
|
2013-03-09 18:59:42 -06:00
|
|
|
for(n=0, p = docname; *p; p++)
|
2010-03-08 04:55:21 -06:00
|
|
|
{ /* Count sizes of strings */
|
|
|
|
n++;
|
|
|
|
if (*p == ';') n--; /* Not converted */
|
|
|
|
else if (*p == HEX_ESCAPE) n=n-2; /* Save two bytes */
|
|
|
|
docid->size = n;
|
|
|
|
}
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
docid->bytes = (char *) malloc(docid->size + 32); /* result record */
|
|
|
|
z = docid->bytes;
|
2013-03-09 18:59:42 -06:00
|
|
|
|
|
|
|
for(p = docname; *p; )
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
q = strchr(p, '=');
|
2013-03-09 18:59:42 -06:00
|
|
|
if (!q)
|
2010-03-08 04:55:21 -06:00
|
|
|
return 0;
|
|
|
|
*q = '\0';
|
|
|
|
*z++ = atoi(p);
|
|
|
|
*q = '=';
|
|
|
|
s = strchr(q, ';'); /* (Check only) */
|
2013-03-09 18:59:42 -06:00
|
|
|
if (!s)
|
2010-03-08 04:55:21 -06:00
|
|
|
return 0; /* Bad! No ';'; */
|
|
|
|
sor = z; /* Remember where the size field was */
|
|
|
|
z++; /* Skip record size for now */
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
int len;
|
|
|
|
int tmp;
|
2013-03-09 18:59:42 -06:00
|
|
|
for(p=q+1; *p!=';' ; )
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
2013-03-09 18:59:42 -06:00
|
|
|
if (*p == HEX_ESCAPE)
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
char c;
|
|
|
|
unsigned int b;
|
|
|
|
p++;
|
|
|
|
c = *p++;
|
|
|
|
b = from_hex(c);
|
|
|
|
c = *p++;
|
2013-03-09 18:59:42 -06:00
|
|
|
if (!c)
|
2010-03-08 04:55:21 -06:00
|
|
|
break; /* Odd number of chars! */
|
|
|
|
*z++ = (b<<4) + from_hex(c);
|
2013-03-09 18:59:42 -06:00
|
|
|
}
|
|
|
|
else
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
*z++ = *p++; /* Record */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
len = (z-sor-1);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
z = sor;
|
|
|
|
if (len > 127)
|
|
|
|
{
|
|
|
|
tmp = (len / 128);
|
|
|
|
len = len - (tmp * 128);
|
|
|
|
tmp = tmp + 128;
|
|
|
|
*z++ = (char)tmp;
|
|
|
|
*z = (char)len;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*z = (char)len;
|
|
|
|
}
|
|
|
|
z++;
|
|
|
|
}
|
2013-03-09 18:59:42 -06:00
|
|
|
|
|
|
|
for(p=q+1; *p!=';' ; )
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
2013-03-09 18:59:42 -06:00
|
|
|
if (*p == HEX_ESCAPE)
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
char c;
|
|
|
|
unsigned int b;
|
|
|
|
p++;
|
|
|
|
c = *p++;
|
|
|
|
b = from_hex(c);
|
|
|
|
c = *p++;
|
2013-03-09 18:59:42 -06:00
|
|
|
if (!c)
|
2010-03-08 04:55:21 -06:00
|
|
|
break; /* Odd number of chars! */
|
|
|
|
*z++ = (b<<4) + from_hex(c);
|
2013-03-09 18:59:42 -06:00
|
|
|
}
|
|
|
|
else
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
*z++ = *p++; /* Record */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
p++; /* After semicolon: start of next record */
|
|
|
|
}
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
#ifndef DISABLE_TRACE
|
2013-03-09 18:59:42 -06:00
|
|
|
if (www2Trace)
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
fprintf(stderr, "WAIS id (%d bytes) is ", (int)docid->size);
|
|
|
|
for(p=docid->bytes; p<docid->bytes+docid->size; p++) {
|
|
|
|
if ((*p >= ' ') && (*p<= '~'))
|
|
|
|
fprintf(stderr, "%c", *p);
|
|
|
|
else
|
|
|
|
fprintf(stderr, "<%x>", (unsigned)*p);
|
|
|
|
}
|
|
|
|
fprintf(stderr, "\n");
|
2013-03-09 18:59:42 -06:00
|
|
|
}
|
2010-03-08 04:55:21 -06:00
|
|
|
#endif
|
|
|
|
return docid; /* Ok */
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
} /* WAIS_from_WWW */
|
|
|
|
|
|
|
|
|
|
|
|
/* Send a plain text record to the client output_text_record()
|
|
|
|
** --------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
PRIVATE void output_text_record ARGS3(
|
|
|
|
HTStream *, target,
|
|
|
|
WAISDocumentText *, record,
|
|
|
|
boolean, quote_string_quotes)
|
|
|
|
{
|
|
|
|
if (record->DocumentText->size)
|
|
|
|
{
|
|
|
|
/* This cast should be unnecessary, as put_block should operate
|
|
|
|
on unsigned char from the start. What was he thinking??? */
|
|
|
|
PUTBLOCK((unsigned char *)record->DocumentText->bytes,
|
|
|
|
record->DocumentText->size);
|
2013-03-09 18:59:42 -06:00
|
|
|
}
|
2010-03-08 04:55:21 -06:00
|
|
|
} /* output text record */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Format A Search response for the client display_search_response
|
|
|
|
** ---------------------------------------
|
|
|
|
*/
|
|
|
|
/* modified from tracy shen's version in wutil.c
|
|
|
|
* displays either a text record or a set of headlines.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
display_search_response ARGS4(
|
|
|
|
HTStructured *, target,
|
|
|
|
SearchResponseAPDU *, response,
|
|
|
|
char *, database,
|
|
|
|
char *, keywords)
|
|
|
|
{
|
|
|
|
WAISSearchResponse *info;
|
|
|
|
long i, k;
|
|
|
|
BOOL archie;
|
|
|
|
|
|
|
|
if (!response)
|
|
|
|
{
|
|
|
|
PUTS("Arrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrgh!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
archie = strstr(database, "archie")!=0; /* Specical handling */
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
#ifndef DISABLE_TRACE
|
2013-03-09 18:59:42 -06:00
|
|
|
if (www2Trace)
|
2010-03-08 04:55:21 -06:00
|
|
|
fprintf(stderr, "HTWAIS: Displaying search response\n");
|
|
|
|
#endif
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace)
|
|
|
|
fprintf (stderr, "HTWAIS: database 0x%08x '%s', response 0x%08x\n",
|
|
|
|
database, database, response);
|
|
|
|
#endif
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace)
|
|
|
|
fprintf (stderr, "HTWAIS: keywords 0x%08x '%s'\n", keywords, keywords);
|
|
|
|
#endif
|
|
|
|
sprintf(line,
|
|
|
|
"Index %s contains the following %d item%s relevant to '%s'.\n",
|
|
|
|
database,
|
|
|
|
(int)(response->NumberOfRecordsReturned),
|
|
|
|
response->NumberOfRecordsReturned ==1 ? "" : "s",
|
|
|
|
keywords);
|
|
|
|
|
|
|
|
PUTS(line);
|
|
|
|
PUTS("The first figure for each entry is its relative score, ");
|
|
|
|
PUTS("the second the number of lines in the item.");
|
|
|
|
START(HTML_MENU);
|
|
|
|
|
|
|
|
if ( response->DatabaseDiagnosticRecords != 0 ) {
|
|
|
|
info = (WAISSearchResponse *)response->DatabaseDiagnosticRecords;
|
2013-03-09 18:59:42 -06:00
|
|
|
i =0;
|
2010-03-08 04:55:21 -06:00
|
|
|
|
|
|
|
if (info->Diagnostics != NULL)
|
|
|
|
showDiags((HTStream*)target, info->Diagnostics);
|
|
|
|
|
|
|
|
if ( info->DocHeaders != 0 ) {
|
|
|
|
for (k=0; info->DocHeaders[k] != 0; k++ ) {
|
|
|
|
WAISDocumentHeader* head = info->DocHeaders[k];
|
|
|
|
char * headline = trim_junk(head->Headline);
|
|
|
|
any * docid = head->DocumentID;
|
|
|
|
char * docname; /* printable version of docid */
|
|
|
|
i++;
|
|
|
|
|
|
|
|
/* Make a printable string out of the document id.
|
|
|
|
*/
|
|
|
|
#ifndef DISABLE_TRACE
|
2013-03-09 18:59:42 -06:00
|
|
|
if (www2Trace) fprintf(stderr,
|
|
|
|
"HTWAIS: %2ld: Score: %4ld, lines:%4ld '%s'\n",
|
2010-03-08 04:55:21 -06:00
|
|
|
i,
|
|
|
|
(long int)(info->DocHeaders[k]->Score),
|
|
|
|
(long int)(info->DocHeaders[k]->Lines),
|
|
|
|
headline);
|
|
|
|
#endif
|
|
|
|
START(HTML_LI);
|
|
|
|
sprintf(line, "%4ld %4ld ",
|
|
|
|
head->Score,
|
|
|
|
head->Lines);
|
|
|
|
PUTS( line);
|
|
|
|
|
|
|
|
if (archie) {
|
|
|
|
char * www_name = WWW_from_archie(headline);
|
|
|
|
if (www_name) {
|
|
|
|
PUTS ("<A HREF=\"");
|
|
|
|
PUTS (www_name);
|
|
|
|
PUTS ("\">");
|
|
|
|
PUTS(headline);
|
|
|
|
PUTS("</A>");
|
|
|
|
free(www_name);
|
|
|
|
} else {
|
|
|
|
PUTS(headline);
|
|
|
|
PUTS(" (bad file name)");
|
|
|
|
}
|
|
|
|
} else { /* Not archie */
|
|
|
|
docname = WWW_from_WAIS(docid);
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace)
|
|
|
|
fprintf (stderr, "HTWAIS: docname '%s'\n", docname);
|
|
|
|
#endif
|
|
|
|
if (docname) {
|
|
|
|
char * dbname = HTEscape(database);
|
|
|
|
char types_array[1000]; /* bad */
|
|
|
|
char *type_escaped;
|
|
|
|
|
|
|
|
types_array[0] = 0;
|
|
|
|
|
|
|
|
if (head->Types)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; head->Types[i]; i++)
|
|
|
|
{
|
|
|
|
if (i)
|
|
|
|
strcat (types_array, ",");
|
|
|
|
|
|
|
|
type_escaped = HTEscape (head->Types[i]);
|
|
|
|
strcat (types_array, type_escaped);
|
|
|
|
free (type_escaped);
|
|
|
|
}
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace)
|
|
|
|
fprintf (stderr, "Built types_array '%s'\n", types_array);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strcat (types_array, "TEXT");
|
|
|
|
}
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
sprintf(line, "%s/%s/%d/%s",
|
|
|
|
dbname,
|
|
|
|
types_array,
|
|
|
|
(int)(head->DocumentLength),
|
|
|
|
docname);
|
|
|
|
|
|
|
|
PUTS ("<A HREF=\"");
|
2013-03-09 18:59:42 -06:00
|
|
|
if (head->Types && head->Types[0] &&
|
2010-03-08 04:55:21 -06:00
|
|
|
strcmp (head->Types[0], "URL") == 0)
|
|
|
|
{
|
|
|
|
/* The real URL, maybe? */
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace)
|
|
|
|
fprintf (stderr, "HTWAIS: Using headline '%s' as URL\n",
|
|
|
|
headline);
|
|
|
|
#endif
|
|
|
|
PUTS(headline);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Our manufactured URL. */
|
|
|
|
PUTS (line);
|
|
|
|
}
|
|
|
|
PUTS ("\">");
|
|
|
|
PUTS(headline);
|
|
|
|
PUTS("</A>");
|
|
|
|
free(dbname);
|
|
|
|
free(docname);
|
|
|
|
} else {
|
|
|
|
PUTS("(bad doc id)");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} /* next document header */
|
|
|
|
} /* if there were any document headers */
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
if ( info->ShortHeaders != 0 ) {
|
|
|
|
k =0;
|
|
|
|
while (info->ShortHeaders[k] != 0 ) {
|
|
|
|
i++;
|
|
|
|
PUTS( "(Short Header record, can't display)");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( info->LongHeaders != 0 ) {
|
|
|
|
k =0;
|
|
|
|
while (info->LongHeaders[k] != 0) {
|
|
|
|
i++;
|
|
|
|
PUTS( "\nLong Header record, can't display\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( info->Text != 0 ) {
|
|
|
|
k =0;
|
|
|
|
while (info->Text[k] != 0) {
|
|
|
|
i++;
|
|
|
|
PUTS( "\nText record\n");
|
|
|
|
output_text_record((HTStream*)target, info->Text[k++], false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( info->Headlines != 0 ) {
|
|
|
|
k =0;
|
|
|
|
while (info->Headlines[k] != 0) {
|
|
|
|
i++;
|
|
|
|
PUTS( "\nHeadline record, can't display\n");
|
|
|
|
/* dsply_headline_record( info->Headlines[k++]); */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( info->Codes != 0 ) {
|
|
|
|
k =0;
|
|
|
|
while (info->Codes[k] != 0) {
|
|
|
|
i++;
|
|
|
|
PUTS( "\nCode record, can't display\n");
|
|
|
|
/* dsply_code_record( info->Codes[k++]); */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} /* Loop: display user info */
|
|
|
|
END(HTML_MENU);
|
|
|
|
PUTC('\n'); ;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
/* ---------------- Local copy of connect_to_server calls ----------------- */
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
|
|
|
|
/* Returns 1 on success, 0 on fail, -1 on interrupt. */
|
|
|
|
static int fd_mosaic_connect_to_server(char *host_name, long port, long *fd)
|
|
|
|
{
|
|
|
|
/* New version. */
|
|
|
|
char dummy[256];
|
|
|
|
int status;
|
|
|
|
|
|
|
|
sprintf (dummy, "wais://%s:%d/", host_name, port);
|
|
|
|
|
|
|
|
status = HTDoConnect (dummy, "WAIS", 210, (int *)fd);
|
|
|
|
if (status == HT_INTERRUPTED)
|
|
|
|
{
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace)
|
|
|
|
fprintf (stderr, "===WAIS=== interrupted in connect\n");
|
|
|
|
#endif
|
|
|
|
HTProgress ("Connection interrupted.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (status < 0)
|
|
|
|
return 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Returns 1 on success, 0 on fail, -1 on interrupt. */
|
|
|
|
static int mosaic_connect_to_server(char *host_name, long port, FILE **fp)
|
|
|
|
{
|
|
|
|
FILE* file;
|
|
|
|
long fd;
|
|
|
|
int rv;
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
rv = fd_mosaic_connect_to_server (host_name, port, &fd);
|
2013-03-09 18:59:42 -06:00
|
|
|
if(rv == 0)
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
HTProgress ("Could not connect to WAIS server.");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (rv == -1)
|
|
|
|
{
|
|
|
|
HTProgress ("Connection interrupted.");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-03-09 18:59:42 -06:00
|
|
|
if ((file = fdopen(fd,"r+")) == NULL)
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
HTProgress ("Could not open WAIS connection for reading.");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
*fp = file;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
/* ------------------------------------------------------------------------ */
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
/* Pulled in from gui.c; corresponds to Rdata.max_wais_responses. */
|
|
|
|
extern int max_wais_responses;
|
|
|
|
|
|
|
|
#define MAX_KEYWORDS_LENGTH 5000
|
|
|
|
#define MAX_SERVER_LENGTH 1000
|
|
|
|
#define MAX_DATABASE_LENGTH 1000
|
|
|
|
#define MAX_SERVICE_LENGTH 1000
|
|
|
|
#define MAXDOCS max_wais_responses
|
|
|
|
|
|
|
|
/* Load by name HTLoadWAIS
|
|
|
|
** ============
|
|
|
|
**
|
|
|
|
** This renders any object or search as required
|
|
|
|
*/
|
|
|
|
PUBLIC int HTLoadWAIS ARGS4(
|
|
|
|
WWW_CONST char *, arg,
|
|
|
|
HTParentAnchor *, anAnchor,
|
|
|
|
HTFormat, format_out,
|
|
|
|
HTStream*, sink)
|
|
|
|
{
|
|
|
|
char *key; /* pointer to keywords in URL */
|
|
|
|
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 *retrieval_response = 0;
|
|
|
|
char keywords[MAX_KEYWORDS_LENGTH + 1];
|
2013-03-09 18:59:42 -06:00
|
|
|
char *server_name;
|
2010-03-08 04:55:21 -06:00
|
|
|
char *wais_database = NULL; /* name of current database */
|
|
|
|
char *www_database; /* Same name escaped */
|
|
|
|
char *service;
|
|
|
|
char *doctype;
|
|
|
|
char *doclength;
|
|
|
|
long document_length;
|
|
|
|
char *docname;
|
|
|
|
FILE *connection = 0;
|
|
|
|
char *names; /* Copy of arg to be hacked up */
|
|
|
|
BOOL ok = NO;
|
|
|
|
WAISSearchResponse *response;
|
|
|
|
diagnosticRecord **diag;
|
2013-03-09 18:59:42 -06:00
|
|
|
|
|
|
|
if (!acceptable_inited)
|
2010-03-08 04:55:21 -06:00
|
|
|
init_acceptable();
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
/* Decipher and check syntax of WWW address:
|
|
|
|
** ----------------------------------------
|
|
|
|
**
|
|
|
|
** First we remove the "wais:" if it was spcified. 920110
|
2013-03-09 18:59:42 -06:00
|
|
|
*/
|
2010-03-08 04:55:21 -06:00
|
|
|
names = HTParse(arg, "", PARSE_HOST | PARSE_PATH | PARSE_PUNCTUATION);
|
|
|
|
key = strchr(names, '?');
|
2013-03-09 18:59:42 -06:00
|
|
|
|
|
|
|
if (key)
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
char * p;
|
|
|
|
*key++ = 0; /* Split off keywords */
|
|
|
|
for (p=key; *p; p++) if (*p == '+') *p = ' ';
|
|
|
|
HTUnEscape(key);
|
|
|
|
}
|
2013-03-09 18:59:42 -06:00
|
|
|
if (names[0]== '/')
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
server_name = names+1;
|
|
|
|
if (*server_name == '/')
|
|
|
|
server_name++; /* Accept one or two */
|
|
|
|
www_database = strchr(server_name,'/');
|
2013-03-09 18:59:42 -06:00
|
|
|
if (www_database)
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
*www_database++ = 0; /* Separate database name */
|
|
|
|
doctype = strchr(www_database, '/');
|
2013-03-09 18:59:42 -06:00
|
|
|
if (key)
|
2010-03-08 04:55:21 -06:00
|
|
|
ok = YES; /* Don't need doc details */
|
2013-03-09 18:59:42 -06:00
|
|
|
else if (doctype)
|
2010-03-08 04:55:21 -06:00
|
|
|
{ /* If not search parse doc details */
|
|
|
|
*doctype++ = 0; /* Separate rest of doc address */
|
|
|
|
doclength = strchr(doctype, '/');
|
2013-03-09 18:59:42 -06:00
|
|
|
if(doclength)
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
*doclength++ = 0;
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
/* OK, now doclength should be the rest of the URL,
|
|
|
|
right??? */
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace)
|
2013-03-09 18:59:42 -06:00
|
|
|
fprintf (stderr,
|
2010-03-08 04:55:21 -06:00
|
|
|
"WAIS: doctype '%s', doclength\n~~~~\n%s\n~~~~\n",
|
|
|
|
doctype, doclength);
|
|
|
|
#endif
|
|
|
|
/* Multitype! */
|
|
|
|
if (strchr (doctype, ','))
|
|
|
|
{
|
2013-03-09 18:59:42 -06:00
|
|
|
HTStructured *target =
|
2010-03-08 04:55:21 -06:00
|
|
|
HTML_new(anAnchor, format_out, sink);
|
|
|
|
char *t, *oldt, *newt, *revised;
|
|
|
|
int first;
|
|
|
|
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace)
|
|
|
|
{
|
|
|
|
fprintf (stderr,
|
|
|
|
"WAIS: Hey boss, got multitype.\n");
|
|
|
|
fprintf (stderr,
|
|
|
|
"WAIS: names is '%s'\n", names);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
START(HTML_TITLE);
|
|
|
|
PUTS("Multiple Format Opportunity");
|
|
|
|
END(HTML_TITLE);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
START(HTML_H1);
|
|
|
|
PUTS("Multiple Format Opportunity");
|
|
|
|
END(HTML_H1);
|
|
|
|
|
|
|
|
PUTS("This is a multiformat WAIS response. You may pick the format of your choice from the list that follows: <p>\n\n<ul>\n");
|
|
|
|
|
|
|
|
/* Get the first doctype. */
|
|
|
|
t = strtok (doctype, ",");
|
|
|
|
|
|
|
|
/* oldt is a copy of the first doctype,
|
|
|
|
with leading period. */
|
|
|
|
oldt = (char *)malloc (strlen (t) + 16);
|
|
|
|
sprintf (oldt, ".%s", t);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
first = 1;
|
|
|
|
|
|
|
|
while (t && *t)
|
|
|
|
{
|
|
|
|
/* Got a type, as t. */
|
|
|
|
PUTS("<li> <a href=\"wais:");
|
|
|
|
PUTS(names);
|
|
|
|
PUTS("/");
|
|
|
|
PUTS(www_database);
|
|
|
|
PUTS("/");
|
|
|
|
PUTS(t);
|
|
|
|
PUTS("/");
|
|
|
|
PUTS(doclength);
|
|
|
|
PUTS("\">");
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
/* Unescape t in place; we don't need it anymore
|
|
|
|
after this anyway. */
|
|
|
|
HTUnEscape (t);
|
|
|
|
PUTS(t);
|
|
|
|
PUTS("</a>\n");
|
|
|
|
t = strtok (NULL, ",");
|
|
|
|
}
|
|
|
|
|
|
|
|
free (oldt);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
PUTS("</ul>");
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
END_TARGET;
|
|
|
|
FREE_TARGET;
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
/* Hey, WE'RE DONE! */
|
|
|
|
free (names);
|
|
|
|
return HT_LOADED;
|
|
|
|
}
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
document_length = atol(doclength);
|
2013-03-09 18:59:42 -06:00
|
|
|
if (document_length)
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
docname=strchr(doclength, '/');
|
2013-03-09 18:59:42 -06:00
|
|
|
if (docname)
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
*docname++ = 0;
|
|
|
|
ok = YES; /* To avoid a goto! */
|
|
|
|
} /* if docname */
|
|
|
|
} /* if document_length valid */
|
|
|
|
} /* if doclength */
|
2013-03-09 18:59:42 -06:00
|
|
|
}
|
|
|
|
else
|
2010-03-08 04:55:21 -06:00
|
|
|
{ /* no doctype? Assume index required */
|
|
|
|
if (!key) key = "";
|
|
|
|
ok = YES;
|
|
|
|
} /* if doctype */
|
|
|
|
} /* if database */
|
|
|
|
}
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
if (!ok)
|
|
|
|
{
|
|
|
|
free (names);
|
|
|
|
return HT_NOT_LOADED;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef DISABLE_TRACE
|
2013-03-09 18:59:42 -06:00
|
|
|
if (www2Trace)
|
2010-03-08 04:55:21 -06:00
|
|
|
fprintf(stderr, "HTWAIS: Parsed OK; type is '%s'\n", doctype);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
service = strchr(names, ':');
|
2013-03-09 18:59:42 -06:00
|
|
|
if (service)
|
2010-03-08 04:55:21 -06:00
|
|
|
*service++ = 0;
|
2013-03-09 18:59:42 -06:00
|
|
|
else
|
2010-03-08 04:55:21 -06:00
|
|
|
service = "210";
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
if (server_name[0] == 0)
|
|
|
|
connection = NULL;
|
|
|
|
else if (!(key && !*key))
|
|
|
|
{
|
|
|
|
int status;
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace)
|
|
|
|
fprintf (stderr, "===WAIS=== calling mosaic_connect_to_server\n");
|
|
|
|
#endif
|
|
|
|
status = mosaic_connect_to_server
|
|
|
|
(server_name, atoi(service), &connection);
|
|
|
|
if (status == 0)
|
|
|
|
{
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace)
|
|
|
|
fprintf (stderr, "===WAIS=== connection failed\n");
|
|
|
|
#endif
|
|
|
|
free(names);
|
|
|
|
return HT_NOT_LOADED;
|
|
|
|
}
|
|
|
|
else if (status == -1)
|
|
|
|
{
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace)
|
|
|
|
fprintf (stderr, "===WAIS=== connection interrupted\n");
|
|
|
|
#endif
|
|
|
|
free(names);
|
|
|
|
return HT_INTERRUPTED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
StrAllocCopy(wais_database,www_database);
|
|
|
|
HTUnEscape(wais_database);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
/* This below fixed size stuff is terrible */
|
|
|
|
request_message = (char*)s_malloc((size_t)MAX_MESSAGE_LEN * sizeof(char));
|
|
|
|
response_message = (char*)s_malloc((size_t)MAX_MESSAGE_LEN * sizeof(char));
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
/* If keyword search is performed but there are no keywords,
|
|
|
|
** the user has followed a link to the index itself. It would be
|
|
|
|
** appropriate at this point to send him the .SRC file - how?
|
|
|
|
*/
|
2013-03-09 18:59:42 -06:00
|
|
|
if (key && !*key)
|
2010-03-08 04:55:21 -06:00
|
|
|
{ /* I N D E X */
|
|
|
|
HTStructured * target = HTML_new(anAnchor, format_out, sink);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
START(HTML_TITLE);
|
|
|
|
PUTS(wais_database);
|
|
|
|
PUTS(" index");
|
|
|
|
END(HTML_TITLE);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
START(HTML_H1);
|
|
|
|
PUTS(wais_database);
|
|
|
|
END(HTML_H1);
|
|
|
|
|
|
|
|
START(HTML_ISINDEX);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
START(HTML_P);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
END_TARGET;
|
2013-03-09 18:59:42 -06:00
|
|
|
if (connection)
|
2010-03-08 04:55:21 -06:00
|
|
|
FW_close_connection(connection);
|
|
|
|
FREE_TARGET;
|
2013-03-09 18:59:42 -06:00
|
|
|
}
|
|
|
|
else if (key)
|
2010-03-08 04:55:21 -06:00
|
|
|
{ /* S E A R C H */
|
|
|
|
char *p;
|
|
|
|
HTStructured * target;
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
strncpy(keywords, key, MAX_KEYWORDS_LENGTH);
|
2013-03-09 18:59:42 -06:00
|
|
|
while(p=strchr(keywords, '+'))
|
2010-03-08 04:55:21 -06:00
|
|
|
*p = ' ';
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
/* Send advance title to get something fast to the other end */
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
target = HTML_new(anAnchor, format_out, sink);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
START(HTML_TITLE);
|
|
|
|
PUTS(keywords);
|
|
|
|
PUTS(" (in ");
|
|
|
|
PUTS(wais_database);
|
|
|
|
PUTS(")");
|
|
|
|
END(HTML_TITLE);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
START(HTML_H1);
|
|
|
|
PUTS(keywords);
|
|
|
|
END(HTML_H1);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
START(HTML_ISINDEX);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
request_buffer_length = MAX_MESSAGE_LEN; /* Amount left */
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace) fprintf(stderr, "HTWAIS: Search for `%s' in `%s'\n",
|
|
|
|
keywords, wais_database);
|
|
|
|
#endif
|
2013-03-09 18:59:42 -06:00
|
|
|
|
|
|
|
if(NULL == generate_search_apdu(request_message + HEADER_LENGTH,
|
|
|
|
&request_buffer_length,
|
2010-03-08 04:55:21 -06:00
|
|
|
keywords, wais_database, NULL, MAXDOCS))
|
|
|
|
{
|
|
|
|
HTProgress ("WAIS request too large; something went wrong.");
|
|
|
|
}
|
2013-03-09 18:59:42 -06:00
|
|
|
|
|
|
|
if(!interpret_message(request_message,
|
|
|
|
MAX_MESSAGE_LEN - request_buffer_length,
|
2010-03-08 04:55:21 -06:00
|
|
|
response_message,
|
|
|
|
MAX_MESSAGE_LEN,
|
|
|
|
connection,
|
|
|
|
false /* true verbose */
|
2013-03-09 18:59:42 -06:00
|
|
|
))
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
HTProgress ("WAIS returned message too large; something went wrong.");
|
2013-03-09 18:59:42 -06:00
|
|
|
}
|
|
|
|
else
|
2010-03-08 04:55:21 -06:00
|
|
|
{ /* returned message ok */
|
|
|
|
SearchResponseAPDU *query_response = 0;
|
|
|
|
readSearchResponseAPDU(&query_response,
|
|
|
|
response_message + HEADER_LENGTH);
|
|
|
|
/* We do want this to be called if !query_response, to
|
|
|
|
get our cute error message. */
|
2013-03-09 18:59:42 -06:00
|
|
|
display_search_response(target,
|
2010-03-08 04:55:21 -06:00
|
|
|
query_response, wais_database, keywords);
|
|
|
|
if (query_response)
|
|
|
|
{
|
|
|
|
if (query_response->DatabaseDiagnosticRecords)
|
|
|
|
freeWAISSearchResponse(query_response->DatabaseDiagnosticRecords);
|
|
|
|
freeSearchResponseAPDU( query_response);
|
|
|
|
}
|
|
|
|
} /* returned message not too large */
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
END_TARGET;
|
2013-03-09 18:59:42 -06:00
|
|
|
if (connection)
|
2010-03-08 04:55:21 -06:00
|
|
|
FW_close_connection(connection);
|
|
|
|
FREE_TARGET;
|
2013-03-09 18:59:42 -06:00
|
|
|
}
|
|
|
|
else
|
2010-03-08 04:55:21 -06:00
|
|
|
{ /* D O C U M E N T F E T C H */
|
|
|
|
HTFormat format_in;
|
|
|
|
HTStream * target;
|
|
|
|
long count;
|
|
|
|
any doc_chunk;
|
|
|
|
any * docid = &doc_chunk;
|
|
|
|
|
|
|
|
if (doctype)
|
|
|
|
HTUnEscape (doctype);
|
|
|
|
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace)
|
|
|
|
fprintf(stderr,
|
|
|
|
"===WAIS=== Retrieve document id `%s' type `%s' length %ld\n",
|
|
|
|
docname, doctype, document_length);
|
2013-03-09 18:59:42 -06:00
|
|
|
#endif
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
char *tmp_doctype = strdup (doctype);
|
|
|
|
char *tmp;
|
|
|
|
for (tmp = tmp_doctype; *tmp; tmp++)
|
|
|
|
*tmp = TOLOWER (*tmp);
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace)
|
|
|
|
fprintf (stderr,
|
|
|
|
"===WAIS=== Doing HTAtom_exists on '%s'\n", tmp_doctype);
|
|
|
|
#endif
|
|
|
|
format_in = HTAtom_exists (tmp_doctype);
|
|
|
|
free (tmp_doctype);
|
|
|
|
}
|
|
|
|
if (!format_in)
|
|
|
|
{
|
|
|
|
char dummy[256];
|
|
|
|
HTAtom *pencoding;
|
|
|
|
int compressed;
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
sprintf (dummy, "foo.%s", doctype);
|
|
|
|
format_in = HTFileFormat (dummy, &pencoding,
|
|
|
|
WWW_PLAINTEXT, &compressed);
|
|
|
|
/* Assume it will always be at *least* WWW_PLAINTEXT. */
|
|
|
|
}
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
target = HTStreamStack(format_in, format_out, 0, sink, anAnchor);
|
2013-03-09 18:59:42 -06:00
|
|
|
if (!target)
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
free (names);
|
2013-03-09 18:59:42 -06:00
|
|
|
if (connection)
|
2010-03-08 04:55:21 -06:00
|
|
|
FW_close_connection(connection);
|
|
|
|
return HT_NOT_LOADED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Decode hex or literal format for document ID
|
2013-03-09 18:59:42 -06:00
|
|
|
*/
|
2010-03-08 04:55:21 -06:00
|
|
|
WAIS_from_WWW(docid, docname);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
/* Loop over slices of the document
|
2013-03-09 18:59:42 -06:00
|
|
|
*/
|
2010-03-08 04:55:21 -06:00
|
|
|
{
|
|
|
|
int bytes = 0, intr;
|
|
|
|
char line[256];
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
HTClearActiveIcon ();
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
count = 0;
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
char *type = s_strdup(doctype); /* Gets freed I guess */
|
|
|
|
request_buffer_length = MAX_MESSAGE_LEN; /* Amount left */
|
|
|
|
#ifndef DISABLE_TRACE
|
2013-03-09 18:59:42 -06:00
|
|
|
if (www2Trace)
|
2010-03-08 04:55:21 -06:00
|
|
|
fprintf(stderr, "HTWAIS: Slice number %ld\n", count);
|
|
|
|
#endif
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
intr = HTCheckActiveIcon (1);
|
|
|
|
if (intr)
|
|
|
|
{
|
|
|
|
HTProgress ("Data transfer interrupted.");
|
|
|
|
(*target->isa->handle_interrupt)(target);
|
|
|
|
free (names);
|
2013-03-09 18:59:42 -06:00
|
|
|
if (connection)
|
2010-03-08 04:55:21 -06:00
|
|
|
FW_close_connection(connection);
|
|
|
|
return HT_INTERRUPTED;
|
|
|
|
}
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
if(generate_retrieval_apdu
|
|
|
|
(request_message + HEADER_LENGTH,
|
2013-03-09 18:59:42 -06:00
|
|
|
&request_buffer_length,
|
|
|
|
docid,
|
2010-03-08 04:55:21 -06:00
|
|
|
CT_byte,
|
|
|
|
count * CHARS_PER_PAGE,
|
|
|
|
(count + 1) * CHARS_PER_PAGE,
|
|
|
|
type,
|
|
|
|
wais_database
|
|
|
|
) == 0)
|
|
|
|
{
|
2013-03-09 18:59:42 -06:00
|
|
|
HTProgress
|
2010-03-08 04:55:21 -06:00
|
|
|
("WAIS error condition; retrieval may be unsuccessful.");
|
|
|
|
}
|
|
|
|
|
|
|
|
free (type);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
|
|
|
/* Actually do the transaction given by request_message */
|
2010-03-08 04:55:21 -06:00
|
|
|
if(0 ==
|
|
|
|
interpret_message
|
2013-03-09 18:59:42 -06:00
|
|
|
(request_message,
|
|
|
|
MAX_MESSAGE_LEN - request_buffer_length,
|
2010-03-08 04:55:21 -06:00
|
|
|
response_message,
|
|
|
|
MAX_MESSAGE_LEN,
|
|
|
|
connection,
|
2013-03-09 18:59:42 -06:00
|
|
|
false /* true verbose */
|
2010-03-08 04:55:21 -06:00
|
|
|
))
|
|
|
|
{
|
|
|
|
HTProgress ("WAIS error condition; retrieval may be unsuccessful.");
|
|
|
|
goto no_more_data;
|
|
|
|
}
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
/* Parse the result which came back into memory.
|
|
|
|
*/
|
2013-03-09 18:59:42 -06:00
|
|
|
readSearchResponseAPDU(&retrieval_response,
|
2010-03-08 04:55:21 -06:00
|
|
|
response_message + HEADER_LENGTH);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
|
|
|
response =
|
2010-03-08 04:55:21 -06:00
|
|
|
(WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords;
|
|
|
|
diag = response->Diagnostics;
|
|
|
|
|
|
|
|
if(NULL == response->Text)
|
|
|
|
{
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace)
|
|
|
|
fprintf (stderr, "WAIS: no more data (NULL response->Text)\n");
|
|
|
|
#endif
|
|
|
|
if (retrieval_response->DatabaseDiagnosticRecords)
|
2013-03-09 18:59:42 -06:00
|
|
|
freeWAISSearchResponse
|
2010-03-08 04:55:21 -06:00
|
|
|
(retrieval_response->DatabaseDiagnosticRecords);
|
|
|
|
freeSearchResponseAPDU (retrieval_response);
|
|
|
|
goto no_more_data;
|
2013-03-09 18:59:42 -06:00
|
|
|
}
|
2010-03-08 04:55:21 -06:00
|
|
|
else if
|
|
|
|
(((WAISSearchResponse *)
|
|
|
|
retrieval_response->DatabaseDiagnosticRecords)->Text[0]->DocumentText->size)
|
|
|
|
{
|
|
|
|
output_text_record
|
|
|
|
(target,
|
|
|
|
((WAISSearchResponse *)
|
|
|
|
retrieval_response->DatabaseDiagnosticRecords)->Text[0],
|
|
|
|
false);
|
|
|
|
} /* If text existed */
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace)
|
|
|
|
fprintf (stderr, "WAIS: no more data (fell through)\n");
|
|
|
|
#endif
|
|
|
|
if (retrieval_response->DatabaseDiagnosticRecords)
|
2013-03-09 18:59:42 -06:00
|
|
|
freeWAISSearchResponse
|
2010-03-08 04:55:21 -06:00
|
|
|
(retrieval_response->DatabaseDiagnosticRecords);
|
|
|
|
freeSearchResponseAPDU (retrieval_response);
|
|
|
|
goto no_more_data;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Slightly inaccurate for last slice. */
|
|
|
|
bytes += CHARS_PER_PAGE;
|
|
|
|
sprintf (line, "Read %d bytes of data.", bytes);
|
|
|
|
HTProgress (line);
|
|
|
|
|
|
|
|
if (diag &&
|
|
|
|
diag[0] &&
|
|
|
|
diag[0]->ADDINFO != NULL &&
|
|
|
|
!strcmp(diag[0]->DIAG, D_PresentRequestOutOfRange))
|
|
|
|
{
|
|
|
|
#ifndef DISABLE_TRACE
|
|
|
|
if (www2Trace)
|
|
|
|
fprintf (stderr, "WAIS: no more data (diag)\n");
|
|
|
|
#endif
|
|
|
|
if (retrieval_response->DatabaseDiagnosticRecords)
|
2013-03-09 18:59:42 -06:00
|
|
|
freeWAISSearchResponse
|
2010-03-08 04:55:21 -06:00
|
|
|
(retrieval_response->DatabaseDiagnosticRecords);
|
|
|
|
freeSearchResponseAPDU (retrieval_response);
|
|
|
|
goto no_more_data;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (retrieval_response->DatabaseDiagnosticRecords)
|
2013-03-09 18:59:42 -06:00
|
|
|
freeWAISSearchResponse
|
2010-03-08 04:55:21 -06:00
|
|
|
(retrieval_response->DatabaseDiagnosticRecords);
|
|
|
|
freeSearchResponseAPDU (retrieval_response);
|
|
|
|
|
|
|
|
count++;
|
|
|
|
} /* Loop over slices */
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
} /* local variables */
|
|
|
|
|
|
|
|
no_more_data:
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
END_TARGET;
|
|
|
|
/* Close the connection BEFORE calling system(), which can
|
|
|
|
happen in the free method. */
|
2013-03-09 18:59:42 -06:00
|
|
|
if (connection)
|
2010-03-08 04:55:21 -06:00
|
|
|
FW_close_connection(connection);
|
|
|
|
FREE_TARGET;
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
free (docid->bytes);
|
|
|
|
} /* If document rather than search */
|
2013-03-09 18:59:42 -06:00
|
|
|
|
|
|
|
if (wais_database)
|
2010-03-08 04:55:21 -06:00
|
|
|
free (wais_database);
|
|
|
|
s_free (request_message);
|
|
|
|
s_free(response_message);
|
2013-03-09 18:59:42 -06:00
|
|
|
|
2010-03-08 04:55:21 -06:00
|
|
|
free(names);
|
|
|
|
return HT_LOADED;
|
|
|
|
}
|
|
|
|
|
|
|
|
PUBLIC HTProtocol HTWAIS = { "wais", HTLoadWAIS, NULL };
|
|
|
|
|
|
|
|
#endif /* DIRECT_WAIS */
|