Back to index

nordugrid-arc-nox  1.1.0~rc6
Classes | Public Member Functions | Private Attributes | Static Private Attributes
Arc::FTPControl Class Reference

#include <FTPControl.h>

Collaboration diagram for Arc::FTPControl:
Collaboration graph
[legend]

List of all members.

Classes

class  CBArg

Public Member Functions

 FTPControl ()
 ~FTPControl ()
bool Connect (const URL &url, const std::string &proxyPath, const std::string &certificatePath, const std::string &keyPath, int timeout)
bool SendCommand (const std::string &cmd, int timeout)
bool SendCommand (const std::string &cmd, std::string &response, int timeout)
bool SendData (const std::string &data, const std::string &filename, int timeout)
bool Disconnect (int timeout)

Private Attributes

globus_ftp_control_handle_t control_handle
CBArgcb
bool connected

Static Private Attributes

static Logger logger

Detailed Description

Definition at line 15 of file FTPControl.h.


Constructor & Destructor Documentation

Definition at line 125 of file FTPControl.cpp.

                         {
    connected = false;
    cb = new CBArg;
    globus_module_activate(GLOBUS_FTP_CONTROL_MODULE);
  }

Definition at line 131 of file FTPControl.cpp.

                          {
    if(connected) Disconnect(10);
    globus_module_deactivate(GLOBUS_FTP_CONTROL_MODULE);
    cb->release();
  }

Here is the call graph for this function:


Member Function Documentation

bool Arc::FTPControl::Connect ( const URL url,
const std::string &  proxyPath,
const std::string &  certificatePath,
const std::string &  keyPath,
int  timeout 
)

Definition at line 137 of file FTPControl.cpp.

                                        {

    bool timedin;
    GlobusResult result;

    result = globus_ftp_control_handle_init(&control_handle);
    if (!result) {
      logger.msg(VERBOSE, "Connect: Failed to init handle: %s", result.str());
      return false;
    }

    cb->ctrl = false;
    result = globus_ftp_control_connect(&control_handle,
                                        const_cast<char*>(url.Host().c_str()),
                                        url.Port(), &ConnectCallback,
                                        cb->claim());
    if (!result) {
      cb->release();
      logger.msg(VERBOSE, "Connect: Failed to connect: %s", result.str());
      return false;
    }
    while (!cb->ctrl) {
      timedin = cb->cond.wait(timeout * 1000);
      if (!timedin) {
        logger.msg(VERBOSE, "Connect: Connecting timed out after %d ms",
                   timeout * 1000);
        return false;
      }
    }
    if (!cb->responseok) {
      logger.msg(VERBOSE, "Connect: Failed to connect: %s", cb->response);
      return false;
    }
    connected = true;

    GSSCredential handle(proxyPath, certificatePath, keyPath);

    globus_ftp_control_auth_info_t auth;
    result = globus_ftp_control_auth_info_init(&auth, handle, GLOBUS_TRUE,
                                               const_cast<char*>("ftp"),
                                               const_cast<char*>("user@"),
                                               GLOBUS_NULL, GLOBUS_NULL);
    if (!result) {
      logger.msg(VERBOSE, "Connect: Failed to init auth info handle: %s",
                 result.str());
      return false;
    }

    cb->ctrl = false;
    result = globus_ftp_control_authenticate(&control_handle, &auth,
                                             GLOBUS_TRUE,
                                             &ControlCallback, cb);
    if (!result) {
      logger.msg(VERBOSE, "Connect: Failed authentication: %s", result.str());
      return false;
    }
    while (!cb->ctrl) {
      timedin = cb->cond.wait(timeout * 1000);
      if (!timedin) {
        logger.msg(VERBOSE, "Connect: Authentication timed out after %d ms",
                   timeout * 1000);
        return false;
      }
    }
    if (!cb->responseok) {
      logger.msg(VERBOSE, "Connect: Failed authentication: %s", cb->response);
      return false;
    }

    return true;

  } // end Connect

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::FTPControl::Disconnect ( int  timeout)

