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

📄 htgopher.c

📁 elinks下lynx是最重要的二个文本浏览器, 在linux下非常实用, lynx比elinks早的多, 目前好像停止开发, 这是lynx源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    */    while ((ich=NEXT_CHAR) != EOF)	{	    if ((char)ich != LF)		{		    *p = (char) ich;    /* Put character in line */		    if (p< &line[BIG-1]) p++;		}	    else		{		    *p = '\0';		/* Terminate line */		    p = line;		/* Scan it to parse it */		    /*		    **	OK we now have a line in 'p'.		    **	Lets parse it and print it.		    */		    /*		    **	Break on line that begins with a 2.		    **	It's the end of data.		    */		    if (*p == '2')			break;		    /*		    **	Lines beginning with 5 are errors.		    **	Print them and quit.		    */		    if (*p == '5') {			START(HTML_H2);			PUTS(p+4);			END(HTML_H2);			break;		    }		    if (*p == '-') {			/*			**  Data lines look like  -200:#:			**  where # is the search result number and can be			**  multiple digits (infinite?).			**  Find the second colon and check the digit to the			**  left of it to see if they are diferent.			**  If they are then a different person is starting.			**  Make this line an <h2>.			*/			/*			**  Find the second_colon.			*/			second_colon = strchr( strchr(p,':')+1, ':');			if(second_colon != NULL) {  /* error check */			    if (*(second_colon-1) != last_char)				/* print seperator */			    {				END(HTML_PRE);				START(HTML_H2);			    }			    /*			    **	Right now the record appears with the alias			    **	(first line) as the header and the rest as			    **	<pre> text.			    **	It might look better with the name as the			    **	header and the rest as a <ul> with <li> tags.			    **	I'm not sure whether the name field comes in			    **	any special order or if its even required in			    **	a record, so for now the first line is the			    **	header no matter what it is (it's almost			    **	always the alias).			    **	A <dl> with the first line as the <DT> and			    **	the rest as some form of <DD> might good also?			    */			    /*			    **	Print data.			    */			    PUTS(second_colon+1);			    PUTC('\n');			    if (*(second_colon-1) != last_char)				/* end seperator */			    {				END(HTML_H2);				START(HTML_PRE);			    }			    /*			    **	Save the char before the second colon			    **	for comparison on the next pass.			    */			    last_char =  *(second_colon-1) ;			} /* end if second_colon */		    } /* end if *p == '-' */		} /* if end of line */	} /* Loop over characters */    /* end the text block */    PUTC('\n');    END(HTML_PRE);    PUTC('\n');    FREE_TARGET;    return;  /* all done */} /* end of procedure *//*	Display a Gopher CSO ISINDEX cover page.**	========================================*/PRIVATE void display_cso ARGS2(	CONST char *,		arg,	HTParentAnchor *,	anAnchor){    CONST char * title;    START(HTML_HEAD);    PUTC('\n');    START(HTML_TITLE);    if ((title = HTAnchor_title(anAnchor)))	PUTS(title);    else	PUTS(GOPHER_CSO_INDEX);    END(HTML_TITLE);    PUTC('\n');    START(HTML_ISINDEX);    PUTC('\n');    END(HTML_HEAD);    PUTC('\n');    START(HTML_H1);    if ((title = HTAnchor_title(anAnchor)))	PUTS(title);    else {       PUTS(arg);       PUTS(INDEX_SEGMENT);    }    END(HTML_H1);    PUTS(GOPHER_CSO_INDEX_SUBTITLE);    START(HTML_P);    PUTS(GOPHER_CSO_SOLICIT_KEYWORDS);    START(HTML_P);    PUTS(SEGMENT_KEYWORDS_WILL);    PUTS(SEGMENT_PERSONS_DB_NAME);    if (!HTAnchor_title(anAnchor))	HTAnchor_setTitle(anAnchor, arg);    FREE_TARGET;    return;}/*	Display a Gopher Index document.**	================================*/PRIVATE void display_index ARGS2(				  CONST char *, arg,				  HTParentAnchor *,anAnchor){    CONST char * title;    START(HTML_HEAD);    PUTC('\n');    PUTC('\n');    START(HTML_TITLE);    if ((title = HTAnchor_title(anAnchor)))	PUTS(title);    else	PUTS(GOPHER_INDEX_TITLE);    END(HTML_TITLE);    PUTC('\n');    START(HTML_ISINDEX);    PUTC('\n');    END(HTML_HEAD);    PUTC('\n');    START(HTML_H1);    if ((title = HTAnchor_title(anAnchor)))	PUTS(title);    else {       PUTS(arg);       PUTS(INDEX_SEGMENT);    }    END(HTML_H1);    PUTS(GOPHER_INDEX_SUBTITLE);    START(HTML_P);    PUTS(GOPHER_SOLICIT_KEYWORDS);    if (!HTAnchor_title(anAnchor))	HTAnchor_setTitle(anAnchor, arg);    FREE_TARGET;    return;}/*	De-escape a selector into a command.**	====================================****	The % hex escapes are converted. Otheriwse, the string is copied.*/PRIVATE void de_escape ARGS2(char *, command, CONST char *, selector){    CONST char * p = selector;    char * q = command;	if (command == NULL)	    outofmem(__FILE__, "HTLoadGopher");    while (*p) {		/* Decode hex */	if (*p == HEX_ESCAPE) {	    char c;	    unsigned int b;	    p++;	    c = *p++;	    b =   from_hex(c);	    c = *p++;	    if (!c) break;	/* Odd number of chars! */	    *q++ = (char) FROMASCII((b<<4) + from_hex(c));	} else {	    *q++ = *p++;	/* Record */	}    }    *q++ = '\0';	/* Terminate command */}/*	Free the CSOfields structures. - FM**	===================================*/PRIVATE void free_CSOfields NOPARAMS{    CSOfield_info *cur = CSOfields;    CSOfield_info *prev;    while (cur) {	if (cur->name != cur->name_buf)	    FREE(cur->name);	if (cur->attributes != cur->attr_buf)	    FREE(cur->attributes);	if (cur->description != cur->desc_buf)	    FREE(cur->description);	prev = cur;	cur = cur->next;	FREE(prev);    }    return;}/*	Interpret CSO/PH form template keys. - FM**	=========================================*/PRIVATE void interpret_cso_key ARGS5(	char *,			key,	char *,			buf,	int *,			length,	CSOformgen_context *,	ctx,	HTStream *,		Target){    CSOfield_info *fld;    if ((fld = ctx->fld) != 0) {	/*	**  Most substitutions only recognized inside of loops.	*/	int error = 0;	if (0 == strncmp(key, "$(FID)", 6)) {	    sprintf(buf, "%d", fld->id);	} else if (0 == strncmp(key, "$(FDESC)", 8)) {	    sprintf(buf, "%.2046s", fld->description);	} else if (0 == strncmp(key, "$(FDEF)", 7)) {	    strcpy(buf, fld->defreturn ? " checked" : "");	} else if (0 == strncmp(key, "$(FNDX)", 7)) {	    strcpy(buf, fld->indexed ? "*" : "");	} else if (0 == strncmp(key, "$(FSIZE)", 8)) {	    sprintf(buf, " size=%d maxlength=%d",		    fld->max_size > 55 ? 55 : fld->max_size,		    fld->max_size);	} else if (0 == strncmp(key, "$(FSIZE2)", 9)) {	    sprintf(buf, " maxlength=%d", fld->max_size);	} else {	    error = 1;	}	if (!error) {	    *length = strlen(buf);	    return;	}    }    buf[0] = '\0';    if (0 == strncmp(key, "$(NEXTFLD)", 10)) {	if (!ctx->fld)	    fld = CSOfields;	else	    fld = ctx->fld->next;	switch (ctx->field_select) {	  case 0:	    /*	    **	'Query' fields, public and lookup attributes.	    */	    for (; fld; fld = fld->next)		 if (fld->public && (fld->lookup==1))		     break;	    break;	  case 1:	    /*	    **	'Query' fields, accept lookup attribute.	    */	    for (; fld; fld = fld->next)		if (fld->lookup == 1)		    break;	    break;	  case 2:	    /*	    **	'Return' fields, public only.	    */	    for (; fld; fld = fld->next)		if (fld->public)		    break;	    break;	  case 3:	    /*	    **	All fields.	    */	    break;	}	if (fld) {	    ctx->cur_line = ctx->rep_line;	    ctx->cur_off = ctx->rep_off;	}	ctx->fld = fld;    } else if ((0 == strncmp(key, "$(QFIELDS)", 10)) ||	       (0 == strncmp(key, "$(RFIELDS)", 10))) {	/*	**  Begin iteration sequence.	*/	ctx->rep_line = ctx->cur_line;	ctx->rep_off = ctx->cur_off;	ctx->fld = (CSOfield_info *) 0;	ctx->seek = "$(NEXTFLD)";	ctx->field_select = (key[2] == 'Q') ? 0 : 2;	if (ctx->public_override)	    ctx->field_select++;    } else if (0 == strncmp(key, "$(NAMEFLD)", 10)) {	/*	**  Special, locate name field.  Flag lookup so QFIELDS will skip it.	*/	for (fld = CSOfields; fld; fld = fld->next)	    if (strcmp(fld->name, "name") == 0 ||		strcmp(fld->name, "Name") == 0) {		if (fld->lookup)		    fld->lookup = 2;		break;	    }	ctx->fld = fld;    } else if (0 == strncmp (key, "$(HOST)", 7)) {	strcpy (buf, ctx->host);    } else if (0 == strncmp (key, "$(PORT)", 7)) {	sprintf(buf, "%d", ctx->port);    } else {	/*	**  No match, dump key to buffer so client sees it for debugging.	*/	size_t out = 0;	while (*key && (*key != ')')) {	    buf[out++] = (*key++);	    if (out > sizeof(buf)-2) {		buf[out] = '\0';		(*Target->isa->put_block)(Target, buf, strlen(buf));		out = 0;	    }	}	buf[out++] = ')';	buf[out] = '\0';	*length = strlen(buf);	return;    }    *length = strlen(buf);    return;}/*	Parse the elements in a CSO/PH fields structure. - FM**	=====================================================*/PRIVATE int parse_cso_field_info ARGS1(	CSOfield_info *,	blk){    char *info, *max_spec;    /*    ** Initialize all fields to default values.    */    blk->indexed = blk->lookup = blk->reserved = blk->max_size = blk->url = 0;    blk->defreturn = blk->explicit_return = blk->public = 0;    /*    **	Search for keywords in info string and set values.  Attributes    **	are converted to all lower-case for comparison.    */    info = blk->attributes;    LYLowerCase(info);    if (strstr(info, "indexed "))	blk->indexed = 1;    if (strstr(info, "default "))	blk->defreturn = 1;    if (strstr(info, "public "))	blk->public = 1;    if (strstr(info, "lookup "))	blk->lookup = 1;    if (strstr(info, "url ")) {	blk->url = 1;	blk->defreturn = 1;    }    max_spec = strstr(info, "max ");    if (max_spec) {	sscanf(&max_spec[4], "%d", &blk->max_size);    } else {	blk->max_size = 32;    }    return 0;}/*	Parse a reply from a CSO/PH fields request. - FM**	================================================*/PRIVATE int parse_cso_fields ARGS2(	char *,		buf,	int,		size){    int ich;    char *p = buf;    int i, code = 0, prev_code;    size_t alen;    char *indx, *name;    CSOfield_info *last, *new;    last = CSOfields = (CSOfield_info *) 0;    prev_code = -2555;    buf[0] = '\0';    /*    **	Start grabbing chars from the network.    */    while ((ich = NEXT_CHAR) != EOF) {	if (interrupted_in_htgetcharacter) {	    CTRACE((tfp, "HTLoadCSO: Interrupted in HTGetCharacter, apparently.\n"));	    free_CSOfields();	    buf[0] = '\0';	    return HT_INTERRUPTED;	}	if ((char)ich != LF) {	    *p = (char) ich;    /* Put character in buffer */	    if (p < &buf[size-1]) {		p++;	    }	} else {	    *p = '\0';		/* Terminate line */	    p = buf;		/* Scan it to parse it */	    /* OK we now have a line in 'p' lets parse it.	     */	    /*	    **	Break on line that begins with a 2.	    **	It's the end of data.	    */	    if (*p == '2')		break;	    /*	    **	Lines beginning with 5 are errors.	    **	Print them and quit.	    */	    if (*p == '5') {		strcpy (buf, p);		return 5;	    }	    if (*p == '-') {		/*		**  Data lines look like  -200:#:		**  where # is the search result number and can be		**  multiple digits (infinite?).		*/

⌨️ 快捷键说明

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