⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sendlib.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (waitpid (pid, &st, 0) > 0)    {      st = WIFEXITED (st) ? WEXITSTATUS (st) : S_ERR;      if (SendmailWait && st == (0xff & EX_OK))      {	unlink (*tempfile); /* no longer needed */	FREE (tempfile);		/* __FREE_CHECKED__ */      }    }    else    {      st = (SendmailWait > 0 && errno == EINTR && SigAlrm) ?	      S_BKG : S_ERR;      if (SendmailWait > 0)      {	unlink (*tempfile);	FREE (tempfile);		/* __FREE_CHECKED__ */      }    }    /* reset alarm; not really needed, but... */    alarm (0);    sigaction (SIGALRM, &oldalrm, NULL);    if (kill (ppid, 0) == -1 && errno == ESRCH)    {      /* the parent is already dead */      unlink (*tempfile);      FREE (tempfile);		/* __FREE_CHECKED__ */    }    _exit (st);  }  sigprocmask (SIG_UNBLOCK, &set, NULL);  if (pid != -1 && waitpid (pid, &st, 0) > 0)    st = WIFEXITED (st) ? WEXITSTATUS (st) : S_ERR; /* return child status */  else    st = S_ERR;	/* error */  mutt_unblock_signals_system (1);  return (st);}static char **add_args (char **args, size_t *argslen, size_t *argsmax, ADDRESS *addr){  for (; addr; addr = addr->next)  {    /* weed out group mailboxes, since those are for display only */    if (addr->mailbox && !addr->group)    {      if (*argslen == *argsmax)	safe_realloc (&args, (*argsmax += 5) * sizeof (char *));      args[(*argslen)++] = addr->mailbox;    }  }  return (args);}static char **add_option (char **args, size_t *argslen, size_t *argsmax, char *s){  if (*argslen == *argsmax)    safe_realloc (&args, (*argsmax += 5) * sizeof (char *));  args[(*argslen)++] = s;  return (args);}intmutt_invoke_sendmail (ADDRESS *from,	/* the sender */		 ADDRESS *to, ADDRESS *cc, ADDRESS *bcc, /* recips */		 const char *msg, /* file containing message */		 int eightbit) /* message contains 8bit chars */{  char *ps = NULL, *path = NULL, *s = safe_strdup (Sendmail), *childout = NULL;  char **args = NULL;  size_t argslen = 0, argsmax = 0;  int i;  ps = s;  i = 0;  while ((ps = strtok (ps, " ")))  {    if (argslen == argsmax)      safe_realloc (&args, sizeof (char *) * (argsmax += 5));    if (i)      args[argslen++] = ps;    else    {      path = safe_strdup (ps);      ps = strrchr (ps, '/');      if (ps)	ps++;      else	ps = path;      args[argslen++] = ps;    }    ps = NULL;    i++;  }  if (eightbit && option (OPTUSE8BITMIME))    args = add_option (args, &argslen, &argsmax, "-B8BITMIME");  if (option (OPTENVFROM))  {    if (EnvFrom)    {      args = add_option (args, &argslen, &argsmax, "-f");      args = add_args   (args, &argslen, &argsmax, EnvFrom);    }    else if (from && !from->next)    {      args = add_option (args, &argslen, &argsmax, "-f");      args = add_args   (args, &argslen, &argsmax, from);    }  }  if (DsnNotify)  {    args = add_option (args, &argslen, &argsmax, "-N");    args = add_option (args, &argslen, &argsmax, DsnNotify);  }  if (DsnReturn)  {    args = add_option (args, &argslen, &argsmax, "-R");    args = add_option (args, &argslen, &argsmax, DsnReturn);  }  args = add_option (args, &argslen, &argsmax, "--");  args = add_args (args, &argslen, &argsmax, to);  args = add_args (args, &argslen, &argsmax, cc);  args = add_args (args, &argslen, &argsmax, bcc);  if (argslen == argsmax)    safe_realloc (&args, sizeof (char *) * (++argsmax));    args[argslen++] = NULL;  if ((i = send_msg (path, args, msg, &childout)) != (EX_OK & 0xff))  {    if (i != S_BKG)    {      const char *e = mutt_strsysexit (i);      e = mutt_strsysexit (i);      mutt_error (_("Error sending message, child exited %d (%s)."), i, NONULL (e));      if (childout)      {	struct stat st;		if (stat (childout, &st) == 0 && st.st_size > 0)	  mutt_do_pager (_("Output of the delivery process"), childout, 0, NULL);      }    }  }  else    unlink (childout);  FREE (&childout);  FREE (&path);  FREE (&s);  FREE (&args);  if (i == (EX_OK & 0xff))    i = 0;  else if (i == S_BKG)    i = 1;  else    i = -1;  return (i);}/* appends string 'b' to string 'a', and returns the pointer to the new   string. */char *mutt_append_string (char *a, const char *b){  size_t la = mutt_strlen (a);  safe_realloc (&a, la + mutt_strlen (b) + 1);  strcpy (a + la, b);	/* __STRCPY_CHECKED__ */  return (a);}/* returns 1 if char `c' needs to be quoted to protect from shell   interpretation when executing commands in a subshell */#define INVALID_CHAR(c) (!isalnum ((unsigned char)c) && !strchr ("@.+-_,:", c))/* returns 1 if string `s' contains characters which could cause problems   when used on a command line to execute a command */int mutt_needs_quote (const char *s){  while (*s)  {    if (INVALID_CHAR (*s))      return 1;    s++;  }  return 0;}/* Quote a string to prevent shell escapes when this string is used on the   command line to send mail. */char *mutt_quote_string (const char *s){  char *r, *pr;  size_t rlen;  rlen = mutt_strlen (s) + 3;  pr = r = (char *) safe_malloc (rlen);  *pr++ = '"';  while (*s)  {    if (INVALID_CHAR (*s))    {      size_t o = pr - r;      safe_realloc (&r, ++rlen);      pr = r + o;      *pr++ = '\\';    }    *pr++ = *s++;  }  *pr++ = '"';  *pr = 0;  return (r);}/* For postponing (!final) do the necessary encodings only */void mutt_prepare_envelope (ENVELOPE *env, int final){  char buffer[LONG_STRING];  if (final)  {    if (env->bcc && !(env->to || env->cc))    {      /* some MTA's will put an Apparently-To: header field showing the Bcc:       * recipients if there is no To: or Cc: field, so attempt to suppress       * it by using an empty To: field.       */      env->to = rfc822_new_address ();      env->to->group = 1;      env->to->next = rfc822_new_address ();      buffer[0] = 0;      rfc822_cat (buffer, sizeof (buffer), "undisclosed-recipients",		  RFC822Specials);      env->to->mailbox = safe_strdup (buffer);    }    mutt_set_followup_to (env);    if (!env->message_id)      env->message_id = mutt_gen_msgid ();  }  /* Take care of 8-bit => 7-bit conversion. */  rfc2047_encode_adrlist (env->to, "To");  rfc2047_encode_adrlist (env->cc, "Cc");  rfc2047_encode_adrlist (env->bcc, "Bcc");  rfc2047_encode_adrlist (env->from, "From");  rfc2047_encode_adrlist (env->mail_followup_to, "Mail-Followup-To");  rfc2047_encode_adrlist (env->reply_to, "Reply-To");  if (env->subject)  {    rfc2047_encode_string (&env->subject);  }  encode_headers (env->userhdrs);}void mutt_unprepare_envelope (ENVELOPE *env){  LIST *item;  for (item = env->userhdrs; item; item = item->next)    rfc2047_decode (&item->data);  rfc822_free_address (&env->mail_followup_to);  /* back conversions */  rfc2047_decode_adrlist (env->to);  rfc2047_decode_adrlist (env->cc);  rfc2047_decode_adrlist (env->bcc);  rfc2047_decode_adrlist (env->from);  rfc2047_decode_adrlist (env->reply_to);  rfc2047_decode (&env->subject);}static int _mutt_bounce_message (FILE *fp, HEADER *h, ADDRESS *to, const char *resent_from,				  ADDRESS *env_from){  int i, ret = 0;  FILE *f;  char date[SHORT_STRING], tempfile[_POSIX_PATH_MAX];  MESSAGE *msg = NULL;  if (!h)  {	  /* Try to bounce each message out, aborting if we get any failures. */    for (i=0; i<Context->msgcount; i++)      if (Context->hdrs[i]->tagged)        ret |= _mutt_bounce_message (fp, Context->hdrs[i], to, resent_from, env_from);    return ret;  }  /* If we failed to open a message, return with error */  if (!fp && (msg = mx_open_message (Context, h->msgno)) == NULL)    return -1;  if (!fp) fp = msg->fp;  mutt_mktemp (tempfile);  if ((f = safe_fopen (tempfile, "w")) != NULL)  {    int ch_flags = CH_XMIT | CH_NONEWLINE | CH_NOQFROM;        if (!option (OPTBOUNCEDELIVERED))      ch_flags |= CH_WEED_DELIVERED;        fseeko (fp, h->offset, 0);    fprintf (f, "Resent-From: %s", resent_from);    fprintf (f, "\nResent-%s", mutt_make_date (date, sizeof(date)));    fprintf (f, "Resent-Message-ID: %s\n", mutt_gen_msgid());    fputs ("Resent-To: ", f);    mutt_write_address_list (to, f, 11, 0);    mutt_copy_header (fp, h, f, ch_flags, NULL);    fputc ('\n', f);    mutt_copy_bytes (fp, f, h->content->length);    fclose (f);    ret = mutt_invoke_sendmail (env_from, to, NULL, NULL, tempfile,			  	h->content->encoding == ENC8BIT);  }  if (msg)    mx_close_message (&msg);  return ret;}int mutt_bounce_message (FILE *fp, HEADER *h, ADDRESS *to){  ADDRESS *from;  const char *fqdn = mutt_fqdn (1);  char resent_from[STRING];  int ret;  char *err;    resent_from[0] = '\0';  from = mutt_default_from ();  if (fqdn)    rfc822_qualify (from, fqdn);  rfc2047_encode_adrlist (from, "Resent-From");  if (mutt_addrlist_to_idna (from, &err))  {    mutt_error (_("Bad IDN %s while preparing resent-from."),		err);    return -1;  }  rfc822_write_address (resent_from, sizeof (resent_from), from, 0);  ret = _mutt_bounce_message (fp, h, to, resent_from, from);  rfc822_free_address (&from);  return ret;}/* given a list of addresses, return a list of unique addresses */ADDRESS *mutt_remove_duplicates (ADDRESS *addr){  ADDRESS *top = addr;  ADDRESS **last = &top;  ADDRESS *tmp;  int dup;  while (addr)  {    for (tmp = top, dup = 0; tmp && tmp != addr; tmp = tmp->next)    {      if (tmp->mailbox && addr->mailbox && 	  !ascii_strcasecmp (addr->mailbox, tmp->mailbox))      {	dup = 1;	break;      }    }        if (dup)    {      dprint (2, (debugfile, "mutt_remove_duplicates: Removing %s\n",		  addr->mailbox));            *last = addr->next;      addr->next = NULL;      rfc822_free_address(&addr);            addr = *last;    }    else     {      last = &addr->next;      addr = addr->next;    }  }    return (top);}static void set_noconv_flags (BODY *b, short flag){  for(; b; b = b->next)  {    if (b->type == TYPEMESSAGE || b->type == TYPEMULTIPART)      set_noconv_flags (b->parts, flag);    else if (b->type == TYPETEXT && b->noconv)    {      if (flag)	mutt_set_parameter ("x-mutt-noconv", "yes", &b->parameter);      else	mutt_delete_parameter ("x-mutt-noconv", &b->parameter);    }  }}int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int post, char *fcc){  CONTEXT f;  MESSAGE *msg;  char tempfile[_POSIX_PATH_MAX];  FILE *tempfp = NULL;  int r;  if (post)    set_noconv_flags (hdr->content, 1);    if (mx_open_mailbox (path, M_APPEND | M_QUIET, &f) == NULL)  {    dprint (1, (debugfile, "mutt_write_fcc(): unable to open mailbox %s in append-mode, aborting.\n",		path));    return (-1);  }  /* We need to add a Content-Length field to avoid problems where a line in   * the message body begins with "From "      */  if (f.magic == M_MMDF || f.magic == M_MBOX)  {    mutt_mktemp (tempfile);    if ((tempfp = safe_fopen (tempfile, "w+")) == NULL)    {      mutt_perror (tempfile);      mx_close_mailbox (&f, NULL);      return (-1);    }  }  hdr->read = !post; /* make sure to put it in the `cur' directory (maildir) */  if ((msg = mx_open_new_message (&f, hdr, M_ADD_FROM)) == NULL)  {    mx_close_mailbox (&f, NULL);    return (-1);  }  /* post == 1 => postpone message. Set mode = -1 in mutt_write_rfc822_header()   * post == 0 => Normal mode. Set mode = 0 in mutt_write_rfc822_header()    * */  mutt_write_rfc822_header (msg->fp, hdr->env, hdr->content, post ? -post : 0, 0);  /* (postponment) if this was a reply of some sort, <msgid> contians the   * Message-ID: of message replied to.  Save it using a special X-Mutt-   * header so it can be picked up if the message is recalled at a later   * point in time.  This will allow the message to be marked as replied if   * the same mailbox is still open.   */  if (post && msgid)    fprintf (msg->fp, "X-Mutt-References: %s\n", msgid);    /* (postponment) save the Fcc: using a special X-Mutt- header so that   * it can be picked up when the message is recalled    */  if (post && fcc)    fprintf (msg->fp, "X-Mutt-Fcc: %s\n", fcc);  fprintf (msg->fp, "Status: RO\n");  /* (postponment) if the mail is to be signed or encrypted, save this info */  if ((WithCrypto & APPLICATION_PGP)      && post && (hdr->security & APPLICATION_PGP))  {    fputs ("X-Mutt-PGP: ", msg->fp);    if (hdr->security & ENCRYPT)       fputc ('E', msg->fp);    if (hdr->security & SIGN)    {      fputc ('S', msg->fp);      if (PgpSignAs && *PgpSignAs)        fprintf (msg->fp, "<%s>", PgpSignAs);    }    if (hdr->security & INLINE)      fputc ('I', msg->fp);    fputc ('\n', msg->fp);  }  /* (postponment) if the mail is to be signed or encrypted, save this info */  if ((WithCrypto & APPLICATION_SMIME)      && post && (hdr->security & APPLICATION_SMIME))  {    fputs ("X-Mutt-SMIME: ", msg->fp);    if (hdr->security & ENCRYPT) {	fputc ('E', msg->fp);	if (SmimeCryptAlg && *SmimeCryptAlg)	    fprintf (msg->fp, "C<%s>", SmimeCryptAlg);    }    if (hdr->security & SIGN) {	fputc ('S', msg->fp);	if (SmimeDefaultKey && *SmimeDefaultKey)	    fprintf (msg->fp, "<%s>", SmimeDefaultKey);    }    if (hdr->security & INLINE)      fputc ('I', msg->fp);    fputc ('\n', msg->fp);  }#ifdef MIXMASTER  /* (postponement) if the mail is to be sent through a mixmaster    * chain, save that information   */    if (post && hdr->chain && hdr->chain)  {    LIST *p;    fputs ("X-Mutt-Mix:", msg->fp);    for (p = hdr->chain; p; p = p->next)      fprintf (msg->fp, " %s", (char *) p->data);        fputc ('\n', msg->fp);  }#endif      if (tempfp)  {    char sasha[LONG_STRING];    int lines = 0;    mutt_write_mime_body (hdr->content, tempfp);    /* make sure the last line ends with a newline.  Emacs doesn't ensure     * this will happen, and it can cause problems parsing the mailbox        * later.     */    fseek (tempfp, -1, 2);    if (fgetc (tempfp) != '\n')    {      fseek (tempfp, 0, 2);      fputc ('\n', tempfp);    }    fflush (tempfp);    if (ferror (tempfp))    {      dprint (1, (debugfile, "mutt_write_fcc(): %s: write failed.\n", tempfile));      fclose (tempfp);      unlink (tempfile);      mx_commit_message (msg, &f);	/* XXX - really? */      mx_close_message (&msg);      mx_close_mailbox (&f, NULL);      return -1;    }    /* count the number of lines */    rewind (tempfp);    while (fgets (sasha, sizeof (sasha), tempfp) != NULL)      lines++;    fprintf (msg->fp, "Content-Length: " OFF_T_FMT "\n", ftello (tempfp));    fprintf (msg->fp, "Lines: %d\n\n", lines);    /* copy the body and clean up */    rewind (tempfp);    r = mutt_copy_stream (tempfp, msg->fp);    if (fclose (tempfp) != 0)      r = -1;    /* if there was an error, leave the temp version */    if (!r)      unlink (tempfile);  }  else  {    fputc ('\n', msg->fp); /* finish off the header */    r = mutt_write_mime_body (hdr->content, msg->fp);  }  if (mx_commit_message (msg, &f) != 0)    r = -1;  mx_close_message (&msg);  mx_close_mailbox (&f, NULL);  if (post)    set_noconv_flags (hdr->content, 0);    return r;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -