コード例 #1
0
ファイル: smtp.c プロジェクト: sohailsomani/curl
/***********************************************************************
 *
 * smtp_perform()
 *
 * This is the actual DO function for SMTP. Get a file/directory according to
 * the options previously setup.
 */
static CURLcode smtp_perform(struct connectdata *conn, bool *connected,
                             bool *dophase_done)
{
  /* This is SMTP and no proxy */
  CURLcode result = CURLE_OK;

  DEBUGF(infof(conn->data, "DO phase starts\n"));

  if(conn->data->set.opt_no_body) {
    /* Requested no body means no transfer */
    struct FTP *smtp = conn->data->state.proto.smtp;
    smtp->transfer = FTPTRANSFER_INFO;
  }

  *dophase_done = FALSE; /* not done yet */

  /* Start the first command in the DO phase */
  result = smtp_mail(conn);
  if(result)
    return result;

  /* Run the state-machine */
  if(conn->data->state.used_interface == Curl_if_multi)
    result = smtp_multi_statemach(conn, dophase_done);
  else {
    result = smtp_easy_statemach(conn);
    *dophase_done = TRUE; /* with the easy interface we are done here */
  }
  *connected = conn->bits.tcpconnect[FIRSTSOCKET];

  if(*dophase_done)
    DEBUGF(infof(conn->data, "DO phase is complete\n"));

  return result;
}
コード例 #2
0
ファイル: smtp.c プロジェクト: bhalder/Optimized-Webserver
/***********************************************************************
 *
 * smtp_done()
 *
 * The DONE function. This does what needs to be done after a single DO has
 * performed.
 *
 * Input argument is already checked for validity.
 */
static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
                          bool premature)
{
  struct SessionHandle *data = conn->data;
  struct FTP *smtp = data->state.proto.smtp;
  CURLcode result = CURLE_OK;
  ssize_t bytes_written;
  (void)premature;

  if(!smtp)
    /* When the easy handle is removed from the multi while libcurl is still
     * trying to resolve the host name, it seems that the smtp struct is not
     * yet initialized, but the removal action calls Curl_done() which calls
     * this function. So we simply return success if no smtp pointer is set.
     */
    return CURLE_OK;

  if(status) {
    conn->bits.close = TRUE; /* marked for closure */
    result = status;      /* use the already set error code */
  }
  else
    /* TODO: make this work even when the socket is EWOULDBLOCK in this
       call! */

    /* write to socket (send away data) */
    result = Curl_write(conn,
                        conn->writesockfd,  /* socket to send to */
                        SMTP_EOB,           /* buffer pointer */
                        SMTP_EOB_LEN,       /* buffer size */
                        &bytes_written);    /* actually sent away */


  if(status == CURLE_OK) {
    struct smtp_conn *smtpc = &conn->proto.smtpc;
    struct pingpong *pp = &smtpc->pp;
    pp->response = Curl_tvnow(); /* timeout relative now */

    state(conn, SMTP_POSTDATA);
    /* run the state-machine

       TODO: when the multi interface is used, this _really_ should be using
       the smtp_multi_statemach function but we have no general support for
       non-blocking DONE operations, not in the multi state machine and with
       Curl_done() invokes on several places in the code!
    */
    result = smtp_easy_statemach(conn);
  }

  /* clear these for next connection */
  smtp->transfer = FTPTRANSFER_BODY;

  return result;
}
コード例 #3
0
ファイル: smtp.c プロジェクト: wnpllrzodiac/transmission
/***********************************************************************
 *
 * smtp_quit()
 *
 * This should be called before calling sclose().  We should then wait for the
 * response from the server before returning. The calling code should then try
 * to close the connection.
 *
 */
static CURLcode smtp_quit(struct connectdata *conn)
{
    CURLcode result = CURLE_OK;

    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "QUIT");
    if(result)
        return result;
    state(conn, SMTP_QUIT);

    result = smtp_easy_statemach(conn);

    return result;
}
コード例 #4
0
ファイル: smtp.c プロジェクト: wnpllrzodiac/transmission
/*
 * smtp_connect() should do everything that is to be considered a part of
 * the connection phase.
 *
 * The variable 'done' points to will be TRUE if the protocol-layer connect
 * phase is done when this function returns, or FALSE is not. When called as
 * a part of the easy interface, it will always be TRUE.
 */
