예제 #1
0
static int ftp_pasvmode(struct ftpc_session_s *session,
                        uint8_t addrport[6])
{
  int tmpap[6];
  char *ptr;
  int nscan;
  int ret;
  int i;

  /* Does this host support the PASV command */

  if (!FTPC_HAS_PASV(session))
  {
    ndbg("Host doesn't support passive mode\n");
    return ERROR;
  }

  /* Request passive mode.  The server normally accepts PASV with code 227.
   * Its response is a single line showing the IP address of the server and
   * the TCP port number where the server is accepting connections.
   */

  ret = ftpc_cmd(session, "PASV");
  if (ret < 0 || !ftpc_connected(session))
    {
      return ERROR;
    }

  /* Skip over any leading stuff before address begins */

  ptr = session->reply + 4;
  while (!isdigit((int)*ptr))
    {
      ptr++;
    }

  /* The response is then 6 integer values:  four representing the
   * IP address and two representing the port number.
   */

  nscan = sscanf(ptr, "%d,%d,%d,%d,%d,%d",
                 &tmpap[0], &tmpap[1], &tmpap[2],
                 &tmpap[3], &tmpap[4], &tmpap[5]);
  if (nscan != 6)
    {
      ndbg("Error parsing PASV reply: '%s'\n", session->reply);
      return ERROR;
    }

  /* Then copy the sscanf'ed values as bytes */


  for (i = 0; i < 6; i++)
    {
      addrport[i] = (uint8_t)(tmpap[i] & 0xff);
    }

  return OK;
}
예제 #2
0
int ftpc_login(SESSION handle, FAR struct ftpc_login_s *login)
{
  FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
  int err;
  int ret;

  /* Verify that we are connected to a server */

  if (!ftpc_connected(session))
    {
      ndbg("Not connected\n");
      err = ENOTCONN;
      goto errout_with_err;
    }

  /* Verify that we are not already logged in to the server */

  if (ftpc_loggedin(session))
    {
      ndbg("Already logged in\n");
      err = EINVAL;
      goto errout_with_err;
    }

  /* Save the login parameter */

  session->uname    = ftpc_dequote(login->uname);
  session->pwd      = ftpc_dequote(login->pwd);
  session->initrdir = ftpc_dequote(login->rdir);

  /* Is passive mode requested? */

  FTPC_CLR_PASSIVE(session);
  if (login->pasv)
    {
      nvdbg("Setting passive mode\n");
      FTPC_SET_PASSIVE(session);
    }

  /* The (Re-)login to the server */

  ret = ftpc_relogin(session);
  if (ret != OK)
    {
      ndbg("login failed: %d\n", errno);
      goto errout;
    }

  return OK;

errout_with_err:
  set_errno(err);
errout:
  return ERROR;
}
예제 #3
0
time_t ftpc_filetime(SESSION handle, FAR const char *filename)
{
  FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
  struct tm timestamp;
  int ret;

  /* Make sure that the server is still connected */

  if (!ftpc_connected(session))
    {
      return ERROR;
    }

  /* Does the server support the MDTM command? */

  if (!FTPC_HAS_MDTM(session))
    {
      return ERROR;
    }

  /* Get the file time in UTC */

  memset(&timestamp, 0, sizeof(timestamp));
  ret = ftpc_cmd(session, "MDTM %s", filename);
  if (ret != OK)
    {
      return ERROR;
    }

  /* Check for "202 Command not implemented, superfluous at this site" */

  if (session->code == 202)
    {
      FTPC_CLR_MDTM(session);
      return ERROR;
    }

  /* Check for "213 File status" */

  if (session->code != 213)
    {
      return ERROR;
    }

  /* Time is Universal Coordinated Time */

  sscanf(session->reply, "%*s %04d%02d%02d%02d%02d%02d",
         &timestamp.tm_year, &timestamp.tm_mon, &timestamp.tm_mday,
         &timestamp.tm_hour, &timestamp.tm_min, &timestamp.tm_sec);
  timestamp.tm_year -= 1900;
  timestamp.tm_mon--;
  return mktime(&timestamp);
}
예제 #4
0
int ftpc_xfrabort(FAR struct ftpc_session_s *session, FAR FILE *stream)
{
  FAR struct pollfd fds;
  int ret;

  /* Make sure that we are still connected */

  if (!ftpc_connected(session))
    {
      return ERROR;
    }

  /* Check if there is data waiting to be read from the cmd channel */

  fds.fd     = session->cmd.sd;
  fds.events = POLLIN;
  ret        = poll(&fds, 1, 0);
  if (ret > 0)
  {
    /* Read data from command channel */

    nvdbg("Flush cmd channel data\n");
    while (stream && fread(session->buffer, 1, CONFIG_FTP_BUFSIZE, stream) > 0);
    return OK;
  }

  FTPC_SET_INTERRUPT(session);

  /* Send the Telnet interrupt sequence to abort the transfer:
   * <IAC IP><IAC DM>ABORT<CR><LF>
   */

  nvdbg("Telnet ABORt sequence\n");
  ftpc_sockprintf(&session->cmd, "%c%c", TELNET_IAC, TELNET_IP); /* Interrupt process */
  ftpc_sockprintf(&session->cmd, "%c%c", TELNET_IAC, TELNET_DM); /* Telnet synch signal */
  ftpc_sockprintf(&session->cmd, "ABOR\r\n");                    /* Abort */
  ftpc_sockflush(&session->cmd);

  /* Read remaining bytes from connection */

  while (stream && fread(session->buffer, 1, CONFIG_FTP_BUFSIZE, stream) > 0);

  /* Get the ABORt reply */

  fptc_getreply(session);

  /* Expected replys are: "226 Closing data connection" or
   * "426 Connection closed; transfer aborted"
   */

  if (session->code != 226 && session->code != 426)
    {
      nvdbg("Expected 226 or 426 reply\n");
    }
  else
    {
      /* Get the next reply */

      fptc_getreply(session);

     /* Expected replys are:  or "225 Data connection open; no transfer in progress"
      * "226 Closing data connection"
      */

     if (session->code != 226 && session->code != 225)
       {
         nvdbg("Expected 225 or 226 reply\n");
       }
    }

  return ERROR;
}
예제 #5
0
int ftpc_xfrinit(FAR struct ftpc_session_s *session)
{
  struct sockaddr_in addr;
  uint8_t addrport[6];
  uint8_t *paddr;
  uint8_t *pport;
  int ret;

  /* We must be connected to initiate a transfer */

  if (!ftpc_connected(session))
    {
      ndbg("Not connected\n");
      goto errout;
    }

  /* Initialize the data channel */

  ret = ftpc_sockinit(&session->data);
  if (ret != OK)
    {
      ndbg("ftpc_sockinit() failed: %d\n", errno);
      goto errout;
    }

  /* Duplicate the address and connection information of the command channel */

  ftpc_sockcopy(&session->data, &session->cmd);

  /* Should we enter passive mode? */

  if (FTPC_IS_PASSIVE(session))
    {
      /* Yes.. going passive. */

      ret = ftp_pasvmode(session, addrport);
      if (ret != OK)
        {
          ndbg("ftp_pasvmode() failed: %d\n", errno);
          goto errout_with_data;
        }

      /* Configure the data socket */

      ftpc_sockgetsockname(&session->cmd, &addr);
      memcpy(&addr.sin_addr, addrport, 4);
      memcpy(&addr.sin_port, addrport+4, 2);

      /* Connect the data socket */

      ret = ftpc_sockconnect(&session->data, &addr);
      if (ret < 0)
        {
          ndbg("ftpc_sockconnect() failed: %d\n", errno);
          goto errout_with_data;
        }
    }
  else
    {
      /* Wait for the connection to be established */

      ftpc_socklisten(&session->data);

      /* Then send our local data channel address to the server */

      paddr = (uint8_t *)&session->data.laddr.sin_addr;
      pport = (uint8_t *)&session->data.laddr.sin_port;

      ret = ftpc_cmd(session, "PORT %d,%d,%d,%d,%d,%d",
                     paddr[0], paddr[1], paddr[2],
                     paddr[3], pport[0], pport[1]);
      if (ret < 0)
        {
          ndbg("ftpc_cmd() failed: %d\n", errno);
          goto errout_with_data;
        }
    }
  return OK;

 errout_with_data:
  ftpc_sockclose(&session->data);
 errout:
  return ERROR;
}