/*
**  Copyright 2000-2004 University of Illinois Board of Trustees
**  Copyright 2000-2004 Mark D. Roth
**  All rights reserved.
**
**  protocol.c - FTP protocol communication code
**
**  Mark D. Roth <roth@feep.net>
*/

#include <internal.h>

#include <stdio.h>
#include <errno.h>

#ifdef STDC_HEADERS
# include <stdlib.h>
# include <string.h>
# include <stdarg.h>
#endif

#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif


/* _ftp_get_response() - read and parse a response from the server. */
int
_ftp_get_response(FTP *ftp, int *code, char *buf, size_t bufsize)
{
	char *linep;
	int done = 0;
	char linebuf[FTPBUFSIZE];

#ifdef DEBUG
	printf("==> _ftp_get_response(ftp=(%s), code=0x%lx, buf=0x%lx, "
	       "bufsize=%lu\n", ftp->ftp_host, code, buf,
	       (unsigned long)bufsize);
#endif

	if (buf != NULL)
		buf[0] = '\0';

	do
	{
		switch (fget_netio_read_line(ftp->ftp_control,
					     ftp->ftp_io_timeout,
					     linebuf,
					     sizeof(linebuf)))
		{
		case 0:
			errno = ECONNRESET;
			/* FALLTHROUGH */
		case -1:
#ifdef DEBUG
			printf("<== _ftp_get_response(): returning -1 "
			       "(errno = %d)\n", errno);
#endif
			return -1;
		default:
			break;
		}

#ifdef DEBUG
		printf("    _ftp_get_response(): linebuf=\"%s\"\n", linebuf);
#endif

		/* extract response code */
		if (strpbrk(linebuf, "0123456789") == linebuf)
		{
			*code = (int)strtoul(linebuf, &linep, 10);
			if (*linep == ' ')
				done = 1;
			linep++;
		}
		else
			linep = linebuf;

#ifdef DEBUG
		printf("    _ftp_get_response(): linep=\"%s\"\n", linep);
#endif

		/* copy line to caller-supplied buffer */
		if (buf != NULL)
		{
			strlcat(buf, linep, bufsize);
			strlcat(buf, "\n", bufsize);
		}
	}
	while (!done);

#ifdef DEBUG
	printf("<== _ftp_get_response(): success\n");
#endif
	return 0;
}


/* _ftp_send_command() - send a command to the server */
int
_ftp_send_command(FTP *ftp, char *fmt, ...)
{
	va_list args;
	int retval;

	va_start(args, fmt);
	retval = _vftp_send_command(ftp, fmt, args);
	va_end(args);

	return retval;
}


/* variable-argument interface for _ftp_send_command() */
int
_vftp_send_command(FTP *ftp, char *fmt, va_list args)
{
	if (ftp->ftp_data != NULL)
	{
		errno = EAGAIN;
		return -1;
	}

	return fget_netio_vwrite_line(ftp->ftp_control,
				      ftp->ftp_io_timeout, fmt, args);
}




syntax highlighted by Code2HTML, v. 0.9.1