/* Copyright (C) 1999 Beau Kuiper
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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "ftpd.h"
#define OUTBUFSIZE 1024
void control_timeout(int num)
{
signal(SIGALRM, control_timeout);
}
int ftp_write(FTPSTATE *peer, int bare, int messnum, char *fmt, ...)
{
int error, outlen, errornum, count;
va_list printfargs;
char number[10];
int logstartpos = STRLENGTH(peer->outbuffer);
/* Make the output string, and store it in the buffer */
if (!bare)
{
number[0] = messnum / 100 + '0';
number[1] = messnum % 100 / 10 + '0';
number[2] = messnum % 10 + '0';
number[3] = ' ';
string_cat(&(peer->outbuffer), number, 4);
}
va_start(printfargs, fmt);
outlen = vsnprintf(NULL, 0, fmt, printfargs);
va_end(printfargs);
va_start(printfargs, fmt);
string_catvprintf(&(peer->outbuffer), outlen, fmt, printfargs);
va_end(printfargs);
if (!bare)
log_addentry(MYLOG_RESPONSE, peer, STRTOCHAR(peer->outbuffer) + logstartpos);
/* add the end-of-line chars to the string */
string_cat(&(peer->outbuffer), "\r\n", 2);
outlen = STRLENGTH(peer->outbuffer);
/* dump the buffer if it is full enough or if end of response! */
error = 0; errornum = 0;
if ((!bare) || (outlen > BUFFERSIZE))
{
count = 0;
signal(SIGALRM, control_timeout);
/* make sure all data is written! */
while ((count < outlen) && (error != -1))
{
alarm(peer->timeout);
error = write(peer->remotefd, STRTOCHAR(peer->outbuffer) + count, outlen - count);
count += error;
}
string_clear(&(peer->outbuffer));
errornum = errno;
alarm(0);
}
if (error == -1)
{
log_giveentry(MYLOG_LOGIN, peer, safe_snprintf("Dropping connection, reason: %s", strerror(errornum)));
exit(0);
}
return(FALSE);
}
syntax highlighted by Code2HTML, v. 0.9.1