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

📄 htnews.c

📁 elinks下lynx是最重要的二个文本浏览器, 在linux下非常实用, lynx比elinks早的多, 目前好像停止开发, 这是lynx源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*			NEWS ACCESS				HTNews.c**			===========**** History:**	26 Sep 90	Written TBL**	29 Nov 91	Downgraded to C, for portable implementation.*/#include <HTUtils.h>		/* Coding convention macros */#ifndef DISABLE_NEWS/* Implements:*/#include <HTNews.h>#include <HTCJK.h>#include <HTMIME.h>#include <HTFont.h>#include <HTFormat.h>#include <HTTCP.h>#include <LYUtils.h>#include <LYStrings.h>#define NEWS_PORT 119		/* See rfc977 */#define SNEWS_PORT 563		/* See Lou Montulli */#define APPEND			/* Use append methods */PUBLIC int HTNewsChunkSize = 30;/* Number of articles for quick display */PUBLIC int HTNewsMaxChunk = 40; /* Largest number of articles in one window */#ifndef DEFAULT_NEWS_HOST#define DEFAULT_NEWS_HOST "news"#endif /* DEFAULT_NEWS_HOST */#ifndef SERVER_FILE#define SERVER_FILE "/usr/local/lib/rn/server"#endif /* SERVER_FILE */#ifdef USE_SSLextern SSL_CTX * ssl_ctx;PRIVATE SSL * Handle = NULL;PRIVATE int channel_s = 1;#define NEWS_NETWRITE(sock, buff, size) \	(Handle ? SSL_write(Handle, buff, size) : NETWRITE(sock, buff, size))#define NEWS_NETCLOSE(sock) \	{ (void)NETCLOSE(sock); if (Handle) SSL_free(Handle); Handle = NULL; }PRIVATE char HTNewsGetCharacter NOPARAMS;#define NEXT_CHAR HTNewsGetCharacter()#else#define NEWS_NETWRITE  NETWRITE#define NEWS_NETCLOSE  NETCLOSE#define NEXT_CHAR HTGetCharacter()#endif /* USE_SSL */#include <HTML.h>#include <HTAccess.h>#include <HTParse.h>#include <HTFormat.h>#include <HTAlert.h>#include <LYNews.h>#include <LYGlobalDefs.h>#include <LYLeaks.h>#define SnipIn(d,fmt,len,s)      sprintf(d, fmt,      (int)sizeof(d)-len, s)#define SnipIn2(d,fmt,tag,len,s) sprintf(d, fmt, tag, (int)sizeof(d)-len, s)struct _HTStructured {	CONST HTStructuredClass *	isa;	/* ... */};struct _HTStream{  HTStreamClass * isa;};#define LINE_LENGTH 512			/* Maximum length of line of ARTICLE etc */#define GROUP_NAME_LENGTH	256	/* Maximum length of group name *//***  Module-wide variables.*/PUBLIC	char * HTNewsHost = NULL;		/* Default host */PRIVATE char * NewsHost = NULL;			/* Current host */PRIVATE char * NewsHREF = NULL;			/* Current HREF prefix */PRIVATE int s;					/* Socket for NewsHost */PRIVATE int HTCanPost = FALSE;			/* Current POST permission */PRIVATE char response_text[LINE_LENGTH+1];	/* Last response *//* PRIVATE HText *	HT;	*/		/* the new hypertext */PRIVATE HTStructured * target;			/* The output sink */PRIVATE HTStructuredClass targetClass;		/* Copy of fn addresses */PRIVATE HTStream * rawtarget = NULL;		/* The output sink for rawtext */PRIVATE HTStreamClass rawtargetClass;		/* Copy of fn addresses */PRIVATE HTParentAnchor *node_anchor;		/* Its anchor */PRIVATE int	diagnostic;			/* level: 0=none 2=source */PRIVATE BOOL rawtext = NO;			/* Flag: HEAD or -mime_headers */PRIVATE HTList *NNTP_AuthInfo = NULL;		/* AUTHINFO database */PRIVATE char *name = NULL;PRIVATE char *address = NULL;PRIVATE char *dbuf = NULL;	/* dynamic buffer for long messages etc. */#define PUTC(c) (*targetClass.put_character)(target, c)#define PUTS(s) (*targetClass.put_string)(target, s)#define RAW_PUTS(s) (*rawtargetClass.put_string)(rawtarget, s)#define START(e) (*targetClass.start_element)(target, e, 0, 0, -1, 0)#define END(e) (*targetClass.end_element)(target, e, 0)#define MAYBE_END(e) if (HTML_dtd.tags[e].contents != SGML_EMPTY) \			(*targetClass.end_element)(target, e, 0)#define FREE_TARGET if (rawtext) (*rawtargetClass._free)(rawtarget); \			else (*targetClass._free)(target)#define ABORT_TARGET if (rawtext) (*rawtargetClass._abort)(rawtarget, NULL); \			else (*targetClass._abort)(target, NULL)typedef struct _NNTPAuth {   char * host;   char * user;   char * pass;} NNTPAuth;#ifdef LY_FIND_LEAKSPRIVATE void free_news_globals NOARGS{    if (s >= 0) {	NEWS_NETCLOSE(s);	s = -1;    }    FREE(HTNewsHost);    FREE(NewsHost);    FREE(NewsHREF);    FREE(name);    FREE(address);    FREE(dbuf);}#endif /* LY_FIND_LEAKS */PRIVATE void free_NNTP_AuthInfo NOARGS{    HTList *cur = NNTP_AuthInfo;    NNTPAuth *auth = NULL;    if (!cur)	return;    while (NULL != (auth = (NNTPAuth *)HTList_nextObject(cur))) {	FREE(auth->host);	FREE(auth->user);	FREE(auth->pass);	FREE(auth);    }    HTList_delete(NNTP_AuthInfo);    NNTP_AuthInfo = NULL;    return;}PUBLIC CONST char * HTGetNewsHost NOARGS{	return HTNewsHost;}PUBLIC void HTSetNewsHost ARGS1(CONST char *, value){	StrAllocCopy(HTNewsHost, value);}/*	Initialisation for this module**	------------------------------****	Except on the NeXT, we pick up the NewsHost name from****	1.	Environment variable NNTPSERVER**	2.	File SERVER_FILE**	3.	Compilation time macro DEFAULT_NEWS_HOST**	4.	Default to "news"****	On the NeXT, we pick up the NewsHost name from, in order:****	1.	WorldWideWeb default "NewsHost"**	2.	Global default "NewsHost"**	3.	News default "NewsHost"**	4.	Compilation time macro DEFAULT_NEWS_HOST**	5.	Default to "news"*/PRIVATE BOOL initialized = NO;PRIVATE BOOL initialize NOARGS{#ifdef NeXTStep    char *cp = NULL;#endif    /*    **	Get name of Host.    */#ifdef NeXTStep    if ((cp = NXGetDefaultValue("WorldWideWeb","NewsHost"))==0) {	if ((cp = NXGetDefaultValue("News","NewsHost")) == 0) {	    StrAllocCopy(HTNewsHost, DEFAULT_NEWS_HOST);	}    }    if (cp) {	StrAllocCopy(HTNewsHost, cp);	cp = NULL;    }#else    if (LYGetEnv("NNTPSERVER")) {	StrAllocCopy(HTNewsHost, LYGetEnv("NNTPSERVER"));	CTRACE((tfp, "HTNews: NNTPSERVER defined as `%s'\n",		    HTNewsHost));    } else {	FILE* fp = fopen(SERVER_FILE, TXT_R);	if (fp) {	    char server_name[MAXHOSTNAMELEN+1];	    if (fgets(server_name, sizeof server_name, fp) != NULL) {		char *p = strchr(server_name, '\n');		if (p != NULL)		    *p = '\0';		StrAllocCopy(HTNewsHost, server_name);		CTRACE((tfp, "HTNews: File %s defines news host as `%s'\n",			    SERVER_FILE, HTNewsHost));	    }	    fclose(fp);	}    }    if (!HTNewsHost)	StrAllocCopy(HTNewsHost, DEFAULT_NEWS_HOST);#endif /* NeXTStep */    s = -1;		/* Disconnected */#ifdef LY_FIND_LEAKS    atexit(free_news_globals);#endif    return YES;}/*	Send NNTP Command line to remote host & Check Response**	------------------------------------------------------**** On entry,**	command points to the command to be sent, including CRLF, or is null**		pointer if no command to be sent.** On exit,**	Negative status indicates transmission error, socket closed.**	Positive status is an NNTP status.*/PRIVATE int response ARGS1(char *,command){    int result;    char * p = response_text;    int ich;    if (command) {	int status;	int length = strlen(command);	CTRACE((tfp, "NNTP command to be sent: %s", command));#ifdef NOT_ASCII	{	    CONST char	* p;	    char	* q;	    char ascii[LINE_LENGTH+1];	    for(p = command, q=ascii; *p; p++, q++) {		*q = TOASCII(*p);	    }	    status = NEWS_NETWRITE(s, ascii, length);	}#else	status = NEWS_NETWRITE(s, (char *)command, length);#endif /* NOT_ASCII */	if (status < 0){	    CTRACE((tfp, "HTNews: Unable to send command. Disconnecting.\n"));	    NEWS_NETCLOSE(s);	    s = -1;	    return status;	} /* if bad status */    } /* if command to be sent */    for (;;) {	ich = NEXT_CHAR;	if (((*p++ = (char) ich) == LF) ||	    (p == &response_text[LINE_LENGTH])) {	    *--p = '\0';			/* Terminate the string */	    CTRACE((tfp, "NNTP Response: %s\n", response_text));	    sscanf(response_text, "%d", &result);	    return result;	} /* if end of line */	if (ich == EOF) {	    *(p-1) = '\0';	    if (interrupted_in_htgetcharacter) {		CTRACE((tfp, "HTNews: Interrupted on read, closing socket %d\n",			    s));	    } else {		CTRACE((tfp, "HTNews: EOF on read, closing socket %d\n",			    s));	    }	    NEWS_NETCLOSE(s);	/* End of file, close socket */	    s = -1;	    if (interrupted_in_htgetcharacter) {		interrupted_in_htgetcharacter = 0;		return(HT_INTERRUPTED);	    }	    return((int)EOF);	/* End of file on response */	}    } /* Loop over characters */}/*	Case insensitive string comparisons**	-----------------------------------**** On entry,**	template must be already un upper case.**	unknown may be in upper or lower or mixed case to match.*/PRIVATE BOOL match ARGS2 (CONST char *,unknown, CONST char *,template){    CONST char * u = unknown;    CONST char * t = template;    for (; *u && *t && (TOUPPER(*u) == *t); u++, t++)	; /* Find mismatch or end */    return (BOOL)(*t == 0);		/* OK if end of template */}typedef enum {    NNTPAUTH_ERROR =	  0,	/* general failure */    NNTPAUTH_OK =	281,	/* authenticated successfully */    NNTPAUTH_CLOSE =	502	/* server probably closed connection */} NNTPAuthResult;/***  This function handles nntp authentication. - FM*/PRIVATE NNTPAuthResult HTHandleAuthInfo ARGS1(	char *,		host){    HTList *cur = NULL;    NNTPAuth *auth = NULL;    char *UserName = NULL;    char *PassWord = NULL;    char *msg = NULL;    char buffer[512];    int status, tries;    /*    **	Make sure we have an interactive user and a host. - FM    */    if (dump_output_immediately || !(host && *host))	return NNTPAUTH_ERROR;    /*    **	Check for an existing authorization entry. - FM    */    if (NNTP_AuthInfo != NULL) {	cur = NNTP_AuthInfo;	while (NULL != (auth = (NNTPAuth *)HTList_nextObject(cur))) {	    if (!strcmp(auth->host, host)) {		UserName = auth->user;		PassWord = auth->pass;		break;	    }	}    } else {	NNTP_AuthInfo = HTList_new();#ifdef LY_FIND_LEAKS	atexit(free_NNTP_AuthInfo);#endif    }    /*    **	Handle the username. - FM    */    buffer[sizeof(buffer)-1] = '\0';    tries = 3;    while (tries) {	if (UserName == NULL) {	    HTSprintf0(&msg, gettext("Username for news host '%s':"), host);	    UserName = HTPrompt(msg, NULL);	    FREE(msg);	    if (!(UserName && *UserName)) {		FREE(UserName);		return NNTPAUTH_ERROR;	    }	}	sprintf(buffer, "AUTHINFO USER %.*s%c%c",		(int) sizeof(buffer)-17, UserName, CR, LF);	if ((status = response(buffer)) < 0) {	    if (status == HT_INTERRUPTED)		_HTProgress(CONNECTION_INTERRUPTED);	    else		HTAlert(FAILED_CONNECTION_CLOSED);	    if (auth) {		if (auth->user != UserName) {		    FREE(auth->user);		    auth->user = UserName;		}	    } else {		FREE(UserName);	    }	    return NNTPAUTH_CLOSE;	}	if (status == 281) {	    /*	    **  Username is accepted and no password is required. - FM	    */	    if (auth) {		if (auth->user != UserName) {		    FREE(auth->user);		    auth->user = UserName;		}	    } else {		/*		**  Store the accepted username and no password. - FM		*/		if ((auth = typecalloc(NNTPAuth)) != NULL) {		    StrAllocCopy(auth->host, host);		    auth->user = UserName;		    HTList_appendObject(NNTP_AuthInfo, auth);		}	    }	    return NNTPAUTH_OK;	}	if (status != 381) {	    /*	    **  Not success, nor a request for the password,	    **  so it must be an error. - FM	    */	    HTAlert(response_text);	    tries--;	    if ((tries > 0) && HTConfirm(gettext("Change username?"))) {		if (!auth || auth->user != UserName) {		    FREE(UserName);		}		if ((UserName = HTPrompt(gettext("Username:"), UserName)) != NULL &&		    *UserName) {		    continue;		}	    }	    if (auth) {		if (auth->user != UserName) {		    FREE(auth->user);		}		FREE(auth->pass);	    }	    FREE(UserName);	    return NNTPAUTH_ERROR;	}	break;    }    if (status == 381) {	/*	**  Handle the password. - FM	*/	tries = 3;	while (tries) {	    if (PassWord == NULL) {		HTSprintf0(&msg, gettext("Password for news host '%s':"), host);		PassWord = HTPromptPassword(msg);		FREE(msg);		if (!(PassWord && *PassWord)) {		    FREE(PassWord);		    return NNTPAUTH_ERROR;		}	    }	    sprintf(buffer, "AUTHINFO PASS %.*s%c%c",		    (int) sizeof(buffer)-17, PassWord, CR, LF);	    if ((status = response(buffer)) < 0) {		if (status == HT_INTERRUPTED) {		    _HTProgress(CONNECTION_INTERRUPTED);		} else {		    HTAlert(FAILED_CONNECTION_CLOSED);		}		if (auth) {		    if (auth->user != UserName) {			FREE(auth->user);			auth->user = UserName;		    }		    if (auth->pass != PassWord) {			FREE(auth->pass);			auth->pass = PassWord;		    }		} else {		    FREE(UserName);		    FREE(PassWord);		}		return NNTPAUTH_CLOSE;	    }	    if (status == 502) {		/*		 *  That's what INN's nnrpd returns.		 *  It closes the connection after this. - kw		 */		HTAlert(response_text);		if (auth) {		    if (auth->user == UserName)			UserName = NULL;		    FREE(auth->user);		    if (auth->pass == PassWord)			PassWord = NULL;		    FREE(auth->pass);		}		FREE(UserName);		FREE(PassWord);		return NNTPAUTH_CLOSE;	    }	    if (status == 281) {	    /*	    **	Password also is accepted, and everything	    **	has been stored. - FM	    */		if (auth) {		    if (auth->user != UserName) {			FREE(auth->user);			auth->user = UserName;		    }

⌨️ 快捷键说明

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