CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
{
  /* When sending SMTP payload, we must detect CRLF.CRLF sequences in
   * the data and make sure it is sent as CRLF..CRLF instead, as
   * otherwise it will wrongly be detected as end of data by the server.
   */
  ssize_t i;
  ssize_t si;
  struct smtp_conn *smtpc = &conn->proto.smtpc;
  struct SessionHandle *data = conn->data;

  if(data->state.scratch == NULL)
    data->state.scratch = malloc(2 * BUFSIZE);
  if(data->state.scratch == NULL) {
    failf (data, "Failed to alloc scratch buffer!");
    return CURLE_OUT_OF_MEMORY;
  }
  /* This loop can be improved by some kind of Boyer-Moore style of
     approach but that is saved for later... */
  for(i = 0, si = 0; i < nread; i++) {

    if(SMTP_EOB[smtpc->eob] == data->req.upload_fromhere[i])
      smtpc->eob++;
    else if(smtpc->eob) {
      /* previously a substring matched, output that first */
      memcpy(&data->state.scratch[si], SMTP_EOB, smtpc->eob);
      si += smtpc->eob;

      /* then compare the first byte */
      if(SMTP_EOB[0] == data->req.upload_fromhere[i])
        smtpc->eob = 1;
      else
        smtpc->eob = 0;
    }

    if(SMTP_EOB_LEN == smtpc->eob) {
      /* It matched, copy the replacement data to the target buffer
         instead. Note that the replacement does not contain the
         trailing CRLF but we instead continue to match on that one
         to deal with repeated sequences. Like CRLF.CRLF.CRLF etc
      */
      memcpy(&data->state.scratch[si], SMTP_EOB_REPL,
             SMTP_EOB_REPL_LEN);
      si += SMTP_EOB_REPL_LEN;
      smtpc->eob = 2; /* start over at two bytes */
    }
    else if(!smtpc->eob)
      data->state.scratch[si++] = data->req.upload_fromhere[i];

  } /* for() */

  if(si != nread) {
    /* only use the new buffer if we replaced something */
    nread = si;

    /* upload from the new (replaced) buffer instead */
    data->req.upload_fromhere = data->state.scratch;

    /* set the new amount too */
    data->req.upload_present = nread;
  }

  return CURLE_OK;
}
CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread)
{
   
  ssize_t i;
  ssize_t si;
  struct smtp_conn *smtpc = &conn->proto.smtpc;
  struct SessionHandle *data = conn->data;

  if(data->state.scratch == NULL)
    data->state.scratch = malloc(2 * BUFSIZE);
  if(data->state.scratch == NULL) {
    failf (data, "Failed to alloc scratch buffer!");
    return CURLE_OUT_OF_MEMORY;
  }
   
  for(i = 0, si = 0; i < nread; i++) {

    if(SMTP_EOB[smtpc->eob] == data->req.upload_fromhere[i])
      smtpc->eob++;
    else if(smtpc->eob) {
       
      memcpy(&data->state.scratch[si], SMTP_EOB, smtpc->eob);
      si += smtpc->eob;

       
      if(SMTP_EOB[0] == data->req.upload_fromhere[i])
        smtpc->eob = 1;
      else
        smtpc->eob = 0;
    }

    if(SMTP_EOB_LEN == smtpc->eob) {
       
      memcpy(&data->state.scratch[si], SMTP_EOB_REPL,
             SMTP_EOB_REPL_LEN);
      si += SMTP_EOB_REPL_LEN;
      smtpc->eob = 2;  
    }
    else if(!smtpc->eob)
      data->state.scratch[si++] = data->req.upload_fromhere[i];

  }  

  if(si != nread) {
     
    nread = si;

     
    data->req.upload_fromhere = data->state.scratch;

     
    data->req.upload_present = nread;
  }

  return CURLE_OK;
}