Definition at line 415 of file FTPControl.cpp.

                                         {

    bool timedin;
    GlobusResult result;
    bool res = true;

    if(!connected) return res;

    cb->ctrl = false;
    result = globus_ftp_control_quit(&control_handle, &ControlCallback, cb);
    if (!result) {
      logger.msg(VERBOSE, "Disconnect: Failed quitting: %s", result.str());
      return false;
    }
    while (!cb->ctrl) {
      timedin = cb->cond.wait(timeout * 1000);
      if (!timedin) {
        logger.msg(VERBOSE, "Disconnect: Quitting timed out after %d ms",
                   timeout * 1000);
        res = false;
      }
    }

    connected = false;
    cb->close = false;
    result = globus_ftp_control_force_close(&control_handle, &CloseCallback,
                                     cb->claim());
    if (!result) {
      cb->release();
      // Assuming only reason for failure here is that connection is 
      // already closed
      logger.msg(DEBUG, "Disconnect: Failed closing - ignoring: %s",
                 result.str());
    } else {
      // Need to wait for callback to make sure handle destruction will work
      // Hopefully forced close should never take long time
      while (!cb->close) {
        timedin = cb->cond.wait(timeout * 1000);
        if (!timedin) {
          logger.msg(ERROR, "Disconnect: Closing timed out after %d ms",
                     timeout * 1000);
          res = false;
        }
      }
    }

    result = globus_ftp_control_handle_destroy(&control_handle);
    if (!result) {
      // That means memory leak
      logger.msg(VERBOSE, "Disconnect: Failed to destroy handle: %s",
                 result.str());
      return false;
    }

    return true;

  } // end Disconnect

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::FTPControl::SendCommand ( const std::string &  cmd,
int  timeout 
)

Definition at line 214 of file FTPControl.cpp.

                                                                {

    bool timedin;
    GlobusResult result;

    cb->ctrl = false;
    result = globus_ftp_control_send_command(&control_handle, cmd.c_str(),
                                             &ControlCallback, cb);
    if (!result) {
      logger.msg(VERBOSE, "SendCommand: Failed: %s", result.str());
      return false;
    }
    while (!cb->ctrl) {
      timedin = cb->cond.wait(timeout * 1000);
      if (!timedin) {
        logger.msg(VERBOSE, "SendCommand: Timed out after %d ms", timeout * 1000);
        return false;
      }
    }
    if (!cb->responseok) {
      logger.msg(VERBOSE, "SendCommand: Failed: %s", cb->response);
      return false;
    }

    return true;

  } // end SendCommand

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::FTPControl::SendCommand ( const std::string &  cmd,
std::string &  response,
int  timeout 
)

Definition at line 242 of file FTPControl.cpp.

                                            {

    bool timedin;
    GlobusResult result;

    cb->ctrl = false;
    result = globus_ftp_control_send_command(&control_handle, cmd.c_str(),
                                             &ControlCallback, cb);
    if (!result) {
      logger.msg(VERBOSE, "SendCommand: Failed: %s", result.str());
      return false;
    }
    while (!cb->ctrl) {
      timedin = cb->cond.wait(timeout * 1000);
      if (!timedin) {
        logger.msg(VERBOSE, "SendCommand: Timed out after %d ms", timeout * 1000);
        return false;
      }
    }
    if (!cb->responseok) {
      logger.msg(VERBOSE, "SendCommand: Failed: %s", cb->response);
      return false;
    }

    response = cb->response;

    return true;

  } // end SendCommand

Here is the call graph for this function:

bool Arc::FTPControl::SendData ( const std::string &  data,
const std::string &  filename,
int  timeout 
)

