示例#1
0
static int
_attachment_setup (mu_mime_io_buffer_t *pinfo, mu_message_t msg,
		   mu_stream_t *pstream)
{
  int ret;
  mu_body_t body;
  mu_mime_io_buffer_t info;
  mu_stream_t stream;
    
  if ((ret = mu_message_get_body (msg, &body)) != 0 ||
      (ret = mu_body_get_streamref (body, &stream)) != 0)
    return ret;
  *pstream = stream;
  if (*pinfo)
    {
      info = *pinfo;
      info->refcnt++;
    }
  else
    {
      ret = mu_mime_io_buffer_create (&info);
      if (ret)
	return ret;
    }
  
  *pinfo = info;
  return 0;
}
示例#2
0
int
moderator_message_get_part (mu_sieve_machine_t mach,
			    mu_message_t msg, size_t index, mu_message_t *pmsg)
{
  int rc;
  mu_message_t tmp;
  mu_header_t hdr = NULL;
  const char *value;

  if ((rc = mu_message_get_part (msg, index, &tmp)))
    {
      mu_sieve_error (mach, _("cannot get message part #%lu: %s"),
		      (unsigned long) index, mu_strerror (rc));
      return 1;
    }
  
  mu_message_get_header (tmp, &hdr);
  if (mu_header_sget_value (hdr, MU_HEADER_CONTENT_TYPE, &value) == 0
      && memcmp (value, "message/rfc822", 14) == 0)
    {
      mu_stream_t str;
      mu_body_t body;

      mu_message_get_body (tmp, &body);
      mu_body_get_streamref (body, &str);

      rc = mu_stream_to_message (str, pmsg);
      mu_stream_destroy (&str);
      if (rc)
	{
	  mu_sieve_error (mach,
			  _("cannot convert MIME part stream to message: %s"),
			  mu_strerror (rc));
	  return 1;
	}
    }
  else if (value)
    {
      mu_sieve_error (mach,
		      _("expected message type message/rfc822, but found %s"),
		      value);
      return 1;
    }
  else
    {
      mu_sieve_error (mach, _("no Content-Type header found"));
      return 1;
    }
  return 0;
}
示例#3
0
/* Build a mime response message from original message MSG. TEXT
   is the message text.
*/
static int
build_mime (mu_sieve_machine_t mach, mu_list_t tags, mu_mime_t *pmime,
	    mu_message_t msg, const char *text)
{
  mu_mime_t mime = NULL;
  mu_message_t newmsg;
  mu_stream_t stream, input;
  mu_header_t hdr;
  mu_body_t body;
  const char *header =
    "Content-Type: text/plain;charset=" MU_SIEVE_CHARSET "\n"
    "Content-Transfer-Encoding: 8bit\n\n";
  int rc;
  
  mu_mime_create (&mime, NULL, 0);
  mu_message_create (&newmsg, NULL);
  mu_message_get_body (newmsg, &body);

  if ((rc = mu_static_memory_stream_create (&input, text, strlen (text))))
    {
      mu_sieve_error (mach,
		      _("cannot create temporary stream: %s"),
		      mu_strerror (rc));
      mu_mime_destroy (&mime);
      mu_message_destroy (&newmsg, NULL);
      return 1;
    }

  if (mu_sieve_tag_lookup (tags, "mime", NULL))
    {
      mu_stream_t fstr;
      rc = mu_filter_create (&fstr, input, "base64",
			     MU_FILTER_ENCODE, 
			     MU_STREAM_READ);
      mu_stream_unref (input); 
      if (rc == 0) 
	{
	  header = "Content-Type: text/plain;charset=" MU_SIEVE_CHARSET "\n"
	           "Content-Transfer-Encoding: base64\n\n";
	  input = fstr;
	}
    }

  rc = mu_body_get_streamref (body, &stream);
  if (rc)
    {
      mu_sieve_error (mach,
		      _("cannot get input body stream: %s"),
		      mu_strerror (rc));
      mu_mime_destroy (&mime);
      mu_message_destroy (&newmsg, NULL);
      mu_stream_destroy (&input);
      return 1;
    }

  rc = mu_stream_copy (stream, input, 0, NULL);
  if (rc)
    {
      mu_sieve_error (mach,
		      _("stream copy failed: %s"),
		      mu_strerror (rc));
      mu_mime_destroy (&mime);
      mu_message_destroy (&newmsg, NULL);
      mu_stream_destroy (&input);
      mu_stream_destroy (&stream);
      return 1;
    }

  mu_stream_destroy (&input);
  
  mu_header_create (&hdr, header, strlen (header));
  mu_message_set_header (newmsg, hdr, NULL);

  mu_mime_add_part (mime, newmsg);
  mu_message_unref (newmsg);

  *pmime = mime;

  return 0;
}
示例#4
0
int
main (int argc, char **argv)
{
  int i;
  char *host = NULL;
  char *infile = NULL;
  char *port = NULL;
  int tls = 0;
  int raw = 1;
  int flags = 0;
  mu_stream_t stream;
  mu_smtp_t smtp;
  mu_stream_t instr;
  char *from = NULL;
  mu_list_t rcpt_list = NULL;
  mu_list_t meth_list = NULL;
  mu_list_t skiphdr_list = NULL;
  struct mu_sockaddr *sa;
  struct mu_sockaddr_hints hints;
  
  mu_set_program_name (argv[0]);
  mu_stdstream_setup (MU_STDSTREAM_RESET_NONE);
  
  if (argc < 2)
    usage ();

  memset (&hints, 0, sizeof (hints)); 
  hints.flags = MU_AH_DETECT_FAMILY;
  hints.port = 25;
  hints.protocol = IPPROTO_TCP;
  hints.socktype = SOCK_STREAM;

  MU_ASSERT (mu_smtp_create (&smtp));

  for (i = 1; i < argc; i++)
    {
      if (strncmp (argv[i], "port=", 5) == 0)
	port = argv[i] + 5;
      else if (strncmp (argv[i], "family=", 7) == 0)
	{
	  hints.flags &= ~MU_AH_DETECT_FAMILY;
	  switch (argv[i][7])
	    {
	    case '4':
	      hints.family = AF_INET;
	      break;
	    case '6':
	      hints.family = AF_INET6;
	      break;
	    default:
	      mu_error ("invalid family name: %s", argv[i]+7);
	      exit (1);
	    }
	}
      else if (strncmp (argv[i], "trace=", 6) == 0)
	{
	  char *arg = argv[i] + 6;

	  if (mu_isdigit (arg[0]))
	    mu_smtp_trace (smtp, atoi (argv[i] + 6) ?
			   MU_SMTP_TRACE_SET : MU_SMTP_TRACE_CLR);
	  else
	    {
	      mu_smtp_trace (smtp, MU_SMTP_TRACE_SET);
	      if (strcmp (arg, "secure") == 0)
		mu_smtp_trace_mask (smtp, MU_SMTP_TRACE_SET,
				    MU_XSCRIPT_SECURE);
	      else if (strcmp (arg, "payload") == 0)
		mu_smtp_trace_mask (smtp, MU_SMTP_TRACE_SET,
				    MU_XSCRIPT_PAYLOAD);
	    }
	}
      else if (strncmp (argv[i], "tls=", 4) == 0)
	tls = atoi (argv[i] + 4);
      else if (strncmp (argv[i], "domain=", 7) == 0)
	MU_ASSERT (mu_smtp_set_param (smtp, MU_SMTP_PARAM_DOMAIN,
				      argv[i] + 7));
      else if (strncmp (argv[i], "user="******"pass="******"service=", 8) == 0)
	MU_ASSERT (mu_smtp_set_param (smtp, MU_SMTP_PARAM_SERVICE,
				      argv[i] + 8));
      else if (strncmp (argv[i], "realm=", 6) == 0)
	MU_ASSERT (mu_smtp_set_param (smtp, MU_SMTP_PARAM_REALM,
				      argv[i] + 6));
      else if (strncmp (argv[i], "host=", 5) == 0)
	MU_ASSERT (mu_smtp_set_param (smtp, MU_SMTP_PARAM_HOST,
				      argv[i] + 5));
      else if (strncmp (argv[i], "url=", 4) == 0)
	MU_ASSERT (mu_smtp_set_param (smtp, MU_SMTP_PARAM_URL,
				      argv[i] + 4));
      else if (strncmp (argv[i], "input=", 6) == 0)
	infile = argv[i] + 6;
      else if (strncmp (argv[i], "raw=", 4) == 0)
	raw = atoi (argv[i] + 4);
      else if (strncmp (argv[i], "rcpt=", 5) == 0)
	{
	  if (!rcpt_list)
	    MU_ASSERT (mu_list_create (&rcpt_list));
	  MU_ASSERT (mu_list_append (rcpt_list, argv[i] + 5));
	}
      else if (strncmp (argv[i], "from=", 5) == 0)
	from = argv[i] + 5;
      else if (strncmp (argv[i], "auth=", 5) == 0)
	update_list (&meth_list, argv[i] + 5);
      else if (strncmp (argv[i], "skiphdr=", 8) == 0)
	{
	  update_list (&skiphdr_list, argv[i] + 8);
	  raw = 0;
	}
      else if (host)
	{
	  mu_error ("server name already given: %s, new name %s?",
		    host, argv[i]);
	  exit (1);
	}
      else
	host = argv[i];
    }

  if (!host)
    usage ();

  if (!raw)
    flags = MU_STREAM_SEEK;
  if (infile)
    MU_ASSERT (mu_file_stream_create (&instr, infile, MU_STREAM_READ|flags));
  else
    MU_ASSERT (mu_stdio_stream_create (&instr, MU_STDIN_FD, flags));
  
  host = argv[1];

  MU_ASSERT (mu_sockaddr_from_node (&sa, host, port, &hints));

  MU_ASSERT (mu_tcp_stream_create_from_sa (&stream, sa, NULL, MU_STREAM_RDWR));
  
  mu_smtp_set_carrier (smtp, stream);
  mu_stream_unref (stream);
  
  if (!from)
    {
      from = getenv ("USER");
      if (!from)
	{
	  mu_error ("cannot determine sender name");
	  exit (1);
	}
    }

  if (raw && !rcpt_list)
    {
      mu_error ("no recipients");
      exit (1);
    }
  
  MU_ASSERT (mu_smtp_open (smtp));
  MU_ASSERT (mu_smtp_ehlo (smtp));

  if (tls && mu_smtp_capa_test (smtp, "STARTTLS", NULL) == 0)
    {
      MU_ASSERT (mu_smtp_starttls (smtp));
      MU_ASSERT (mu_smtp_ehlo (smtp));
    }

  if (meth_list)
    {
      int status;
      
      MU_ASSERT (mu_smtp_add_auth_mech_list (smtp, meth_list));
      status = mu_smtp_auth (smtp);
      switch (status)
	{
	case 0:
	  MU_ASSERT (mu_smtp_ehlo (smtp));
	  break;
	  
	case ENOSYS:
	case MU_ERR_NOENT:
	  /* Ok, skip it */
	  break;

	default:
	  mu_error ("authentication failed: %s", mu_strerror (status));
	  exit (1);
	}
    }
  
  MU_ASSERT (mu_smtp_mail_basic (smtp, from, NULL));
  mu_list_foreach (rcpt_list, send_rcpt_command, smtp);
  
  if (raw)
    {
      /* Raw sending mode: send from the stream directly */
      MU_ASSERT (mu_smtp_send_stream (smtp, instr));
    }
  else
    {
      /* Message (standard) sending mode: send a MU message. */

      mu_message_t msg;
      mu_stream_t ostr, bstr;
      mu_header_t hdr;
      mu_iterator_t itr;
      mu_body_t body;

      if (skiphdr_list)
	mu_list_set_comparator (skiphdr_list, headercmp);
      
      MU_ASSERT (mu_stream_to_message (instr, &msg));
      mu_stream_unref (instr);
      MU_ASSERT (mu_smtp_data (smtp, &ostr));
      MU_ASSERT (mu_message_get_header (msg, &hdr));
      MU_ASSERT (mu_header_get_iterator (hdr, &itr));
      for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
	   mu_iterator_next (itr))
	{
	  const char *name;
	  void *value;

	  mu_iterator_current_kv (itr, (void*) &name, &value);
	  if (mu_list_locate (skiphdr_list, (void*) name, NULL) == 0)
	    continue;

	  mu_stream_printf (ostr, "%s: %s\n", name, (char*)value);
	}
      mu_iterator_destroy (&itr);
      MU_ASSERT (mu_stream_write (ostr, "\n", 1, NULL));
      
      MU_ASSERT (mu_message_get_body (msg, &body));
      MU_ASSERT (mu_body_get_streamref (body, &bstr));
      MU_ASSERT (mu_stream_copy (ostr, bstr, 0, NULL));
      mu_stream_destroy (&bstr);
      mu_stream_close (ostr);
      mu_stream_destroy (&ostr);
    }
  MU_ASSERT (mu_smtp_dot (smtp));
  MU_ASSERT (mu_smtp_quit (smtp));
  
  mu_smtp_destroy (&smtp);
  mu_stream_close (instr);
  mu_stream_destroy (&instr);
  return 0;
}
示例#5
0
oo\n\
";

