/* 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); }