static CURLcode smtp_connect(struct connectdata *conn,
                             bool *done) /* see description above */
{
    CURLcode result;
    struct smtp_conn *smtpc = &conn->proto.smtpc;
    struct SessionHandle *data=conn->data;
    struct pingpong *pp=&smtpc->pp;
    const char *path = conn->data->state.path;
    int len;
    char localhost[1024 + 1];

    *done = FALSE; /* default to not done yet */

    /* If there already is a protocol-specific struct allocated for this
       sessionhandle, deal with it */
    Curl_reset_reqproto(conn);

    result = smtp_init(conn);
    if(CURLE_OK != result)
        return result;

    /* We always support persistant connections on smtp */
    conn->bits.close = FALSE;

    pp->response_time = RESP_TIMEOUT; /* set default response time-out */
    pp->statemach_act = smtp_statemach_act;
    pp->endofresp = smtp_endofresp;
    pp->conn = conn;

#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_PROXY)
    if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
        /* for SMTP over HTTP proxy */
        struct HTTP http_proxy;
        struct FTP *smtp_save;

        /* BLOCKING */
        /* We want "seamless" SMTP operations through HTTP proxy tunnel */

        /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the member
         * conn->proto.http; we want SMTP through HTTP and we have to change the
         * member temporarily for connecting to the HTTP proxy. After
         * Curl_proxyCONNECT we have to set back the member to the original struct
         * SMTP pointer
         */
        smtp_save = data->state.proto.smtp;
        memset(&http_proxy, 0, sizeof(http_proxy));
        data->state.proto.http = &http_proxy;

        result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
                                   conn->host.name, conn->remote_port);

        data->state.proto.smtp = smtp_save;

        if(CURLE_OK != result)
            return result;
    }
#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_PROXY */

    if(conn->protocol & PROT_SMTPS) {
        /* BLOCKING */
        /* SMTPS is simply smtp with SSL for the control channel */
        /* now, perform the SSL initialization for this socket */
        result = Curl_ssl_connect(conn, FIRSTSOCKET);
        if(result)
            return result;
    }

    Curl_pp_init(pp); /* init the response reader stuff */

    pp->response_time = RESP_TIMEOUT; /* set default response time-out */
    pp->statemach_act = smtp_statemach_act;
    pp->endofresp = smtp_endofresp;
    pp->conn = conn;

    if(!*path) {
        if(!Curl_gethostname(localhost, sizeof localhost))
            path = localhost;
        else
            path = "localhost";
    }

    /* url decode the path and use it as domain with EHLO */
    smtpc->domain = curl_easy_unescape(conn->data, path, 0, &len);
    if(!smtpc->domain)
        return CURLE_OUT_OF_MEMORY;

    /* When we connect, we start in the state where we await the server greeting
     */
    state(conn, SMTP_SERVERGREET);

    if(data->state.used_interface == Curl_if_multi)
        result = smtp_multi_statemach(conn, done);
    else {
        result = smtp_easy_statemach(conn);
        if(!result)
            *done = TRUE;
    }

    return result;
}
コード例 #5
0
ファイル: smtp.c プロジェクト: sohailsomani/curl
/***********************************************************************
 *
 * smtp_done()
 *
 * The DONE function. This does what needs to be done after a single DO has
 * performed.
 *
 * Input argument is already checked for validity.
 */
