⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htwsrc.c

📁 www工具包. 这是W3C官方支持的www支撑库. 其中提供通用目的的客户端的WebAPI: complete HTTP/1.1 (with caching, pipelining, PUT, POS
💻 C
字号:
/*								       HTWSRC.c**	PARSE WAIS SOURCE FILE****	(c) COPYRIGHT MIT 1995.**	Please first read the full copyright statement in the file COPYRIGH.**	@(#) $Id: HTWSRC.c,v 2.37 1999/02/22 22:10:12 frystyk Exp $****	This module parses a stream with WAIS source file**	format information on it and creates a structured stream.**	That structured stream is then converted into whatever.****	3 Jun 93	Bug fix: Won't crash if no description**	8 Jul 94  FM	Insulate free() from _free structure element.*//* Library include files */#include "wwwsys.h"#include "HTUtils.h"#include "HTString.h"#include "HTMLPDTD.h"#include "HTMLGen.h"#include "HTParse.h"#include "HTReqMan.h"#include "HTProxy.h"#include "HTWSRC.h"					 /* Implemented here */#define BIG 10000		/* Arbitrary limit to value length */#define PARAM_MAX BIG#define CACHE_PERIOD (7*86400)	/* Time to keep .src file in seconds */#define HEX_ESCAPE '%'struct _HTStructured {	const HTStructuredClass *	isa;	/* ... */};#define PUTC(c) (*me->target->isa->put_character)(me->target, c)#define PUTS(s) (*me->target->isa->put_string)(me->target, s)#define START(e) (*me->target->isa->start_element)(me->target, e, 0, 0)#define END(e) (*me->target->isa->end_element)(me->target, e)/*	Here are the parameters which can be specified in a  source file*/PRIVATE const char* par_name[] = {	"version", 	"ip-address",#define PAR_IP_NAME 2	"ip-name", #define PAR_TCP_PORT 3	"tcp-port", #define PAR_DATABASE_NAME 4	"database-name",#define PAR_COST 5	"cost", #define PAR_COST_UNIT 6	"cost-unit", #define PAR_FREE 7	"free",	#define PAR_MAINTAINER 8	"maintainer", 	#define PAR_DESCRIPTION 9	"description",	"keyword-list", 		"source",#define PAR_UNKNOWN 12	"unknown",	0,				/* Terminate list */#define PAR_COUNT 13} ;#if 0PRIVATE  const char * hex = "0123456789ABCDEF";#endifenum tokenstate { beginning, before_tag, colon, before_value,		value, bracketed_value, quoted_value, escape_in_quoted, done };/*		Stream Object**		------------****	The target is the structured stream down which the**	parsed results will go.****	all the static stuff below should go in here to make it reentrant*/struct _HTStream {	const HTStreamClass *	isa;	HTStructured *		target;	HTRequest *		request;	char *			par_value[PAR_COUNT];	enum tokenstate 	state;	char 			param[BIG+1];	int			param_number;	int			param_count;};#if 0/*	Decode one hex character*/PRIVATE char from_hex (char c){    return 		  (c>='0')&&(c<='9') ? c-'0'			: (c>='A')&&(c<='F') ? c-'A'+10			: (c>='a')&&(c<='f') ? c-'a'+10			:		       0;}#endif/*			State machine**			-------------**** On entry,**	me->state	is a valid state (see WSRC_init)**	c		is the next character** On exit,** 	returns	1	Done with file**		0	Continue. me->state is updated if necessary.**		-1	Syntax error error*//*		Treat One Character**		-------------------*/PRIVATE int WSRCParser_put_character (HTStream* me, char c){    switch (me->state) {    case beginning:        if (c=='(') me->state = before_tag;	break;	    case before_tag:        if (c==')') {	    me->state = done;	    return HT_OK;			/* Done with input file */	} else if (c==':') {	    me->param_count = 0;	    me->state = colon;	}				/* Ignore other text */	break;    case colon:        if (isspace((int) c)) {	    me->param[me->param_count++] = 0;	/* Terminate */	    for(me->param_number = 0; par_name[me->param_number]; me->param_number++) {		if (0==strcmp(par_name[me->param_number], me->param)) {		    break;		}	    }	    if (!par_name[me->param_number]) {	/* Unknown field */	        HTTRACE(PROT_TRACE, "HTWSRC: Unknown field `%s' in source file\n" _ 		    me->param);		me->param_number = PAR_UNKNOWN;		me->state = before_value;	/* Could be better ignore */		return HT_OK;	    }	    me->state = before_value;	} else {	    if (me->param_count < PARAM_MAX)  me->param[me->param_count++] = c;	}	break;	    case before_value:        if (c==')') {	    me->state = done;	    return HT_OK;			/* Done with input file */	}	if (isspace((int) c)) return HT_OK;		/* Skip white space */	me->param_count = 0;	if (c=='"') {	    me->state = quoted_value;	    break;	}	me->state = (c=='"') ? quoted_value : 		    (c=='(') ? bracketed_value : value;	me->param[me->param_count++] = c;	/* Don't miss first character */	break;    case value:        if (isspace((int) c)) {	    me->param[me->param_count] = 0;	    StrAllocCopy(me->par_value[me->param_number], me->param);	    me->state = before_tag;	} else {	    if (me->param_count < PARAM_MAX)  me->param[me->param_count++] = c;	}	break;    case bracketed_value:        if (c==')') {	    me->param[me->param_count] = 0;	    StrAllocCopy(me->par_value[me->param_number], me->param);	    me->state = before_tag;	    break;	}        if (me->param_count < PARAM_MAX)  me->param[me->param_count++] = c;	break;	    case quoted_value:        if (c=='"') {	    me->param[me->param_count] = 0;	    StrAllocCopy(me->par_value[me->param_number], me->param);	    me->state = before_tag;	    break;	}		if (c=='\\') {		/* Ignore escape but switch state */	    me->state = escape_in_quoted;	    break;	}	/* Fall through! */    case escape_in_quoted:        if (me->param_count < PARAM_MAX)  me->param[me->param_count++] = c;	break;	    case done:				/* Ignore anything after EOF */	return HT_OK;    } /* switch me->state */    return HT_OK;}/*			Open Cache file**			===============****   Bugs: Maybe for filesystem-challenged platforms (MSDOS for example) we**   should make a hash code for the filename.*/#ifdef CACHE_FILE_PREFIXPRIVATE BOOL write_cache (HTStream * me){    FILE * fp;    char cache_file_name[256];    char * www_database;    if (!me->par_value[PAR_DATABASE_NAME]    	|| !me->par_value[PAR_IP_NAME]	) return NO;        www_database = HTEscape(me->par_value[PAR_DATABASE_NAME], URL_XALPHAS);    sprintf(cache_file_name, "%sWSRC-%s:%s:%.100s.txt",    	CACHE_FILE_PREFIX,	me->par_value[PAR_IP_NAME],	me->par_value[PAR_TCP_PORT] ? me->par_value[PAR_TCP_PORT] : "210",	www_database);    HT_FREE(www_database);    fp = fopen(cache_file_name, "wb");    if (!fp) return NO;        if (me->par_value[PAR_DESCRIPTION])        fputs(me->par_value[PAR_DESCRIPTION], fp);    else         fputs("Description not available\n", fp);    fclose(fp);    return YES;}#endif/*			Output equivalent HTML**			----------------------***/void give_parameter (HTStream * me, int p){    PUTS(par_name[p]);    if (me->par_value[p]) {	PUTS(": ");	PUTS(me->par_value[p]);	PUTS("; ");    } else {        PUTS(" NOT GIVEN in source file; ");    }}/*			Generate Outout**			===============*/PRIVATE void WSRC_gen_html (HTStream * me, BOOL source_file){    if (me->par_value[PAR_DATABASE_NAME]) {	char * shortname = NULL;	int l;	StrAllocCopy(shortname, me->par_value[PAR_DATABASE_NAME]);	l = strlen(shortname);	if ( l > 4 && !strcasecomp(shortname + l -4, ".src")) {	    shortname[l-4] = 0;	/* Chop of .src -- boring! */	}		START(HTML_TITLE);	PUTS(shortname);	PUTS(source_file ? " WAIS source file" : " index");	END(HTML_TITLE);    	START(HTML_H1);	PUTS(shortname);	PUTS(source_file ? " description" : " index");	END(HTML_H1);	HT_FREE(shortname);				  /* memleak, henrik */    }        START(HTML_DL);		/* Definition list of details */        if (source_file) {	START(HTML_DT);	PUTS("Access link");	START(HTML_DD);	if (me->par_value[PAR_IP_NAME] &&	    me->par_value[PAR_DATABASE_NAME]) {	    char WSRC_address[256];	    char *addr = HTAnchor_address((HTAnchor*) me->request->anchor);	    char *gate = HTGateway_find(addr);	    char *www_database = HTEscape(me->par_value[PAR_DATABASE_NAME],					  URL_XALPHAS);	    if (!gate) {		sprintf(WSRC_address, "wais://%s%s%s/%s",			me->par_value[PAR_IP_NAME],			me->par_value[PAR_TCP_PORT] ? ":" : "",			me->par_value[PAR_TCP_PORT] ?			me->par_value[PAR_TCP_PORT] :"", www_database);		HTStartAnchor(me->target, NULL, WSRC_address);		PUTS("Direct access");		END(HTML_A);	    } else {		sprintf(WSRC_address, "%s%s%s%s/%s",			gate,			me->par_value[PAR_IP_NAME],			me->par_value[PAR_TCP_PORT] ? ":" : "",			me->par_value[PAR_TCP_PORT] ?			me->par_value[PAR_TCP_PORT] : "",			www_database);		HTStartAnchor(me->target, NULL, WSRC_address);		PUTS("Through a gateway");		END(HTML_A);	    }	    HT_FREE(gate);	    HT_FREE(addr);	    HT_FREE(www_database);	    	} else {	    give_parameter(me, PAR_IP_NAME);	    give_parameter(me, PAR_DATABASE_NAME);	}        } /* end if source_file */        if (me->par_value[PAR_MAINTAINER]) {	START(HTML_DT);	PUTS("Maintainer");	START(HTML_DD);	PUTS(me->par_value[PAR_MAINTAINER]);    }    if (me->par_value[PAR_IP_NAME]) {    	START(HTML_DT);    	PUTS("Host");    	START(HTML_DD);    	PUTS(me->par_value[PAR_IP_NAME]);    }        END(HTML_DL);    if (me->par_value[PAR_DESCRIPTION]) {	START(HTML_PRE);		/* Preformatted description */	PUTS(me->par_value[PAR_DESCRIPTION]);	END(HTML_PRE);    }        (*me->target->isa->_free)(me->target);        return;} /* generate html */PRIVATE int WSRCParser_put_string (HTStream * context, const char* s){    while (*s)        WSRCParser_put_character(context, *s++);    return HT_OK;}PRIVATE int WSRCParser_write (HTStream * 	context,				   const char* 	b,				   int		l){    while (l-- > 0)	WSRCParser_put_character(context, *b++);    return HT_OK;}PRIVATE int WSRCParser_flush (HTStream * me){    return HT_OK;}PRIVATE int WSRCParser_free (HTStream * me){    WSRC_gen_html(me, YES);#ifdef CACHE_FILE_PREFIX    write_cache(me);#endif    {	int p;	for(p=0; par_name[p]; p++) {	/* Clear out old values */	    if (me->par_value[p]) {		HT_FREE(me->par_value[p]);	    }	}    }    HT_FREE(me);    return HT_OK;}PRIVATE int WSRCParser_abort (HTStream * me, HTList * e){    WSRCParser_free(me);    return HT_ERROR;}/*		Stream subclass		-- method routines**		---------------*/HTStreamClass WSRCParserClass = {	"WSRCParser",	WSRCParser_flush,	WSRCParser_free,	WSRCParser_abort,	WSRCParser_put_character, 	WSRCParser_put_string,	WSRCParser_write};/*		Converter from WAIS Source to whatever**		--------------------------------------*/PUBLIC HTStream* HTWSRCConvert (HTRequest *	request,				void *		param,				HTFormat	input_format,				HTFormat	output_format,				HTStream *	output_stream){    HTStream * me;    if ((me = (HTStream  *) HT_CALLOC(1, sizeof(HTStream))) == NULL)        HT_OUTOFMEM("HTWSRCConvert");    me->isa = &WSRCParserClass;    me->target = HTMLGenerator(request, param, input_format, output_format,			       output_stream);    me->request = request;    me->state = beginning;    return me;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -