/*
- * $Id: ftp.cc,v 1.432 2007/08/09 23:30:52 rousskov Exp $
+ * $Id: ftp.cc,v 1.433 2007/08/12 23:57:28 amosjeffries Exp $
*
* DEBUG: section 9 File Transfer Protocol (FTP)
* AUTHOR: Harvest Derived
static void
ftpSendUser(FtpStateData * ftpState)
{
+ /* check the server control channel is still available */
+ if(!haveControlChannel("ftpSendUser"))
+ return;
+
if (ftpState->proxy_host != NULL)
snprintf(cbuf, 1024, "USER %s@%s\r\n",
ftpState->user,
static void
ftpSendPass(FtpStateData * ftpState)
{
+ /* check the server control channel is still available */
+ if(!haveControlChannel("ftpSendPass"))
+ return;
+
snprintf(cbuf, 1024, "PASS %s\r\n", ftpState->password);
ftpState->writeCommand(cbuf);
ftpState->state = SENT_PASS;
const char *t;
const char *filename;
char mode;
+
+ /* check the server control channel is still available */
+ if(!haveControlChannel("ftpSendType"))
+ return;
+
/*
* Ref section 3.2.2 of RFC 1738
*/
ftpSendCwd(FtpStateData * ftpState)
{
char *path = ftpState->filepath;
+
+ /* check the server control channel is still available */
+ if(!haveControlChannel("ftpSendCwd"))
+ return;
+
debugs(9, 3, "ftpSendCwd");
if (!strcmp(path, "..") || !strcmp(path, "/")) {
ftpSendMkdir(FtpStateData * ftpState)
{
char *path = ftpState->filepath;
+
+ /* check the server control channel is still available */
+ if(!haveControlChannel("ftpSendMkdir"))
+ return;
+
debugs(9, 3, "ftpSendMkdir: with path=" << path);
snprintf(cbuf, 1024, "MKD %s\r\n", path);
ftpState->writeCommand(cbuf);
static void
ftpSendMdtm(FtpStateData * ftpState)
{
+ /* check the server control channel is still available */
+ if(!haveControlChannel("ftpSendMdtm"))
+ return;
+
assert(*ftpState->filepath != '\0');
snprintf(cbuf, 1024, "MDTM %s\r\n", ftpState->filepath);
ftpState->writeCommand(cbuf);
static void
ftpSendSize(FtpStateData * ftpState)
{
+ /* check the server control channel is still available */
+ if(!haveControlChannel("ftpSendPasv"))
+ return;
+
/* Only send SIZE for binary transfers. The returned size
* is useless on ASCII transfers */
static void
ftpSendPasv(FtpStateData * ftpState)
{
-
struct sockaddr_in addr;
socklen_t addr_len;
+ /* check the server control channel is still available */
+ if(!haveControlChannel("ftpSendPasv"))
+ return;
+
debugs(9, 3, HERE << "ftpSendPasv started");
if (ftpState->request->method == METHOD_HEAD && (ftpState->flags.isdir || ftpState->size != -1)) {
socklen_t addr_len;
unsigned char *addrptr;
unsigned char *portptr;
+
+ /* check the server control channel is still available */
+ if(!haveControlChannel("ftpSendPort"))
+ return;
+
debugs(9, 3, "This is ftpSendPort");
ftpState->flags.pasv_supported = 0;
fd = ftpOpenListenSocket(ftpState, 0);
static void
ftpSendStor(FtpStateData * ftpState)
{
+ /* check the server control channel is still available */
+ if(!haveControlChannel("ftpSendStor"))
+ return;
+
if (ftpState->filepath != NULL) {
/* Plain file upload */
snprintf(cbuf, 1024, "STOR %s\r\n", ftpState->filepath);
static void
ftpSendRest(FtpStateData * ftpState)
{
+ /* check the server control channel is still available */
+ if(!haveControlChannel("ftpSendRest"))
+ return;
+
snprintf(cbuf, 1024, "REST %d\r\n", ftpState->restart_offset);
ftpState->writeCommand(cbuf);
ftpState->state = SENT_REST;
static void
ftpSendList(FtpStateData * ftpState)
{
+ /* check the server control channel is still available */
+ if(!haveControlChannel("ftpSendList"))
+ return;
+
if (ftpState->filepath) {
snprintf(cbuf, 1024, "LIST %s\r\n", ftpState->filepath);
} else {
static void
ftpSendNlst(FtpStateData * ftpState)
{
+ /* check the server control channel is still available */
+ if(!haveControlChannel("ftpSendNlst"))
+ return;
+
ftpState->flags.tried_nlst = 1;
if (ftpState->filepath) {
static void
ftpSendRetr(FtpStateData * ftpState)
{
+ /* check the server control channel is still available */
+ if(!haveControlChannel("ftpSendRetr"))
+ return;
+
assert(ftpState->filepath != NULL);
snprintf(cbuf, 1024, "RETR %s\r\n", ftpState->filepath);
ftpState->writeCommand(cbuf);
static void
ftpSendQuit(FtpStateData * ftpState)
{
- assert(ftpState->ctrl.fd > -1);
+ /* check the server control channel is still available */
+ if(!haveControlChannel("ftpSendQuit"))
+ return;
+
snprintf(cbuf, 1024, "QUIT\r\n");
ftpState->writeCommand(cbuf);
ftpState->state = SENT_QUIT;
int code = ftpState->ctrl.replycode;
http_status http_code;
err_type err_code = ERR_NONE;
+
debugs(9, 5, "ftpSendReply: " << ftpState->entry->url() << ", code " << code );
if (cbdataReferenceValid(ftpState))
return ctrl.fd < 0 && data.fd < 0;
}
+bool
+haveControlChannel(const char *caller_name)
+{
+ if(!doneWithServer())
+ return true;
+
+ debugs(9, 2, caller_name << ": attempted on a closed FTP channel.");
+ return false;
+}
+
// Quickly abort the transaction
// TODO: destruction should be sufficient as the destructor should cleanup,
// including canceling close handlers