int
main (int argc, char **argv)
{
  int i;
  char *p;
  mu_message_t msg;
  mu_stream_t stream = NULL;
  mu_header_t hdr;
  mu_body_t body;
  
  mu_set_program_name (argv[0]);

  mu_static_memory_stream_create (&stream, text, strlen (text));
  assert (mu_stream_to_message (stream, &msg) == 0);
  mu_stream_unref (stream);
  assert (mu_message_get_header (msg, &hdr) == 0);
  assert (mu_message_get_body (msg, &body) == 0);
  assert (mu_body_get_streamref (body, &stream) == 0);
  assert (mu_stream_seek (stream, 0, MU_SEEK_END, NULL) == 0);
  
  for (i = 1; i < argc; i++)
    {
      if (strcmp (argv[i], "-h") == 0)
	{
	  mu_printf ("usage: %s [-a HDR:VAL] [-t TEXT]\n", mu_program_name);
	  return 0;
	}
      
      if (strcmp (argv[i], "-a") == 0)
	{
	  i++;
	  assert (argv[i] != NULL);
	  p = strchr (argv[i], ':');
	  assert (p != NULL);
	  *p++ = 0;
	  while (*p && mu_isspace (*p))
	    p++;
	  assert (mu_header_set_value (hdr, argv[i], p, 1) == 0);
	}
      else if (strcmp (argv[i], "-l") == 0)
	{
	  mu_off_t off;
	  int whence = MU_SEEK_SET;
	  
	  i++;
	  assert (argv[i] != NULL);
	  off = strtol (argv[i], &p, 10);
	  assert (*p == 0);
	  if (off < 0)
	    whence = MU_SEEK_END;
	  assert (mu_stream_seek (stream, off, whence, NULL) == 0);
	}
      else if (strcmp (argv[i], "-t") == 0)
	{
	  mu_wordsplit_t ws;
	  i++;
	  assert (argv[i] != NULL);

	  if (mu_wordsplit (argv[i], &ws,
			    MU_WRDSF_NOSPLIT | MU_WRDSF_DEFFLAGS))
	    {
	      mu_error ("mu_wordsplit: %s", mu_wordsplit_strerror (&ws));
	      exit (1);
	    }
	  else
	    assert (mu_stream_write (stream, ws.ws_wordv[0],
				     strlen (ws.ws_wordv[0]), NULL) == 0);
	  mu_wordsplit_free (&ws);
	}
      else
	mu_error ("ignoring unknown argument %s", argv[i]);
    }
  mu_stream_unref (stream);

  assert (mu_message_get_streamref (msg, &stream) == 0);
  assert (mu_stream_copy (mu_strout, stream, 0, NULL) == 0);
  mu_stream_unref (stream);

  return 0;
}
示例#6
0
int
mu_message_create_attachment (const char *content_type, const char *encoding,
			      const char *filename, mu_message_t *newmsg)
{
  mu_header_t hdr;
  mu_body_t body;
  mu_stream_t fstream = NULL, tstream = NULL;
  char *header = NULL, *name = NULL, *fname = NULL;
  int ret;

  if (newmsg == NULL)
    return MU_ERR_OUT_PTR_NULL;
  if (filename == NULL)
    return EINVAL;

  if ((ret = mu_message_create (newmsg, NULL)) == 0)
    {
      if (content_type == NULL)
	content_type = "text/plain";
      if (encoding == NULL)
	encoding = "7bit";
      if ((fname = strdup (filename)) != NULL)
	{
	  name = strrchr (fname, '/');
	  if (name)
	    name++;
	  else
	    name = fname;
	  ret = mu_asprintf (&header,
			     "Content-Type: %s; name=%s\n"
			     "Content-Transfer-Encoding: %s\n"
			     "Content-Disposition: attachment; filename=%s\n\n",
			     content_type, name, encoding, name);
	  if (ret == 0)
	    {
	      if ((ret = mu_header_create (&hdr, header,
					   strlen (header))) == 0)
		{
		  mu_stream_t bstr;
		  mu_message_get_body (*newmsg, &body);
		  mu_body_get_streamref (body, &bstr);
		  
		  if ((ret = mu_file_stream_create (&fstream, filename,
						    MU_STREAM_READ)) == 0)
		    {
		      if ((ret = mu_filter_create (&tstream, fstream, encoding,
						   MU_FILTER_ENCODE,
						   MU_STREAM_READ)) == 0)
			{
			  mu_stream_copy (bstr, tstream, 0, NULL);
			  mu_stream_unref (tstream);
			  mu_message_set_header (*newmsg, hdr, NULL);
			}
		    }
		  mu_stream_unref (bstr);
		  free (header);
		}
	    }
	}
    }
  
  if (ret)
    {
      if (*newmsg)
	mu_message_destroy (newmsg, NULL);
      if (hdr)
	mu_header_destroy (&hdr);
      if (fstream)
	mu_stream_destroy (&fstream);
      if (fname)
	free (fname);
    }
  return ret;
}
示例#7
0
int
main (int argc, char **argv)
{
  int index;
  int rc;
  mu_stream_t in, tmp;
  mu_message_t msg;
  mu_header_t hdr;
  mu_iterator_t itr;
  const char *file;
  char *newval;
  mu_off_t size;
  mu_body_t body;
  mu_stream_t bstr;
  
  MU_APP_INIT_NLS ();
  
  mh_argp_init ();
  mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
		 opt_handler, NULL, &index);

  if (index == argc)
    {
      mu_error (_("file name not given"));
      exit (1);
    }
  file = argv[index];

  prompter_init ();
  if (erase_seq)
    prompter_set_erase (erase_seq);
  if (kill_seq)
    prompter_set_erase (kill_seq);

  if ((rc = mu_stdio_stream_create (&strout, MU_STDOUT_FD, MU_STREAM_WRITE)))
    {
      mu_error (_("cannot open stdout: %s"), mu_strerror (rc));
      return 1;
    }
  
  if ((rc = mu_file_stream_create (&in, file, MU_STREAM_RDWR)))
    {
      mu_error (_("cannot open input file `%s': %s"),
		file, mu_strerror (rc));
      return 1;
    }
  rc = mu_stream_to_message (in, &msg);
  mu_stream_unref (in);
  if (rc)
    {
      mu_error (_("input stream %s is not a message (%s)"),
		file, mu_strerror (rc));
      return 1;
    }
  
  if ((rc = mu_temp_file_stream_create (&tmp, NULL, 0))) 
    {
      mu_error (_("Cannot open temporary file: %s"),
		mu_strerror (rc));
      return 1;
    }

  /* Copy headers */
  mu_message_get_header (msg, &hdr);
  mu_header_get_iterator (hdr, &itr);
  for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
       mu_iterator_next (itr))
    {
      const char *name, *val;
      
      mu_iterator_current_kv (itr, (const void **)&name, (void**)&val);
      if (!is_empty_string (val))
	{
	  mu_stream_printf (tmp, "%s: %s\n", name, val);
	  mu_stream_printf (strout, "%s: %s\n", name, val);
	}
      else
	{
	  int cont = 0;
	  mu_opool_t opool;
	  const char *prompt = name;
	  
	  mu_opool_create (&opool, 1);
	  do
	    {
	      size_t len;
	      char *p;
	      p = prompter_get_value (prompt);
	      if (!p)
		return 1;
	      prompt = NULL;
	      if (cont)
		{
		  mu_opool_append_char (opool, '\n');
		  if (!mu_isspace (p[0]))
		    mu_opool_append_char (opool, '\t');
		}
	      len = strlen (p);
	      if (len > 0 && p[len-1] == '\\')
		{
		  len--;
		  cont = 1;
		}
	      else
		cont = 0;
	      mu_opool_append (opool, p, len);
	      free (p);
	    }
	  while (cont);

	  mu_opool_append_char (opool, 0);
	  newval = mu_opool_finish (opool, NULL);
	  if (!is_empty_string (newval))
	    mu_stream_printf (tmp, "%s: %s\n", name, newval);
	  mu_opool_destroy (&opool);
	}
    }
  mu_iterator_destroy (&itr);
  mu_stream_printf (strout, "--------\n");
  mu_stream_write (tmp, "\n", 1, NULL);

  /* Copy body */
  
  if (prepend_option)
    {
      mu_stream_printf (strout, "\n--------%s\n\n", _("Enter initial text"));
      while ((newval = prompter_get_line ()))
	{
	  mu_stream_write (tmp, newval, strlen (newval), NULL);
	  free (newval);
	  mu_stream_write (tmp, "\n", 1, NULL);
	}
    }

  mu_message_get_body (msg, &body);
  mu_body_get_streamref (body, &bstr);

  if (!prepend_option && !rapid_option)
    {
      mu_stream_copy (strout, bstr, 0, NULL);
      mu_stream_seek (bstr, 0, MU_SEEK_SET, NULL);
    }

  mu_stream_copy (tmp, bstr, 0, NULL);
  mu_stream_unref (bstr);

  if (!prepend_option && !rapid_option)
    {
      printf ("\n--------%s\n\n", _("Enter additional text"));
      while ((newval = prompter_get_line ()))
	{
	  mu_stream_write (tmp, newval, strlen (newval), NULL);
	  free (newval);
	  mu_stream_write (tmp, "\n", 1, NULL);
	}
    }

  /* Destroy the message */
  mu_message_destroy (&msg, mu_message_get_owner (msg));

  /* Rewind the streams and copy data back to in. */
  mu_stream_seek (in, 0, MU_SEEK_SET, NULL);
  mu_stream_seek (tmp, 0, MU_SEEK_SET, NULL);
  mu_stream_copy (in, tmp, 0, &size);
  mu_stream_truncate (in, size);

  mu_stream_destroy (&in);
  mu_stream_destroy (&tmp);
  mu_stream_destroy (&strout);

  prompter_done ();
  
  return 0;
}
示例#8
0
void
message_display_parts (mu_message_t msg, int indent)
{
  int ret, j;
  size_t nparts;
  mu_message_t part;
  mu_header_t hdr;
  mu_stream_t str;
  mu_body_t body;
  int ismulti;
  size_t nbytes;

  /* How many parts does the message has? */
  if ((ret = mu_message_get_num_parts (msg, &nparts)) != 0)
    {
      fprintf (stderr, "mu_message_get_num_parts - %s\n", mu_strerror (ret));
      exit (2);
    }

  /* Iterate through all the parts.
     Treat type "message/rfc822" differently, since it is a message of
     its own that can have other subparts(recursive). */
  for (j = 1; j <= nparts; j++)
    {
      int status;
      const char *hvalue;
      char *type = NULL;
      const char *encoding = "";

      MU_ASSERT (mu_message_get_part (msg, j, &part));
      MU_ASSERT (mu_message_get_header (part, &hdr));
      status = mu_header_sget_value (hdr, MU_HEADER_CONTENT_TYPE,
				     &hvalue);
      if (status == MU_ERR_NOENT)
	/* nothing */;
      else if (status != 0)
	mu_error ("Cannot get header value: %s", mu_strerror (status));
      else
	{
	  status = mu_mimehdr_aget_disp (hvalue, &type);
	  if (status)
	    mu_error ("Cannot extract content type field: %s",
		      mu_strerror (status));
	}
      printf ("%*.*sType of part %d = %s\n", indent, indent, "",
	      j, type ? type : "");
      print_message_part_sizes (part, indent);
      if (mu_header_sget_value (hdr, MU_HEADER_CONTENT_TRANSFER_ENCODING,
				&encoding))
	encoding = "";
      ismulti = 0;
      if ((type
           && mu_c_strcasecmp (type, "message/rfc822") == 0)
          || (mu_message_is_multipart (part, &ismulti) == 0 && ismulti))
        {
          if (!ismulti)
	    MU_ASSERT (mu_message_unencapsulate (part, &part, NULL));
	  
          MU_ASSERT (mu_message_get_header (part, &hdr));
          if (mu_header_sget_value (hdr, MU_HEADER_FROM, &from))
	    from = "";
          if (mu_header_sget_value (hdr, MU_HEADER_SUBJECT, &subject))
	    subject = "";
          printf ("%*.*sEncapsulated message : %s\t%s\n",
                  indent, indent, "", from, subject);
          printf ("%*.*sBegin\n", indent, indent, "");
          message_display_parts (part, indent + indent_level);
          mu_message_destroy (&part, NULL);
        }
      else if (!type
               || (mu_c_strcasecmp (type, "text/plain") == 0)
               || (mu_c_strcasecmp (type, "text/html")) == 0)
	{
	  printf ("%*.*sText Message\n", indent, indent, "");
          printf ("%*.*sBegin\n", indent, indent, "");
          mu_message_get_body (part, &body);
          mu_body_get_streamref (body, &str);
          /* Make sure the original body stream is not closed when
             str gets destroyed */
          mu_filter_create (&str, str, encoding, MU_FILTER_DECODE,
			    MU_STREAM_READ);
	  
	  while (mu_stream_readline (str, buf, sizeof (buf), &nbytes) == 0
		 && nbytes)
            {
              printf ("%*.*s%s", indent, indent, "", buf);
            }
          mu_stream_destroy (&str);
        }
      else
        {
          /* Save the attachements.  */
          char *fname = NULL;

          mu_message_aget_decoded_attachment_name (part, charset,
						   &fname, NULL);
          if (fname == NULL)
            fname = mu_tempname (NULL);

          printf ("%*.*sAttachment - saving [%s]\n", indent, indent, "",
                  fname);
          printf ("%*.*sBegin\n", indent, indent, "");
          if (charset)
	    {
	      mu_mime_io_buffer_t info;
	      mu_mime_io_buffer_create (&info);
	      mu_mime_io_buffer_set_charset (info, charset);
	      MU_ASSERT (mu_message_save_attachment (part, NULL, info));
	      mu_mime_io_buffer_destroy (&info);
	    }
	  else
	    MU_ASSERT (mu_message_save_attachment (part, fname, NULL));
          if (print_attachments)
            print_file (fname, indent);
          free (fname);
        }
      printf ("\n%*.*sEnd\n", indent, indent, "");
      free (type);
    }
}
示例#9
0
int
mu_progmailer_send (struct _mu_progmailer *pm, mu_message_t msg)
{
  int status;
  mu_stream_t stream = NULL;
  char buffer[512];
  size_t len = 0;
  int rc;
  mu_header_t hdr;
  mu_body_t body;
  int found_nl = 0;
  int exit_status;
	
  if (!pm || !msg)
    return EINVAL;
  mu_message_get_header (msg, &hdr);
  status = mu_header_get_streamref (hdr, &stream);
  if (status)
    {
      mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
		("cannot get header stream: %s", mu_strerror (status)));
      return status;
    }
  mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE, ("Sending headers..."));
  mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
  while ((status = mu_stream_readline (stream, buffer, sizeof (buffer),
				       &len)) == 0
	 && len != 0)
    {
      if (mu_c_strncasecmp (buffer, MU_HEADER_FCC, sizeof (MU_HEADER_FCC) - 1))
	{
	  mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_PROT, ("Header: %s", buffer));
	  if (write (pm->fd, buffer, len) == -1)
	    {
	      status = errno;
	      
	      mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
			("write failed: %s", strerror (status)));
	      break;
	    }
	}
      found_nl = (len == 1 && buffer[0] == '\n');
    }

  if (!found_nl)
    {
      if (write (pm->fd, "\n", 1) == -1)
	{
	  status = errno;
		
	  mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
		    ("write failed: %s", strerror (status)));
	}
    }
  mu_stream_destroy (&stream);
  
  mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE, ("Sending body..."));
  mu_message_get_body (msg, &body);
  status = mu_body_get_streamref (body, &stream);
  if (status)
    {
      mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
		("cannot get body stream: %s\n", mu_strerror (status)));
      return status;
    }

  mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
  while ((status = mu_stream_read (stream, buffer, sizeof (buffer),
				   &len)) == 0
	 && len != 0)
    {
      if (write (pm->fd, buffer, len) == -1)
	{
	  status = errno;
	  
	  mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
		    ("write failed: %s\n", strerror (status)));
	  break;
	}
    }
  mu_body_get_streamref (body, &stream);

  close (pm->fd);

  rc = waitpid (pm->pid, &exit_status, 0);
  if (status == 0)
    {
      if (rc < 0)
	{
	  if (errno == ECHILD)
	    status = 0;
	  else
	    { 
	      status = errno;
	      mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
			("waitpid(%lu) failed: %s\n",
			 (unsigned long) pm->pid, strerror (status)));
	    }
	}
      else if (WIFEXITED (exit_status))
	{
	  exit_status = WEXITSTATUS (exit_status);
	  mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE,
		    ("%s exited with: %d\n",
		     pm->command, exit_status));
	  status = (exit_status == 0) ? 0 : MU_ERR_PROCESS_EXITED;
	}
      else if (WIFSIGNALED (exit_status))
	status = MU_ERR_PROCESS_SIGNALED;
      else
	status = MU_ERR_PROCESS_UNKNOWN_FAILURE;
    }
  pm->pid = -1;
  return status;
}