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

📄 clientlib.c

📁 UUDeview是一个编码解码器
💻 C
字号:
#ifndef lintstatic char	*sccsid = "@(#)clientlib.c	1.11	(Berkeley) 10/27/89";#endif/* * NNTP client routines. *//* * Include configuration parameters only if we're made in the nntp tree. */#ifdef HAVE_CONFIG_H#include "../config.h"#endif#include <stdio.h>#ifndef FOR_NN#include <sys/types.h>#endif#include <sys/socket.h>#ifdef FOR_NN#if !defined(NETWORK_DATABASE) || defined(NETWORK_BYTE_ORDER)#include <netinet/in.h>#endif#else#include <netinet/in.h>#endif#ifndef EXCELAN# include <netdb.h>#endif/* * __FP__ includes */#ifdef STDC_HEADERS#include <stdlib.h>#include <string.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef EXCELAN# define	IPPORT_NNTP	119#endif#ifdef DECNET#include <netdnet/dn.h>#include <netdnet/dnetdb.h>#endif#include "nntp.h"FILE	*ser_rd_fp = NULL;FILE	*ser_wr_fp = NULL;/* * getserverbyfile	Get the name of a server from a named file. *			Handle white space and comments. *			Use NNTPSERVER environment variable if set. * *	Parameters:	"file" is the name of the file to read. * *	Returns:	Pointer to static data area containing the *			first non-ws/comment line in the file. *			NULL on error (or lack of entry in file). * *	Side effects:	None. */char *getserverbyfile(file)char	*file;{	register FILE	*fp;	register char	*cp;	static char	buf[256];	if (cp = getenv("NNTPSERVER")) {		(void) strcpy(buf, cp);		return (buf);	}	if (cp = getenv("NNTP_SERVER")) {	  (void) strcpy (buf, cp);	  return (buf);	}	/*	 * may define NNTPSERVER at compile time __FP__	 */#ifdef NNTPSERVER        if (NNTPSERVER[0]) {          (void) strcpy (buf, NNTPSERVER);          return buf;        }#endif	if (file == NULL)		return (NULL);	fp = fopen(file, "r");	if (fp == NULL)		return (NULL);	while (fgets(buf, sizeof (buf), fp) != NULL) {		if (*buf == '\n' || *buf == '#')			continue;		cp = strchr(buf, '\n');		if (cp)			*cp = '\0';		(void) fclose(fp);		return (buf);	}	(void) fclose(fp);	return (NULL);			 /* No entry */}/* * server_init  Get a connection to the remote news server. * *	Parameters:	"machine" is the machine to connect to. * *	Returns:	-1 on error *			server's initial response code on success. * *	Side effects:	Connects to server. *			"ser_rd_fp" and "ser_wr_fp" are fp's *			for reading and writing to server. */server_init(machine)char	*machine;{	int	sockt_rd, sockt_wr;	char	line[256];#ifdef DECNET	char	*cp;	cp = strchr(machine, ':');	if (cp && cp[1] == ':') {		*cp = '\0';		sockt_rd = get_dnet_socket(machine);	} else		sockt_rd = get_tcp_socket(machine);#else	sockt_rd = get_tcp_socket(machine);#endif	if (sockt_rd < 0)		return (-1);	/*	 * Now we'll make file pointers (i.e., buffered I/O) out of	 * the socket file descriptor.  Note that we can't just	 * open a fp for reading and writing -- we have to open	 * up two separate fp's, one for reading, one for writing.	 */	if ((ser_rd_fp = fdopen(sockt_rd, "r")) == NULL) {		perror("server_init: fdopen #1");		return (-1);	}	sockt_wr = dup(sockt_rd);	if ((ser_wr_fp = fdopen(sockt_wr, "w")) == NULL) {		perror("server_init: fdopen #2");		ser_rd_fp = NULL;		/* from above */		return (-1);	}	/* Now get the server's signon message */	(void) get_server(line, sizeof(line));	return (atoi(line));}/* * get_tcp_socket -- get us a socket connected to the news server. * *	Parameters:	"machine" is the machine the server is running on. * *	Returns:	Socket connected to the news server if *			all is ok, else -1 on error. * *	Side effects:	Connects to server. * *	Errors:		Printed via perror. */get_tcp_socket(machine)char	*machine;{	int	s;	struct	sockaddr_in sin;#ifndef EXCELAN	struct	servent *getservbyname(), *sp;	struct	hostent *gethostbyname(), *hp;#ifdef h_addr	int	x = 0;	register char **cp;#endif	if ((sp = getservbyname("nntp", "tcp")) ==  NULL) {		fprintf(stderr, "nntp/tcp: Unknown service.\n");		return (-1);	}       /*        * Name resolution doesn't quite go as far as it should.  Take things        * one stage further to allow nnn.nnn.nnn.nnn addresses if all else        * fails.        */       if( (hp = gethostbyname( machine ) ) == NULL ) {               unsigned long inet_addr();               static struct hostent def;               static struct in_addr defaddr;               static char *alist[1];               static char namebuf[ 256 ];               defaddr.s_addr = inet_addr( machine );               if( defaddr.s_addr != -1 ) {                       strcpy( namebuf, machine );                       def.h_name = namebuf;#ifdef h_addr                       def.h_addr_list = alist;#endif                       def.h_addr = (char *)&defaddr;                       def.h_length = sizeof( struct in_addr );                       def.h_addrtype = AF_INET;                       def.h_aliases = 0;                       hp = &def;               }       }       if (hp == NULL) {		fprintf(stderr, "%s: Unknown host.\n", machine);		return (-1);	}	memset (&sin, '\0', sizeof(sin));	sin.sin_family = hp->h_addrtype;	sin.sin_port = sp->s_port;#else	memset (&sin, '\0', sizeof(sin));	sin.sin_family = AF_INET;	sin.sin_port = htons(IPPORT_NNTP);#endif	/*	 * The following is kinda gross.  The name server under 4.3	 * returns a list of addresses, each of which should be tried	 * in turn if the previous one fails.  However, 4.2 hostent	 * structure doesn't have this list of addresses.	 * Under 4.3, h_addr is a #define to h_addr_list[0].	 * We use this to figure out whether to include the NS specific	 * code...	 */#ifdef	h_addr	/* get a socket and initiate connection -- use multiple addresses */	for (cp = hp->h_addr_list; cp && *cp; cp++) {		s = socket(hp->h_addrtype, SOCK_STREAM, 0);		if (s < 0) {			perror("socket");			return (-1);		}		memcpy ((char *)&sin.sin_addr, *cp, hp->h_length);/*	        bcopy(*cp, (char *)&sin.sin_addr, hp->h_length);*/		if (x < 0)			fprintf(stderr, "trying %s\n", inet_ntoa(sin.sin_addr));		x = connect(s, (struct sockaddr *)&sin, sizeof (sin));		if (x == 0)			break;                fprintf(stderr, "connection to %s: ", inet_ntoa(sin.sin_addr));		perror("");		(void) close(s);	}	if (x < 0) {		fprintf(stderr, "giving up...\n");		return (-1);	}#else	/* no name server */#ifdef EXCELAN	if ((s = rresvport(SO_KEEPALIVE)) < 0)	{		/* Get the socket */		perror("socket");		return (-1);	}	/* set up addr for the connect */	sin.sin_addr.s_addr = rhost(machine);	if (sin.sin_addr.s_addr < 0){		fprintf(stderr, "%s: Unknown host.\n", machine);		return (-1);	}	/* And then connect */	if (connect(s, &sin) < 0) {		perror("connect");		(void) close(s);		return (-1);	}#else	if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {		perror("socket");		return (-1);	}	/* And then connect *//*	bcopy(hp->h_addr, (char *) &sin.sin_addr, hp->h_length);*/	memcpy ((char *)&sin.sin_addr, hp->h_addr, hp->h_length);	if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {		perror("connect");		(void) close(s);		return (-1);	}#endif#endif	return (s);}#ifdef DECNET/* * get_dnet_socket -- get us a socket connected to the news server. * *	Parameters:	"machine" is the machine the server is running on. * *	Returns:	Socket connected to the news server if *			all is ok, else -1 on error. * *	Side effects:	Connects to server. * *	Errors:		Printed via nerror. */get_dnet_socket(machine)char	*machine;{	int	s, area, node;	struct	sockaddr_dn sdn;	struct	nodeent *getnodebyname(), *np;	memset (&sdn, '\0', sizeof(sdn));	switch (s = sscanf( machine, "%d%*[.]%d", &area, &node )) {		case 1:			node = area;			area = 0;		case 2:			node += area*1024;			sdn.sdn_add.a_len = 2;			sdn.sdn_family = AF_DECnet;			sdn.sdn_add.a_addr[0] = node % 256;			sdn.sdn_add.a_addr[1] = node / 256;			break;		default:			if ((np = getnodebyname(machine)) == NULL) {				fprintf(stderr,					"%s: Unknown host.\n", machine);				return (-1);			} else {			  /*			     bcopy(np->n_addr,			     (char *) sdn.sdn_add.a_addr,			     np->n_length);			     */			  memcpy ((char *) sdn.sdn_add.a_addr,				  np->n_addr,				  np->n_length);			  sdn.sdn_add.a_len = np->n_length;			  sdn.sdn_family = np->n_addrtype;			}			break;	}	sdn.sdn_objnum = 0;	sdn.sdn_flags = 0;	sdn.sdn_objnamel = strlen("NNTP");/*	bcopy("NNTP", &sdn.sdn_objname[0], sdn.sdn_objnamel); */	memcpy (&sdn.sdn_objname[0], "NNTP", sdn.sdn_objnamel);	if ((s = socket(AF_DECnet, SOCK_STREAM, 0)) < 0) {		nerror("socket");		return (-1);	}	/* And then connect */	if (connect(s, (struct sockaddr *) &sdn, sizeof(sdn)) < 0) {		nerror("connect");		close(s);		return (-1);	}	return (s);}#endif/* * handle_server_response * *	Print some informative messages based on the server's initial *	response code.  This is here so inews, rn, etc. can share *	the code. * *	Parameters:	"response" is the response code which the *			server sent us, presumably from "server_init", *			above. *			"server" is the news server we got the *			response code from. * *	Returns:	-1 if the error is fatal (and we should exit). *			0 otherwise. * *	Side effects:	None. */handle_server_response(response, server)int	response;char	*server;{    switch (response) {	case OK_NOPOST:		/* fall through */    		printf(	"NOTE: This machine does not have permission to post articles.\n");		printf(	"      Please don't waste your time trying.\n\n");	case OK_CANPOST:		return (0);		break;	case ERR_ACCESS:		printf(   "This machine does not have permission to use the %s news server.\n",		server);		return (-1);		break;	default:		printf("Unexpected response code from %s news server: %d\n",			server, response);		return (-1);		break;    }	/*NOTREACHED*/}/* * put_server -- send a line of text to the server, terminating it * with CR and LF, as per ARPA standard. * *	Parameters:	"string" is the string to be sent to the *			server. * *	Returns:	Nothing. * *	Side effects:	Talks to the server. * *	Note:		This routine flushes the buffer each time *			it is called.  For large transmissions *			(i.e., posting news) don't use it.  Instead, *			do the fprintf's yourself, and then a final *			fflush. */voidput_server(string)char *string;{#ifdef DEBUG	fprintf(stderr, ">>> %s\n", string);#endif	fprintf(ser_wr_fp, "%s\r\n", string);	(void) fflush(ser_wr_fp);}/* * get_server -- get a line of text from the server.  Strips * CR's and LF's. * *	Parameters:	"string" has the buffer space for the *			line received. *			"size" is the size of the buffer. * *	Returns:	-1 on error, 0 otherwise. * *	Side effects:	Talks to server, changes contents of "string". */get_server(string, size)char	*string;int	size;{	register char *cp;	if (fgets(string, size, ser_rd_fp) == NULL)		return (-1);	if ((cp = strchr(string, '\r')) != NULL)		*cp = '\0';	else if ((cp = strchr(string, '\n')) != NULL)		*cp = '\0';#ifdef DEBUG	fprintf(stderr, "<<< %s\n", string);#endif	return (0);}/* * close_server -- close the connection to the server, after sending *		the "quit" command. * *	Parameters:	None. * *	Returns:	Nothing. * *	Side effects:	Closes the connection with the server. *			You can't use "put_server" or "get_server" *			after this routine is called. */voidclose_server(){	char	ser_line[256];	if (ser_wr_fp == NULL || ser_rd_fp == NULL)		return;	put_server("QUIT");	(void) get_server(ser_line, sizeof(ser_line));	(void) fclose(ser_wr_fp);	(void) fclose(ser_rd_fp);}

⌨️ 快捷键说明

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