/**************************************************************************************************
	$Header: /pub/cvsroot/yencode/src/ypost/nntp.c,v 1.1 2002/03/15 15:10:49 bboy Exp $

	Copyright (C) 2002  Don Moore <bboy@bboy.net>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at Your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
**************************************************************************************************/

#include "ypost.h"

int	nntp_fd = -1;												/* Connection to NNTP server */


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	NNTP_GET_REPLY_NUM
	Extracts the numeric reply value from a reply.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
inline int
nntp_get_reply_num(const char *reply)
{
	char num[4];

	if (!isdigit(reply[0]) || !isdigit(reply[1]) || !isdigit(reply[2]))
      return (0);
	num[0] = reply[0]; num[1] = reply[1]; num[2] = reply[2]; num[3] = '\0';
	return (atoi(num));
}
/*--- nntp_get_reply_num() ----------------------------------------------------------------------*/


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	_NNTPTRANS
	Sends the NNTP command provided in varargs.  If an error is returned, it is fatal.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
static unsigned char *
_nntptrans(const unsigned char *cmd, size_t len, int *rnum)
{
	unsigned char *outbuf;
	register unsigned char *i, *o;
	unsigned char *reply;
	int		replynum;

	if (_sock_current_fd == -1)
		Err(_("unable to write; not connected to remote server"));

	/* Remove CR, convert LF to CRLF */
	outbuf = (unsigned char *)xmalloc(((len * 2) + 1) * sizeof(unsigned char));
	for (i = (unsigned char *)cmd, o = outbuf; *i; i++)
	{
		if (*i == CR)
			continue;
		else if (*i == LF)
		{
			*(o++) = CR;
			*(o++) = LF;
		}
		else
			*(o++) = *i;
	}
	*o = '\0';
	sock_puts_fd(_sock_current_fd, outbuf);
	free(outbuf);

	if (!(reply = sock_gets()))
		Err(_("server did not reply to our command"));

	if (!(replynum = nntp_get_reply_num(reply)))
      Err("%s", reply);
   if (STATUS_ERR(replynum))
      Err("%s: `%s'", _("error indicated by server"), reply+4);
	if (rnum)
		*rnum = replynum;

	return (reply);
}
/*--- _nntptrans() ------------------------------------------------------------------------------*/


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	NNTPTRANS
	Sends the command in `fmt', returns the reply (which needs to be freed).
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
unsigned char *
nntptrans(const char *fmt, ...)
{
	va_list  ap;
	size_t   len;
	unsigned char buf[BUFSIZ];
	int		replynum;

	va_start(ap, fmt);
	len = vsnprintf(buf, sizeof(buf)-4, fmt, ap);
	va_end(ap);

	return (_nntptrans(buf, len, &replynum));
}
/*--- nntptrans() -------------------------------------------------------------------------------*/


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	NNTPTRANSX
	Sends the command in `fmt', discards (and frees) the reply.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void
nntptransx(const char *fmt, ...)
{
	va_list  ap;
	size_t   len;
	unsigned char buf[BUFSIZ], *reply;
	int		replynum;

	va_start(ap, fmt);
	len = vsnprintf(buf, sizeof(buf)-4, fmt, ap);
	va_end(ap);

	reply = _nntptrans(buf, len, &replynum);
	free(reply);
}
/*--- nntptransx() ------------------------------------------------------------------------------*/


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	NNTP_CONNECT
	Establishes connection with the NNTP server.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void
nntp_connect(void)
{
	struct sockaddr_in *sa;										/* Address for remote server */
	unsigned char *greeting;

	if (opt_stdout)												/* Never connect if output is to stdout */
		return;
	if (nntp_fd != -1)											/* Already connected? */
		return;
	if (!opt_nntp_server)
		Err(_("no news server specified"));

	sa = sock_getsockaddr(opt_nntp_server);
	nntp_fd = sock_open(sa);
	sock_setfd(nntp_fd);											/* Set connection as default for sock_ funcs */

	Debug(_("connected to %s (%s), port %u"),
			opt_nntp_server, inet_ntoa(sa->sin_addr), ntohs(sa->sin_port));

	/* Read server's greeting */
	greeting = sock_gets();
	free(greeting);

	/* Log in if necessary */
	if (opt_auth_user)
		nntptransx("AUTHINFO USER %s\n", opt_auth_user);
	if (opt_prompt_pass)
	{
		char	prompt[512];
		snprintf(prompt, sizeof(prompt), "Password for %s: ", opt_auth_user ? opt_auth_user : opt_nntp_server);
		opt_auth_pass = passinput(prompt);
		opt_prompt_pass = 0;
	}
	if (opt_auth_pass)
		nntptransx("AUTHINFO PASS %s\n", opt_auth_pass);
}
/*--- nntp_connect() ----------------------------------------------------------------------------*/


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	NNTP_DISCONNECT
	Disconnects from the NNTP server.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void
nntp_disconnect(void)
{
	if (opt_stdout)
		return;
	close(nntp_fd);
	nntp_fd = -1;
}
/*--- nntp_disconnect() -------------------------------------------------------------------------*/

/* vi:set ts=3: */


syntax highlighted by Code2HTML, v. 0.9.1