Ejemplo n.º 1
0
long smtp_rcpt (SENDSTREAM *stream,ADDRESS *adr,long *error)
{
 char *s,tmp[2*MAILTMPLEN],orcpt[MAILTMPLEN];
  while (adr) {			/* for each address on the list */
				/* clear any former error */
    if (adr->error) fs_give ((void **) &adr->error);
    if (adr->host) {		/* ignore group syntax */
				/* enforce SMTP limits to protect the buffer */
      if (strlen (adr->mailbox) > MAXLOCALPART) {
	adr->error = cpystr ("501 Recipient name too long");
	*error = T;
      }
      else if ((strlen (adr->host) > SMTPMAXDOMAIN)) {
	adr->error = cpystr ("501 Recipient domain too long");
	*error = T;
      }
#ifndef RFC2821			/* old code with A-D-L support */
      else if (adr->adl && (strlen (adr->adl) > SMTPMAXPATH)) {
	adr->error = cpystr ("501 Path too long");
	*error = T;
      }
#endif

      else {
	strcpy (tmp,"TO:<");	/* compose "RCPT TO:<return-path>" */
#ifdef RFC2821
	rfc822_cat (tmp,adr->mailbox,NIL);
	sprintf (tmp + strlen (tmp),"@%s>",adr->host);
#else				/* old code with A-D-L support */
	rfc822_address (tmp,adr);
	strcat (tmp,">");
#endif
				/* want notifications */
	if (ESMTP.ok && ESMTP.dsn.ok && ESMTP.dsn.want) {
				/* yes, start with prefix */
	  strcat (tmp," NOTIFY=");
	  s = tmp + strlen (tmp);
	  if (ESMTP.dsn.notify.failure) strcat (s,"FAILURE,");
	  if (ESMTP.dsn.notify.delay) strcat (s,"DELAY,");
	  if (ESMTP.dsn.notify.success) strcat (s,"SUCCESS,");
				/* tie off last comma */
	  if (*s) s[strlen (s) - 1] = '\0';
	  else strcat (tmp,"NEVER");
	  if (adr->orcpt.addr) {
	    sprintf (orcpt,"%.498s;%.498s",
		     adr->orcpt.type ? adr->orcpt.type : "rfc822",
		     adr->orcpt.addr);
	    sprintf (tmp + strlen (tmp)," ORCPT=%.500s",orcpt);
	  }
	}
	switch (smtp_send (stream,"RCPT",tmp)) {
	case SMTPOK:		/* looks good */
	  break;
	case SMTPUNAVAIL:	/* mailbox unavailable? */
	case SMTPWANTAUTH:	/* wants authentication? */
	case SMTPWANTAUTH2:
	  if (ESMTP.auth) return T;
	default:		/* other failure */
	  *error = T;		/* note that an error occurred */
	  adr->error = cpystr (stream->reply);
	}
      }
    }
    adr = adr->next;		/* do any subsequent recipients */
  }
  return NIL;			/* no retry called for */
}
Ejemplo n.º 2
0
int
mutt_copy_header (FILE *in, HEADER *h, FILE *out, int flags, const char *prefix)
{
  char buffer[SHORT_STRING];

  if (h->env)
    flags |= (h->env->irt_changed ? CH_UPDATE_IRT : 0)
      | (h->env->refs_changed ? CH_UPDATE_REFS : 0);
  
  if (mutt_copy_hdr (in, out, h->offset, h->content->offset, flags, prefix) == -1)
    return -1;

  if (flags & CH_TXTPLAIN)
  {
    char chsbuf[SHORT_STRING];
    fputs ("MIME-Version: 1.0\n", out);
    fputs ("Content-Transfer-Encoding: 8bit\n", out);
    fputs ("Content-Type: text/plain; charset=", out);
    mutt_canonical_charset (chsbuf, sizeof (chsbuf), Charset ? Charset : "us-ascii");
    rfc822_cat(buffer, sizeof(buffer), chsbuf, MimeSpecials);
    fputs(buffer, out);
    fputc('\n', out);
  }

  if ((flags & CH_UPDATE_IRT) && h->env->in_reply_to)
  {
    LIST *listp = h->env->in_reply_to;
    fputs ("In-Reply-To:", out);
    for (; listp; listp = listp->next)
    {
      fputc (' ', out);
      fputs (listp->data, out);
    }
    fputc ('\n', out);
  }

  if ((flags & CH_UPDATE_REFS) && h->env->references)
  {
    fputs ("References:", out);
    mutt_write_references (h->env->references, out, 0);
    fputc ('\n', out);
  }

  if ((flags & CH_UPDATE) && (flags & CH_NOSTATUS) == 0)
  {
    if (h->old || h->read)
    {
      fputs ("Status: ", out);
      if (h->read)
	fputs ("RO", out);
      else if (h->old)
	fputc ('O', out);
      fputc ('\n', out);
    }

    if (h->flagged || h->replied)
    {
      fputs ("X-Status: ", out);
      if (h->replied)
	fputc ('A', out);
      if (h->flagged)
	fputc ('F', out);
      fputc ('\n', out);
    }
  }

  if (flags & CH_UPDATE_LEN &&
      (flags & CH_NOLEN) == 0)
  {
    fprintf (out, "Content-Length: " OFF_T_FMT "\n", h->content->length);
    if (h->lines != 0 || h->content->length == 0)
      fprintf (out, "Lines: %d\n", h->lines);
  }

  if ((flags & CH_NONEWLINE) == 0)
  {
    if (flags & CH_PREFIX)
      fputs(prefix, out);
    fputc ('\n', out); /* add header terminator */
  }

  if (ferror (out) || feof (out))
    return -1;
  
  return 0;
}
Ejemplo n.º 3
0
long smtp_mail (SENDSTREAM *stream,char *type,ENVELOPE *env,BODY *body)
{
  RFC822BUFFER buf;
  char tmp[SENDBUFLEN+1];
  long error = NIL;
  long retry = NIL;
  buf.f = smtp_soutr;		/* initialize buffer */
  buf.s = stream->netstream;
  buf.end = (buf.beg = buf.cur = tmp) + SENDBUFLEN;
  tmp[SENDBUFLEN] = '\0';	/* must have additional null guard byte */
  if (!(env->to || env->cc || env->bcc)) {
  				/* no recipients in request */
    smtp_seterror (stream,SMTPHARDERROR,"No recipients specified");
    return NIL;
  }
  do {				/* make sure stream is in good shape */
    if (retry) {		/* need to retry with authentication? */
      NETMBX mb;
				/* yes, build remote name for authentication */
      sprintf (tmp,"{%.200s/smtp%s}<none>",
	       (long) mail_parameters (NIL,GET_TRUSTDNS,NIL) ?
	       ((long) mail_parameters (NIL,GET_SASLUSESPTRNAME,NIL) ?
		net_remotehost (stream->netstream) :
		net_host (stream->netstream)) :
	       stream->host,
	       (stream->netstream->dtb ==
		(NETDRIVER *) mail_parameters (NIL,GET_SSLDRIVER,NIL)) ?
	       "/ssl" : "");
      mail_valid_net_parse (tmp,&mb);
      smtp_send (stream,"RSET",NIL);
      if (!smtp_auth (stream,&mb,tmp)) return NIL;
      retry = NIL;		/* no retry at this point */
    }

    strcpy (tmp,"FROM:<");	/* compose "MAIL FROM:<return-path>" */
#ifdef RFC2821
    if (env->return_path && env->return_path->host &&
	!((strlen (env->return_path->mailbox) > SMTPMAXLOCALPART) ||
	  (strlen (env->return_path->host) > SMTPMAXDOMAIN))) {
      rfc822_cat (tmp,env->return_path->mailbox,NIL);
      sprintf (tmp + strlen (tmp),"@%s",env->return_path->host);
    }
#else				/* old code with A-D-L support */
    if (env->return_path && env->return_path->host &&
	!((env->return_path->adl &&
	   (strlen (env->return_path->adl) > SMTPMAXPATH)) ||
	  (strlen (env->return_path->mailbox) > SMTPMAXLOCALPART) ||
	  (strlen (env->return_path->host) > SMTPMAXDOMAIN)))
      rfc822_address (tmp,env->return_path);
#endif
    strcat (tmp,">");
    if (ESMTP.ok) {
      if (ESMTP.eightbit.ok && ESMTP.eightbit.want)
	strcat (tmp," BODY=8BITMIME");
      if (ESMTP.dsn.ok && ESMTP.dsn.want) {
	strcat (tmp,ESMTP.dsn.full ? " RET=FULL" : " RET=HDRS");
	if (ESMTP.dsn.envid)
	  sprintf (tmp + strlen (tmp)," ENVID=%.100s",ESMTP.dsn.envid);
      }
    }
				/* send "MAIL FROM" command */
    switch (smtp_send (stream,type,tmp)) {
    case SMTPUNAVAIL:		/* mailbox unavailable? */
    case SMTPWANTAUTH:		/* wants authentication? */
    case SMTPWANTAUTH2:
      if (ESMTP.auth) retry = T;/* yes, retry with authentication */
    case SMTPOK:		/* looks good */
      break;
    default:			/* other failure */
      smtp_send (stream,"RSET",NIL);
      return NIL;
    }
				/* negotiate the recipients */
    if (!retry && env->to) retry = smtp_rcpt (stream,env->to,&error);
    if (!retry && env->cc) retry = smtp_rcpt (stream,env->cc,&error);
    if (!retry && env->bcc) retry = smtp_rcpt (stream,env->bcc,&error);
    if (!retry && error) {	/* any recipients failed? */
      smtp_send (stream,"RSET",NIL);
      smtp_seterror (stream,SMTPHARDERROR,"One or more recipients failed");
      return NIL;
    }
  } while (retry);
				/* negotiate data command */
  if (!(smtp_send (stream,"DATA",NIL) == SMTPREADY)) {
    smtp_send (stream,"RSET",NIL);
    return NIL;
  }
				/* send message data */
  if (!rfc822_output_full (&buf,env,body,
			   ESMTP.eightbit.ok && ESMTP.eightbit.want)) {
    smtp_fake (stream,"SMTP connection broken (message data)");
    return NIL;			/* can't do much else here */
  }
				/* send trailing dot */
  if (smtp_send (stream,".",NIL) != SMTPOK) {
    smtp_send (stream,"RSET",NIL);
    return NIL;
  }
  return LONGT;
}