static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
                          bool premature)
{
  struct SessionHandle *data = conn->data;
  struct FTP *smtp = data->state.proto.smtp;
  CURLcode result = CURLE_OK;
  ssize_t bytes_written;

  (void)premature;

  if(!smtp)
    /* When the easy handle is removed from the multi while libcurl is still
     * trying to resolve the host name, it seems that the smtp struct is not
     * yet initialized, but the removal action calls Curl_done() which calls
     * this function. So we simply return success if no smtp pointer is set.
     */
    return CURLE_OK;

  if(status) {
    conn->bits.close = TRUE; /* marked for closure */
    result = status;         /* use the already set error code */
  }
  else if(!data->set.connect_only) {
    struct smtp_conn *smtpc = &conn->proto.smtpc;
    struct pingpong *pp = &smtpc->pp;

    /* Send the end of block data */
    result = Curl_write(conn,
                        conn->writesockfd,  /* socket to send to */
                        SMTP_EOB,           /* buffer pointer */
                        SMTP_EOB_LEN,       /* buffer size */
                        &bytes_written);    /* actually sent away */

    if(result)
      return result;

    if(bytes_written != SMTP_EOB_LEN) {
      /* The whole chunk was not sent so keep it around and adjust the
         pingpong structure accordingly */
      pp->sendthis = strdup(SMTP_EOB);
      pp->sendsize = SMTP_EOB_LEN;
      pp->sendleft = SMTP_EOB_LEN - bytes_written;
    }
    else
      /* Successfully sent so adjust the response timeout relative to now */
      pp->response = Curl_tvnow();

    state(conn, SMTP_POSTDATA);

    /* Run the state-machine

       TODO: when the multi interface is used, this _really_ should be using
       the smtp_multi_statemach function but we have no general support for
       non-blocking DONE operations, not in the multi state machine and with
       Curl_done() invokes on several places in the code!
    */
    result = smtp_easy_statemach(conn);
  }

  /* Clear the transfer mode for the next connection */
  smtp->transfer = FTPTRANSFER_BODY;

  return result;
}
コード例 #6
0
ファイル: smtp.c プロジェクト: sohailsomani/curl
/***********************************************************************
 *
 * smtp_connect()
 *
 * This function should do everything that is to be considered a part of
 * the connection phase.
 *
 * The variable pointed to by 'done' will be TRUE if the protocol-layer
 * connect phase is done when this function returns, or FALSE if not. When
 * called as a part of the easy interface, it will always be TRUE.
 */
static CURLcode smtp_connect(struct connectdata *conn, bool *done)
{
  CURLcode result;
  struct smtp_conn *smtpc = &conn->proto.smtpc;
  struct SessionHandle *data = conn->data;
  struct pingpong *pp = &smtpc->pp;
  const char *path = conn->data->state.path;
  char localhost[HOSTNAME_MAX + 1];

  *done = FALSE; /* default to not done yet */

  /* If there already is a protocol-specific struct allocated for this
     sessionhandle, deal with it */
  Curl_reset_reqproto(conn);

  result = smtp_init(conn);
  if(CURLE_OK != result)
    return result;

  /* We always support persistent connections on smtp */
  conn->bits.close = FALSE;

  pp->response_time = RESP_TIMEOUT; /* set default response time-out */
  pp->statemach_act = smtp_statemach_act;
  pp->endofresp = smtp_endofresp;
  pp->conn = conn;

  if((conn->handler->protocol & CURLPROTO_SMTPS) &&
      data->state.used_interface != Curl_if_multi) {
    /* SMTPS is simply smtp with SSL for the control channel */
    /* so perform the SSL initialization for this socket */
    result = Curl_ssl_connect(conn, FIRSTSOCKET);
    if(result)
      return result;
  }

  /* Initialise the response reader stuff */
  Curl_pp_init(pp);

  /* Set the default response time-out */
  pp->response_time = RESP_TIMEOUT;
  pp->statemach_act = smtp_statemach_act;
  pp->endofresp = smtp_endofresp;
  pp->conn = conn;

  /* Calculate the path if necessary */
  if(!*path) {
    if(!Curl_gethostname(localhost, sizeof(localhost)))
      path = localhost;
    else
      path = "localhost";
  }

  /* URL decode the path and use it as the domain in our EHLO */
  result = Curl_urldecode(conn->data, path, 0, &smtpc->domain, NULL, TRUE);
  if(result)
    return result;

  /* Start off waiting for the server greeting response */
  state(conn, SMTP_SERVERGREET);

  if(data->state.used_interface == Curl_if_multi)
    result = smtp_multi_statemach(conn, done);
  else {
    result = smtp_easy_statemach(conn);
    if(!result)
      *done = TRUE;
  }

  return result;
}