Пример #1
0
/***********************************************************************
 *
 * 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_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 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;

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

  result = smtp_multi_statemach(conn, done);

  return result;
}
Пример #3
0
/* called from multi.c while DOing */
static CURLcode smtp_doing(struct connectdata *conn,
                           bool *dophase_done)
{
    CURLcode result;
    result = smtp_multi_statemach(conn, dophase_done);

    if(*dophase_done) {
        result = smtp_dophase_done(conn, FALSE /* not connected */);

        DEBUGF(infof(conn->data, "DO phase is complete\n"));
    }
    return result;
}
Пример #4
0
/***********************************************************************
 *
 * smtp_perform()
 *
 * This is the actual DO function for SMTP. Transfer a mail, send a command
 * or get some data 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;
  struct Curl_easy *data = conn->data;
  struct SMTP *smtp = data->req.protop;

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

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

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

  /* Store the first recipient (or NULL if not specified) */
  smtp->rcpt = data->set.mail_rcpt;

  /* Initial data character is the first character in line: it is implicitly
     preceded by a virtual CRLF. */
  smtp->trailing_crlf = TRUE;
  smtp->eob = 2;

  /* Start the first command in the DO phase */
  if((data->set.upload || data->set.mimepost.kind) && data->set.mail_rcpt)
    /* MAIL transfer */
    result = smtp_perform_mail(conn);
  else
    /* SMTP based command (VRFY, EXPN, NOOP, RSET or HELP) */
    result = smtp_perform_command(conn);

  if(result)
    return result;

  /* Run the state-machine */
  result = smtp_multi_statemach(conn, dophase_done);

  *connected = conn->bits.tcpconnect[FIRSTSOCKET];

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

  return result;
}
Пример #5
0
Файл: smtp.c Проект: 54chen/curl
/***********************************************************************
 *
 * smtp_perform()
 *
 * This is the actual DO function for SMTP. Transfer a mail, send a command
 * or get some data 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;
  struct SessionHandle *data = conn->data;
  struct SMTP *smtp = data->req.protop;

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

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

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

  /* Store the first recipient (or NULL if not specified) */
  smtp->rcpt = data->set.mail_rcpt;

  /* Start the first command in the DO phase */
  if(data->set.upload && data->set.mail_rcpt)
    /* MAIL transfer */
    result = smtp_perform_mail(conn);
  else
    /* SMTP based command (VRFY, EXPN, NOOP, RSET or HELP) */
    result = smtp_perform_command(conn);

  if(result)
    return result;

  /* Run the state-machine */
  result = smtp_multi_statemach(conn, dophase_done);

  *connected = conn->bits.tcpconnect[FIRSTSOCKET];

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

  return result;
}
Пример #6
0
/***********************************************************************
 *
 * 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.
 */
static CURLcode smtp_connect(struct connectdata *conn, bool *done)
{
  CURLcode result = CURLE_OK;
  struct smtp_conn *smtpc = &conn->proto.smtpc;
  struct pingpong *pp = &smtpc->pp;

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

  /* We always support persistent connections in SMTP */
  connkeep(conn, "SMTP default");

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

  /* Initialize the SASL storage */
  Curl_sasl_init(&smtpc->sasl, &saslsmtp);

  /* Initialise the pingpong layer */
  Curl_pp_init(pp);

  /* Parse the URL options */
  result = smtp_parse_url_options(conn);
  if(result)
    return result;

  /* Parse the URL path */
  result = smtp_parse_url_path(conn);
  if(result)
    return result;

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

  result = smtp_multi_statemach(conn, done);

  return result;
}
Пример #7
0
/*
 * 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;
}
Пример #8
0
/*
 * smtp_connect() 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) /* 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;
  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 */
    /* 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 the domain in our EHLO */
  result = Curl_urldecode(conn->data, path, 0, &smtpc->domain, NULL, TRUE);
  if(result)
    return result;

  /* Set the state as we are waiting 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;
}