Definition at line 273 of file FTPControl.cpp.

                                                                    {

    bool timedin;
    GlobusResult result;

    if (!SendCommand("DCAU N", timeout)) {
      logger.msg(VERBOSE, "SendData: Failed sending DCAU command");
      return false;
    }

    if (!SendCommand("TYPE I", timeout)) {
      logger.msg(VERBOSE, "SendData: Failed sending TYPE command");
      return false;
    }

    std::string response;

    if (!SendCommand("PASV", response, timeout)) {
      logger.msg(VERBOSE, "SendData: Failed sending PASV command");
      return false;
    }

    std::string::size_type pos1 = response.find('(');
    if (pos1 == std::string::npos) {
      logger.msg(VERBOSE, "SendData: Server PASV response parsing failed: %s",
                 response);
      return false;
    }
    std::string::size_type pos2 = response.find(')', pos1 + 1);
    if (pos2 == std::string::npos) {
      logger.msg(VERBOSE, "SendData: Server PASV response parsing failed: %s",
                 response);
      return false;
    }

    globus_ftp_control_host_port_t passive_addr;
    passive_addr.port = 0;
    unsigned short port_low, port_high;
    if (sscanf(response.substr(pos1 + 1, pos2 - pos1 - 1).c_str(),
               "%i,%i,%i,%i,%hu,%hu",
               &passive_addr.host[0],
               &passive_addr.host[1],
               &passive_addr.host[2],
               &passive_addr.host[3],
               &port_high,
               &port_low) == 6) {
      passive_addr.port = 256 * port_high + port_low;
    } else {
      logger.msg(VERBOSE, "SendData: Server PASV response parsing failed: %s",
                 response);
      return false;
    }

    result = globus_ftp_control_local_port(&control_handle, &passive_addr);
    if (!result) {
      logger.msg(VERBOSE, "SendData: Local port failed: %s", result.str());
      return false;
    }

    result = globus_ftp_control_local_type(&control_handle,
                                           GLOBUS_FTP_CONTROL_TYPE_IMAGE, 0);
    if (!result) {
      logger.msg(VERBOSE, "SendData: Local type failed: %s", result.str());
      return false;
    }

    cb->ctrl = false;
    cb->data = false;
    result = globus_ftp_control_send_command(&control_handle,
                                             ("STOR " + filename).c_str(),
                                             &ControlCallback, cb);
    if (!result) {
      logger.msg(VERBOSE, "SendData: Failed sending STOR command: %s",
                 result.str());
      return false;
    }

    result = globus_ftp_control_data_connect_write(&control_handle,
                                                   &DataConnectCallback, cb);
    if (!result) {
      logger.msg(VERBOSE, "SendData: Data connect write failed: %s",
                 result.str());
      return false;
    }
    while (!cb->data) {
      timedin = cb->cond.wait(timeout * 1000);
      if (!timedin) {
        logger.msg(VERBOSE, "SendData: Data connect write timed out after %d ms",
                   timeout * 1000);
        return false;
      }
    }
    while (!cb->ctrl) {
      timedin = cb->cond.wait(timeout * 1000);
      if (!timedin) {
        logger.msg(VERBOSE, "SendData: Data connect write timed out after %d ms",
                   timeout * 1000);
        return false;
      }
    }
    if (!cb->responseok) {
      logger.msg(VERBOSE, "SendData: Data connect write failed: %s",
                 cb->response);
      return false;
    }

    cb->data = false;
    cb->ctrl = false;
    result = globus_ftp_control_data_write(&control_handle,
                                           (globus_byte_t*)data.c_str(),
                                           data.size(), 0, GLOBUS_TRUE,
                                           &ReadWriteCallback, cb);
    if (!result) {
      logger.msg(VERBOSE, "SendData: Data write failed: %s", result.str());
      return false;
    }
    while (!cb->data) {
      timedin = cb->cond.wait(timeout * 1000);
      if (!timedin) {
        logger.msg(VERBOSE, "SendData: Data write timed out after %d ms",
                   timeout * 1000);
        return false;
      }
    }
    while (!cb->ctrl) {
      timedin = cb->cond.wait(timeout * 1000);
      if (!timedin) {
        logger.msg(VERBOSE, "SendData: Data write timed out after %d ms",
                   timeout * 1000);
        return false;
      }
    }
    if (!cb->responseok) {
      logger.msg(VERBOSE, "SendData: Data write failed: %s", cb->response);
      return false;
    }

    return true;

  } // end SendData

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 36 of file FTPControl.h.

Definition at line 37 of file FTPControl.h.

globus_ftp_control_handle_t Arc::FTPControl::control_handle [private]

Definition at line 35 of file FTPControl.h.

Logger Arc::FTPControl::logger [static, private]

Definition at line 31 of file FTPControl.h.


The documentation for this class was generated from the following files: