Esempio n. 1
0
static void
_iostream_done (struct _mu_stream *str)
{
  struct _mu_iostream *sp = (struct _mu_iostream *)str;
  mu_stream_unref (sp->transport[_MU_STREAM_INPUT]);
  mu_stream_unref (sp->transport[_MU_STREAM_OUTPUT]);
}
Esempio n. 2
0
int
main (int argc, char **argv)
{
  int i;
  mu_stream_t in, out;
  mu_stream_t cvt;
  const char *args[5] = { "iconv" };
  
  if (argc < 3 || argc > 4)
    {
      fprintf (stderr, "usage: %s from-code to-code [err]\n", argv[0]);
      return 1;
    }

  MU_ASSERT (mu_stdio_stream_create (&in, MU_STDIN_FD, 0));
  args[1] = argv[1];
  args[2] = argv[2];
  i = 3;
  if (argc == 4)
    args[i++] = argv[3];
  args[i] = NULL;
  
  MU_ASSERT (mu_filter_create_args (&cvt, in, args[0], i, args,
				    MU_FILTER_DECODE,
				    MU_FILTER_READ));
  mu_stream_unref (in);
  MU_ASSERT (mu_stdio_stream_create (&out, MU_STDOUT_FD, 0));
  MU_ASSERT (mu_stream_copy (out, cvt, 0, NULL));
  mu_stream_unref (cvt);
  mu_stream_flush (out);
  return 0;
}
Esempio n. 3
0
int
mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg,
			  mu_mime_io_buffer_t info)
{
  int ret = 0;
  mu_header_t hdr;
  mu_stream_t istream;

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

  if (info == NULL /* FIXME: not needed? */
      && (ret = mu_message_get_header (msg, &hdr)) == 0)
    {
      const char *s;
      if (!(mu_header_sget_value (hdr, MU_HEADER_CONTENT_TYPE, &s) == 0 &&
	    mu_c_strncasecmp (s, MESSAGE_RFC822_STR,
			      sizeof (MESSAGE_RFC822_STR) - 1) == 0))
	return EINVAL;
    }
  if ((ret = _attachment_setup (&info, msg, &istream)) != 0)
    return ret;
  ret = mu_stream_to_message (istream, &info->msg);
  mu_stream_unref (istream);
  if (ret == 0)
    *newmsg = info->msg;
  _attachment_free (info, ret && ret != EAGAIN);
  return ret;
}
Esempio n. 4
0
static PyObject *
api_sieve_machine_error_text (PyObject *self, PyObject *args)
{
  int status;
  PySieveMachine *py_mach;
  mu_stream_t estr;
  mu_transport_t trans[2];
  PyObject *retval;
  mu_off_t length = 0;
  
  if (!PyArg_ParseTuple (args, "O!", &PySieveMachineType, &py_mach))
    return NULL;
  if (!py_mach->mach)
    PyErr_SetString (PyExc_RuntimeError, "Uninitialized Sieve machine");
      
  mu_sieve_get_diag_stream (py_mach->mach, &estr);
  status = mu_stream_ioctl (estr, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET,
			    trans);
  if (status == 0)
    {
      mu_stream_t str = (mu_stream_t) trans[0];

      mu_stream_size (str, &length);
      status = mu_stream_ioctl (str, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET,
				trans);
      mu_stream_truncate (str, 0);
    }
  
  if (status)
    PyErr_SetString (PyExc_RuntimeError, mu_strerror (status));
  retval = PyString_FromStringAndSize ((char*) trans[0], length);

  mu_stream_unref (estr);
  return _ro (retval);
}
Esempio n. 5
0
static PyObject *
api_stream_unref (PyObject *self, PyObject *args)
{
  PyStream *py_stm;

  if (!PyArg_ParseTuple (args, "O!", &PyStreamType, &py_stm))
    return NULL;

  mu_stream_unref (py_stm->stm);
  return _ro (Py_None);
}
Esempio n. 6
0
static int
set_strerr_flt ()
{
  mu_stream_t flt, trans[2];
  int rc;
  
  rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_TOPSTREAM, MU_IOCTL_OP_GET, trans);
  if (rc == 0)
    {
      char sessidstr[10];
      char *argv[] = { "inline-comment", NULL, "-S", NULL };

      snprintf (sessidstr, sizeof sessidstr, "%08lx:", mu_session_id);
      argv[1] = sessidstr;
      rc = mu_filter_create_args (&flt, trans[0], "inline-comment", 3,
				  (const char **)argv,
				  MU_FILTER_ENCODE, MU_STREAM_WRITE);
      mu_stream_unref (trans[0]);
      if (rc == 0)
	{
	  mu_stream_set_buffer (flt, mu_buffer_line, 0);
	  trans[0] = flt;
	  trans[1] = NULL;
	  rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_TOPSTREAM,
				MU_IOCTL_OP_SET, trans);
	  mu_stream_unref (trans[0]);
	  if (rc)
	    mu_error (_("%s failed: %s"), "MU_IOCTL_SET_STREAM",
		      mu_stream_strerror (mu_strerr, rc));
	}
      else
	mu_error (_("cannot create log filter stream: %s"), mu_strerror (rc));
    }
  else
    {
      mu_error (_("%s failed: %s"), "MU_IOCTL_GET_STREAM",
		mu_stream_strerror (mu_strerr, rc));
    }
  return rc;
}
Esempio n. 7
0
static void
clr_strerr_flt ()
{
  mu_stream_t flt, trans[2];
  int rc;

  rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_TOPSTREAM, MU_IOCTL_OP_GET, trans);
  if (rc == 0)
    {
      flt = trans[0];

      rc = mu_stream_ioctl (flt, MU_IOCTL_TOPSTREAM, MU_IOCTL_OP_GET, trans);
      if (rc == 0)
	{
	  mu_stream_unref (trans[0]);
	  rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_TOPSTREAM,
				MU_IOCTL_OP_SET, trans);
	  if (rc == 0)
	    mu_stream_unref (flt);
	}
    }
}
Esempio n. 8
0
static PyObject *
api_sieve_machine_init (PyObject *self, PyObject *args)
{
  int status;
  PySieveMachine *py_mach;
  mu_stream_t str, estr;
  
  if (!PyArg_ParseTuple (args, "O!", &PySieveMachineType, &py_mach))
    return NULL;

  status = mu_memory_stream_create (&str, MU_STREAM_RDWR);
  if (status)
    return _ro (PyInt_FromLong (status));
  status = mu_log_stream_create (&estr, str);
  mu_stream_unref (str);
  if (status)
    return _ro (PyInt_FromLong (status));
  
  status = mu_sieve_machine_init_ex (&py_mach->mach, NULL, estr);
  mu_stream_unref (estr);
  return _ro (PyInt_FromLong (status));
}
Esempio n. 9
0
int
imap4d_init_tls_server ()
{
  mu_stream_t tlsstream, stream[2];
  int rc;

  rc = mu_stream_ioctl (iostream, MU_IOCTL_SUBSTREAM, MU_IOCTL_OP_GET, stream);
  if (rc)
    {
      mu_error (_("%s failed: %s"), "MU_IOCTL_GET_STREAM",
		mu_stream_strerror (iostream, rc));
      return 1;
    }
  
  rc = mu_tls_server_stream_create (&tlsstream, stream[0], stream[1], 0);
  if (rc)
    {
      mu_diag_output (MU_DIAG_ERROR, _("cannot open TLS stream: %s"),
		      mu_stream_strerror (tlsstream, rc));
      return 1;
    }

  mu_stream_unref (stream[0]);
  mu_stream_unref (stream[1]);
  stream[0] = stream[1] = tlsstream;

  rc = mu_stream_ioctl (iostream, MU_IOCTL_SUBSTREAM, MU_IOCTL_OP_SET, stream);
  if (rc)
    {
      mu_error (_("%s failed: %s"), "MU_IOCTL_SET_STREAM",
		mu_stream_strerror (iostream, rc));
      imap4d_bye (ERR_STREAM_CREATE);
    }
  mu_stream_unref (stream[0]);
  mu_stream_unref (stream[1]);
  
  return 0;
}
Esempio n. 10
0
/* A locale-independent version of strftime */
size_t
mu_strftime (char *buf, size_t size, const char *format, struct tm *tm)
{
  int rc;
  mu_stream_t str;
  mu_stream_stat_buffer stat;

  if (mu_fixed_memory_stream_create (&str, buf, size, MU_STREAM_WRITE))
    return 0;
  mu_stream_set_stat (str, MU_STREAM_STAT_MASK (MU_STREAM_STAT_OUT), stat);
  rc = mu_c_streamftime (str, format, tm, NULL);
  if (rc == 0)
    rc = mu_stream_write (str, "", 1, NULL);
  mu_stream_unref (str);
  return rc ? 0 : stat[MU_STREAM_STAT_OUT] - 1;
}
Esempio n. 11
0
static int
_mh_prop_save (struct _mu_property *prop)
{
  struct mu_mh_prop *mhprop = prop->_prop_init_data;
  mu_header_t header = prop->_prop_data;
  mu_stream_t stream;
  int rc;
  
  if (mhprop->ro)
    return 0;
  
  rc = mu_file_stream_create (&stream, mhprop->filename,
			      MU_STREAM_WRITE|MU_STREAM_CREAT);
  if (rc)
    return rc;
  rc = _mh_prop_write_stream (header, mhprop, stream);
  mu_stream_unref (stream);
  return rc;
}
Esempio n. 12
0
static int
chk_ssha (const char *db_pass, const char *pass)
{
  int rc;
  unsigned char sha1digest[20];
  unsigned char *d1;
  struct mu_sha1_ctx sha1context;
  mu_stream_t str = NULL, flt = NULL;
  size_t size;
  
  size = strlen (db_pass);
  mu_static_memory_stream_create (&str, db_pass, size);
  mu_filter_create (&flt, str, "base64", MU_FILTER_DECODE, MU_STREAM_READ);
  mu_stream_unref (str);

  d1 = malloc (size);
  if (!d1)
    {
      mu_stream_destroy (&flt);
      return ENOMEM;
    }
  
  mu_stream_read (flt, (char*) d1, size, &size);
  mu_stream_destroy (&flt);

  if (size <= 16)
    {
      mu_error ("malformed SSHA1 password: %s", db_pass);
      return MU_ERR_FAILURE;
    }
  
  mu_sha1_init_ctx (&sha1context);
  mu_sha1_process_bytes (pass, strlen (pass), &sha1context);
  mu_sha1_process_bytes (d1 + 20, size - 20, &sha1context);
  mu_sha1_finish_ctx (&sha1context, sha1digest);

  rc = memcmp (sha1digest, d1, sizeof sha1digest) == 0 ?
                  0 : MU_ERR_AUTH_FAILURE;
  free (d1);
  return rc;
}
Esempio n. 13
0
static int
chk_sha (const char *db_pass, const char *pass)
{
  unsigned char sha1digest[20];
  unsigned char d1[20];
  mu_stream_t str = NULL, flt = NULL;
  struct mu_sha1_ctx sha1context;
   
  mu_sha1_init_ctx (&sha1context);
  mu_sha1_process_bytes (pass, strlen (pass), &sha1context);
  mu_sha1_finish_ctx (&sha1context, sha1digest);

  mu_static_memory_stream_create (&str, db_pass, strlen (db_pass));
  mu_filter_create (&flt, str, "base64", MU_FILTER_DECODE, MU_STREAM_READ);
  mu_stream_unref (str);

  mu_stream_read (flt, (char*) d1, sizeof d1, NULL);
  mu_stream_destroy (&flt);
  
  return memcmp (sha1digest, d1, sizeof sha1digest) == 0 ?
                  0 : MU_ERR_AUTH_FAILURE;
}
Esempio n. 14
0
static int
pop_scan_message (struct _pop3_message *mpm)
{
  int status;
  mu_stream_t stream;
  struct mu_message_scan scan;

  if (mpm->flags & _POP3_MSG_SCANNED)
    return 0;
  
  status = _pop_message_get_stream (mpm, &stream);
  if (status)
    return status;
      
  scan.flags = MU_SCAN_SEEK | MU_SCAN_SIZE;
  scan.message_start = 0;
  scan.message_size = mpm->message_size;
  status = mu_stream_scan_message (stream, &scan);
  mu_stream_unref (stream);

  if (status == 0)
    {
      mpm->body_start = scan.body_start;
      mpm->body_end = scan.body_end;
      mpm->header_lines = scan.header_lines;
      mpm->body_lines = scan.body_lines;
      if (!(mpm->flags & _POP3_MSG_ATTRSET))
	{
	  mpm->attr_flags = scan.attr_flags;
	  mpm->flags |= _POP3_MSG_ATTRSET;
	}

      mpm->flags |= _POP3_MSG_SCANNED;
    }
  
  return status;
}
Esempio n. 15
0
static int
_mh_prop_fill (struct _mu_property *prop)
{
  struct mu_mh_prop *mhprop = prop->_prop_init_data;
  int rc;
  mu_stream_t stream;
  mu_header_t header;
  
  rc = mu_file_stream_create (&stream, mhprop->filename, MU_STREAM_READ);
  if (rc)
    {
      if ((rc = mu_header_create (&header, NULL, 0)) != 0)
	mu_error (_("cannot create context %s: %s"),
		  mhprop->filename, mu_strerror (rc));
    }
  else
    {
      rc = _mh_prop_read_stream (&header, stream);
      mu_stream_unref (stream);
    }
  if (rc == 0)
    prop->_prop_data = header;
  return rc;
}
Esempio n. 16
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;
}
Esempio n. 17
0
static void
_sieve_action_printer (void *data, mu_stream_t stream,
		       size_t msgno, mu_message_t msg,
		       const char *action, const char *fmt, va_list ap)
{
  PyObject *py_args;
  PyObject *py_dict = PyDict_New ();
  PyStream *py_stm;

  if (!py_dict)
    return;
  py_stm = PyStream_NEW ();
  if (py_stm)
    {
      PyMessage *py_msg = PyMessage_NEW ();
      char *buf = NULL;
      size_t buflen = 0;

      if (py_msg)
	{
	  PyStream *py_stm = PyStream_NEW ();
	  if (py_stm)
	    {
	      py_stm->stm = stream;
	      mu_stream_ref (stream);
	  
	      py_msg->msg = msg;
	      Py_INCREF (py_msg);

	      PyDict_SetItemString (py_dict, "msgno",
				    PyInt_FromSize_t (msgno));
	      PyDict_SetItemString (py_dict, "msg", (PyObject *)py_msg);
	      PyDict_SetItemString (py_dict, "action",
				    PyString_FromString (action ? action : ""));

	      if (mu_vasnprintf (&buf, &buflen, fmt, ap))
		{
		  mu_stream_unref (stream);
		  return;
		}
	      PyDict_SetItemString (py_dict, "text",
				    PyString_FromString (buf ? buf : ""));
	      free (buf);

	      py_args = PyTuple_New (1);
	      if (py_args)
		{
		  struct _mu_py_sieve_logger *s = data;
		  PyObject *py_fnc = s->py_action_printer;

		  Py_INCREF (py_dict);
		  PyTuple_SetItem (py_args, 0, py_dict);
		  
		  if (py_fnc && PyCallable_Check (py_fnc))
		    PyObject_CallObject (py_fnc, py_args);

		  Py_DECREF (py_dict);
		  Py_DECREF (py_args);
		}
	    }
	}
    }
}
Esempio n. 18
0
int
main (int argc, char * argv [])
{
  mu_stream_t in, out, flt;
  int i;
  int mode = MU_FILTER_ENCODE;
  int flags = MU_STREAM_READ;
  char *fltname;
  mu_off_t shift = 0;
  int newline_option = 0;
  size_t bufsize = 0;
  
  if (argc == 1)
    usage (NULL);
  if (argc < 4)
    usage ("not enough arguments");
  
  fltname = argv[1];

  if (strcmp (argv[2], "encode") == 0)
    mode = MU_FILTER_ENCODE;
  else if (strcmp (argv[2], "decode") == 0)
    mode = MU_FILTER_DECODE;
  else
    usage ("2nd arg is wrong");

  if (strcmp (argv[3], "read") == 0)
    flags = MU_STREAM_READ;
  else if (strcmp (argv[3], "write") == 0)
    flags = MU_STREAM_WRITE;
  else
    usage ("3rd arg is wrong");

  for (i = 4; i < argc; i++)
    {
      if (strncmp (argv[i], "shift=", 6) == 0)
	shift = strtoul (argv[i] + 6, NULL, 0);
      else if (strncmp (argv[i], "bufsize=", 8) == 0)
	bufsize = strtoul (argv[i] + 8, NULL, 0);
      else if (strcmp (argv[i], "verbose") == 0)
	verbose++;
      else if (strcmp (argv[i], "printable") == 0)
	printable++;
      else if (strcmp (argv[i], "nl") == 0)
	newline_option++;
      else if (strcmp (argv[i], "--") == 0)
	{
	  argv[i] = fltname;
	  break;
	}
      else
	usage ("wrong option");
    }

  argc -= i;
  argv += i;
  
  MU_ASSERT (mu_stdio_stream_create (&in, MU_STDIN_FD, 0));
  if (bufsize)
    mu_stream_set_buffer (in, mu_buffer_full, bufsize);
  MU_ASSERT (mu_stdio_stream_create (&out, MU_STDOUT_FD, 0));

  if (flags == MU_STREAM_READ)
    {
      MU_ASSERT (mu_filter_create_args (&flt, in, fltname,
					argc, (const char **)argv,
					mode,
					MU_STREAM_READ|MU_STREAM_SEEK));
      mu_stream_unref (in);
      if (bufsize)
	mu_stream_set_buffer (flt, mu_buffer_full, bufsize);
      if (shift)
	MU_ASSERT (mu_stream_seek (flt, shift, MU_SEEK_SET, NULL));
      c_copy (out, flt);
    }
  else
    {
      MU_ASSERT (mu_filter_create_args (&flt, out, fltname,
					argc, (const char **)argv,
					mode,
					MU_STREAM_WRITE));
      if (bufsize)
	mu_stream_set_buffer (flt, mu_buffer_full, bufsize);
      if (shift)
	MU_ASSERT (mu_stream_seek (in, shift, MU_SEEK_SET, NULL));
      c_copy (flt, in);

      mu_stream_close (in);
      mu_stream_destroy (&in);
    }

  mu_stream_close (flt);
  mu_stream_destroy (&flt);
  
  if (newline_option)
    mu_stream_write (out, "\n", 1, NULL);
    
  mu_stream_close (out);
  mu_stream_destroy (&out);
  
  if (verbose)
    {
      fprintf (stderr, "\nInput stream stats:\n");
      fprintf (stderr, "Bytes in: %lu\n",
	       (unsigned long) instat[MU_STREAM_STAT_IN]);
      fprintf (stderr, "Bytes out: %lu\n",
	       (unsigned long) instat[MU_STREAM_STAT_OUT]);
      fprintf (stderr, "Reads: %lu\n",
	       (unsigned long) instat[MU_STREAM_STAT_READS]);
      fprintf (stderr, "Seeks: %lu\n",
	       (unsigned long) instat[MU_STREAM_STAT_SEEKS]);

      fprintf (stderr, "\nOutput stream stats:\n");
      fprintf (stderr, "Bytes in: %lu\n",
	       (unsigned long) outstat[MU_STREAM_STAT_IN]);
      fprintf (stderr, "Bytes out: %lu\n",
	       (unsigned long) outstat[MU_STREAM_STAT_OUT]);
      fprintf (stderr, "Writes: %lu\n",
	       (unsigned long) outstat[MU_STREAM_STAT_WRITES]);
      fprintf (stderr, "Seeks: %lu\n",
	       (unsigned long) outstat[MU_STREAM_STAT_SEEKS]);
    }

  return 0;
}
Esempio n. 19
0
void
io_setio (int ifd, int ofd, int tls)
{
  mu_stream_t str, istream, ostream;
  
  if (ifd == -1)
    imap4d_bye (ERR_NO_IFILE);
  if (ofd == -1)
    imap4d_bye (ERR_NO_OFILE);

  if (mu_stdio_stream_create (&istream, ifd, MU_STREAM_READ))
    imap4d_bye (ERR_STREAM_CREATE);
  mu_stream_set_buffer (istream, mu_buffer_line, 0);
  
  if (mu_stdio_stream_create (&ostream, ofd, MU_STREAM_WRITE))
    imap4d_bye (ERR_STREAM_CREATE);
  mu_stream_set_buffer (ostream, mu_buffer_line, 0);
  
  /* Combine the two streams into an I/O one. */
#ifdef WITH_TLS
  if (tls)
    {
      int rc = mu_tls_server_stream_create (&str, istream, ostream, 0);
      if (rc)
	{
	  mu_stream_unref (istream);
	  mu_stream_unref (ostream);
	  mu_error (_("failed to create TLS stream: %s"), mu_strerror (rc));
	  imap4d_bye (ERR_STREAM_CREATE);
	}
    }
  else
#endif
  if (mu_iostream_create (&str, istream, ostream))
    imap4d_bye (ERR_STREAM_CREATE);

  /* Convert all writes to CRLF form.
     There is no need to convert reads, as the code ignores extra \r anyway.
  */
  if (mu_filter_create (&iostream, str, "CRLF", MU_FILTER_ENCODE,
			MU_STREAM_WRITE | MU_STREAM_RDTHRU))
    imap4d_bye (ERR_STREAM_CREATE);
  /* Change buffering scheme: filter streams are fully buffered by default. */
  mu_stream_set_buffer (iostream, mu_buffer_line, 0);
  
  if (imap4d_transcript)
    {
      int rc;
      mu_stream_t dstr, xstr;
      
      rc = mu_dbgstream_create (&dstr, MU_DIAG_DEBUG);
      if (rc)
	mu_error (_("cannot create debug stream; transcript disabled: %s"),
		  mu_strerror (rc));
      else
	{
	  rc = mu_xscript_stream_create (&xstr, iostream, dstr, NULL);
	  mu_stream_unref (dstr);
	  if (rc)
	    mu_error (_("cannot create transcript stream: %s"),
		      mu_strerror (rc));
	  else
	    {
	      mu_stream_unref (iostream);
	      iostream = xstr;
	    }
	}
    }
}
Esempio n. 20
0
static int
_iostream_ctl (struct _mu_stream *str, int code, int opcode, void *arg)
{
  struct _mu_iostream *sp = (struct _mu_iostream *)str;

  switch (code)
    {
    case MU_IOCTL_TRANSPORT:
      if (!arg)
	return EINVAL;
      else
	{
	  mu_transport_t *ptrans = arg;

	  switch (opcode)
	    {
	    case MU_IOCTL_OP_GET:
	      ptrans[0] = (mu_transport_t) sp->transport[_MU_STREAM_INPUT];
	      ptrans[1] = (mu_transport_t) sp->transport[_MU_STREAM_OUTPUT];
	      break;

	    case MU_IOCTL_OP_SET:
	      ptrans = arg;
	      sp->transport[_MU_STREAM_INPUT] = (mu_stream_t) ptrans[0];
	      sp->transport[_MU_STREAM_OUTPUT] = (mu_stream_t) ptrans[1];
	      break;

	    default:
	      return EINVAL;
	    }
	}
      break;

    case MU_IOCTL_SUBSTREAM:
    case MU_IOCTL_TOPSTREAM:
      if (!arg)
	return EINVAL;
      else
	{
	  mu_stream_t *pstr = arg;
	  switch (opcode)
	    {
	    case MU_IOCTL_OP_GET:
	      pstr[0] = sp->transport[0];
	      mu_stream_ref (pstr[0]);
	      pstr[1] = sp->transport[1];
	      mu_stream_ref (pstr[1]);
	      break;

	    case MU_IOCTL_OP_SET:
	      mu_stream_unref (sp->transport[0]);
	      sp->transport[0] = pstr[0];
	      mu_stream_ref (sp->transport[0]);
	      
	      mu_stream_unref (sp->transport[1]);
	      sp->transport[1] = pstr[1];
	      mu_stream_ref (sp->transport[1]);
	      break;

	    default:
	      return EINVAL;
	    }
	}
      break;

    case MU_IOCTL_TRANSPORT_BUFFER:
      if (!arg)
	return EINVAL;
      else
	{
	  struct mu_buffer_query *qp = arg;
	  if (!MU_TRANSPORT_VALID_TYPE (qp->type) || !sp->transport[qp->type])
	    return EINVAL;
	  return mu_stream_ioctl (sp->transport[qp->type], code, opcode, arg);
	}
      
    default:
      return ENOSYS;
    }
  return 0;
}
Esempio n. 21
0
int
mutool_filter (int argc, char **argv)
{
  int rc, index;
  mu_stream_t flt, prev_stream;
  const char *fltname;
  int mode;
  
  if (argp_parse (&filter_argp, argc, argv, ARGP_IN_ORDER, &index, NULL))
    return 1;

  argc -= index;
  argv += index;

  if (list_option)
    {
      if (argc)
	{
	  mu_error (_("excess arguments"));
	  return 1;
	}
      return list_filters ();
    }
  
  if (argc == 0)
    {
      mu_error (_("what filter do you want?"));
      return 1;
    }

  prev_stream = mu_strin;
  mu_stream_ref (mu_strin);
  do
    {
      int i;
      
      fltname = argv[0];
      if (fltname[0] == '~')
	{
	  mode = negate_filter_mode (filter_mode);
	  fltname++;
	}
      else
	mode = filter_mode;

      for (i = 1; i < argc; i++)
	if (strcmp (argv[i], "+") == 0)
	  break;
      
      rc = mu_filter_create_args (&flt, prev_stream, fltname,
				  i, (const char **)argv,
				  mode, MU_STREAM_READ);
      mu_stream_unref (prev_stream);
      if (rc)
	{
	  mu_error (_("cannot open filter stream: %s"), mu_strerror (rc));
	  return 1;
	}
      prev_stream = flt;
      argc -= i;
      argv += i;
      if (argc)
	{
	  argc--;
	  argv++;
	}
    }
  while (argc);
  
  rc = mu_stream_copy (mu_strout, flt, 0, NULL);

  if (rc)
    {
      mu_error ("%s", mu_strerror (rc));
      return 1;
    }

  if (newline_option)
    mu_stream_write (mu_strout, "\n", 1, NULL);

  mu_stream_destroy (&flt);
  mu_stream_flush (mu_strout);
  
  return 0;
}
Esempio n. 22
0
/* Generate and send the reply message */
static int
vacation_reply (mu_sieve_machine_t mach, mu_list_t tags, mu_message_t msg,
		char *text, char *to, char *from)
{
  mu_mime_t mime = NULL;
  mu_message_t newmsg;
  mu_header_t newhdr;
  mu_address_t to_addr = NULL, from_addr = NULL;
  char *value;
  mu_mailer_t mailer;
  int rc;

  if (mu_sieve_tag_lookup (tags, "file", NULL))
    {
      mu_stream_t instr;
      
      rc = mu_mapfile_stream_create (&instr, text, MU_STREAM_READ);
      if (rc)
	{
	  mu_sieve_error (mach,
			  _("%lu: cannot open message file %s: %s"),
			  (unsigned long) mu_sieve_get_message_num (mach),
			  text,
			  mu_strerror (rc));
	  return -1;
	}
      rc = mu_stream_to_message (instr, &newmsg);
      mu_stream_unref (instr);
      if (rc)
	{
	  mu_sieve_error (mach,
			  _("%lu: cannot read message from file %s: %s"),
			  (unsigned long) mu_sieve_get_message_num (mach),
			  text,
			  mu_strerror (rc));
	  return -1;
	} 
    }
  else
    {
      if (build_mime (mach, tags, &mime, msg, text))
	return -1;
      mu_mime_get_message (mime, &newmsg);
      mu_message_unref (newmsg);
      mu_message_get_header (newmsg, &newhdr);
    }
  
  rc = mu_address_create (&to_addr, to);
  if (rc)
    {
      mu_sieve_error (mach,
		      _("%lu: cannot create recipient address <%s>: %s"),
		      (unsigned long) mu_sieve_get_message_num (mach),
		      from, mu_strerror (rc));
    }
  else
    {
      mu_header_set_value (newhdr, MU_HEADER_TO, to, 0);
      
      vacation_subject (mach, tags, msg, newhdr);
      
      if (from)
        {
          if (mu_address_create (&from_addr, from))
	    from_addr = NULL;
        }
      else
        {
          from_addr = NULL;
        }
      
      if (mu_rfc2822_in_reply_to (msg, &value) == 0)
        {
          mu_header_set_value (newhdr, MU_HEADER_IN_REPLY_TO, value, 1);
          free (value);
        }
      
      if (mu_rfc2822_references (msg, &value) == 0)
        {
          mu_header_set_value (newhdr, MU_HEADER_REFERENCES, value, 1);
          free (value);
        }
      
      mailer = mu_sieve_get_mailer (mach);
      if (mailer)
	{
	  rc = mu_mailer_send_message (mailer, newmsg, from_addr, to_addr);
	}
      else
	rc = MU_ERR_FAILURE;
    }
  mu_address_destroy (&to_addr);
  mu_address_destroy (&from_addr);
  mu_mime_destroy (&mime);
  return rc;
}
Esempio n. 23
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;
}
Esempio n. 24
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;
}
Esempio n. 25
0
static int
_pop_message_get_stream (struct _pop3_message *mpm, mu_stream_t *pstr)
{
  int status;
  struct _pop3_mailbox *mpd = mpm->mpd;
  
  if (!(mpm->flags & _POP3_MSG_CACHED))
    {
      mu_stream_t stream;
      mu_off_t size;
      
      status = mu_pop3_retr (mpd->pop3, mpm->num, &stream);
      if (status)
	return status;

      do
	{
	  mu_stream_t flt;
	  
	  if (!mpd->cache)
	    {
	      status = mu_temp_file_stream_create (&mpd->cache, NULL, 0);
	      if (status)
		/* FIXME: Try to recover first */
		break;

	      mu_stream_set_buffer (mpd->cache, mu_buffer_full, 8192);
	    }

	  status = mu_stream_size (mpd->cache, &mpm->offset);
	  if (status)
	    break;

	  status = mu_filter_create (&flt, stream, "CRLF", MU_FILTER_DECODE,
				     MU_STREAM_READ);
	  if (status)
	    break;

	  status = mu_stream_copy (mpd->cache, flt, 0, &size);

	  mu_stream_destroy (&flt);
	}
      while (0);

      if (status)
	{
	  pop_stream_drain (stream);
	  mu_stream_unref (stream);
	  return status;
	}

      mu_stream_unref (stream);

      mpm->message_size = size; /* FIXME: Possible overflow. */

      mpm->flags |= _POP3_MSG_CACHED | _POP3_MSG_SIZE;
    }
  return mu_streamref_create_abridged (pstr, mpd->cache,
				       mpm->offset,
				       mpm->offset + mpm->message_size - 1);
}
Esempio n. 26
0
static int
pop_open (mu_mailbox_t mbox, int flags)
{
  struct _pop3_mailbox *mpd = mbox->data;
  int status;
  mu_stream_t stream;
  struct mu_sockaddr *sa;
  struct mu_sockaddr_hints hints;

  /* Sanity checks. */
  if (mpd == NULL)
    return EINVAL;
  
  mbox->flags = flags;
  
  memset (&hints, 0, sizeof (hints));
  hints.flags = MU_AH_DETECT_FAMILY;
  hints.port = mpd->pops ? MU_POPS_PORT : MU_POP_PORT;
  hints.protocol = IPPROTO_TCP;
  hints.socktype = SOCK_STREAM;
  status = mu_sockaddr_from_url (&sa, mbox->url, &hints);
  if (status)
    return status;
      
  status = mu_tcp_stream_create_from_sa (&stream, sa, NULL, mbox->flags);
  if (status)
    {
      mu_sockaddr_free (sa);
      return status;
    }
#ifdef WITH_TLS
  if (mpd->pops)
    {
      mu_stream_t newstr;
      
      status = mu_tls_client_stream_create (&newstr, stream, stream, 0);
      mu_stream_unref (stream);
      if (status)
	{
	  mu_error ("pop_open: mu_tls_client_stream_create: %s",
		    mu_strerror (status));
	  return status;
	}
      stream = newstr;
    }
#endif /* WITH_TLS */

  /* FIXME: How to configure buffer size? */
  mu_stream_set_buffer (stream, mu_buffer_line, 0);

  status = mu_pop3_create (&mpd->pop3);
  if (status)
    {
      mu_stream_destroy (&stream);
      return status;
    }
  mu_pop3_set_carrier (mpd->pop3, stream);

  if (mu_debug_level_p (MU_DEBCAT_MAILBOX, MU_DEBUG_PROT))
    mu_pop3_trace (mpd->pop3, MU_POP3_TRACE_SET);
  if (mu_debug_level_p (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE6))
    mu_pop3_trace_mask (mpd->pop3, MU_POP3_TRACE_SET, MU_XSCRIPT_SECURE);
  if (mu_debug_level_p (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE7))
    mu_pop3_trace_mask (mpd->pop3, MU_POP3_TRACE_SET, MU_XSCRIPT_PAYLOAD);
    
  do
    {
      status = mu_pop3_connect (mpd->pop3);
      if (status)
	break;

      status = mu_pop3_capa (mpd->pop3, 1, NULL);
      if (status == MU_ERR_REPLY) 
        {
	  mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR, 
		    ("server rejected the CAPA command: %s",
		     mu_pop3_strresp (mpd->pop3)));
	  /* try to continue anyway */
        } 
      else if (status)
	return status;

#ifdef WITH_TLS      
      if (!mpd->pops &&
	  mu_url_sget_param (mbox->url, "notls", NULL) == MU_ERR_NOENT &&
	  mu_pop3_capa_test (mpd->pop3, "STLS", NULL) == 0)
	{
	  status = mu_pop3_stls (mpd->pop3);
	  if (status)
	    break;
	}
#endif
      status = mu_authority_authenticate (mbox->folder->authority);
    }
  while (0);
  
  if (status)
    mu_pop3_destroy (&mpd->pop3);
  return status;
}
Esempio n. 27
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;
}
Esempio n. 28
0
static void
_streamref_done (struct _mu_stream *str)
{
  struct _mu_streamref *sp = (struct _mu_streamref *)str;
  mu_stream_unref (sp->transport);
}
Esempio n. 29
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;
}
Esempio n. 30
0
int
mutool_send (int argc, char **argv)
{
  int index;
  char *infile;
  mu_stream_t instr;
  mu_message_t msg;
  size_t count;
  mu_url_t urlhint, url;
  mu_mailer_t mailer;
  
  MU_ASSERT (mu_address_create_null (&rcpt_addr));
  mu_register_all_mailer_formats ();
  
  if (argp_parse (&send_argp, argc, argv, 0, &index, NULL))
    return 1;

  argc -= index;
  argv += index;

  if (argc < 1)
    {
      mu_error (_("not enough arguments"));
      return 1;
    }

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

  MU_ASSERT (mu_stream_to_message (instr, &msg));
  mu_stream_unref (instr);

  mu_address_get_count (rcpt_addr, &count);
  if (count == 0)
    read_recipients = 1;

  if (read_recipients)
    {
      int rc;
      mu_header_t header;
      const char *value;

      MU_ASSERT (mu_message_get_header (msg, &header));
	  
      rc = mu_header_sget_value (header, MU_HEADER_TO, &value);
      if (rc == 0)
	send_address_add (&rcpt_addr, value);
      else if (rc != MU_ERR_NOENT)
	{
	  mu_diag_funcall (MU_DIAG_ERROR, "mu_header_sget_value",
			   MU_HEADER_TO, rc);
	  exit (1);
	}
      
      rc = mu_header_sget_value (header, MU_HEADER_CC, &value);
      if (rc == 0)
	send_address_add (&rcpt_addr, value);
      else if (rc != MU_ERR_NOENT)
	{
	  mu_diag_funcall (MU_DIAG_ERROR, "mu_header_sget_value",
			   MU_HEADER_CC, rc);
	  exit (1);
	}

      rc = mu_header_sget_value (header, MU_HEADER_BCC, &value);
      if (rc == 0)
	send_address_add (&rcpt_addr, value);
      else if (rc != MU_ERR_NOENT)
	{
	  mu_diag_funcall (MU_DIAG_ERROR, "mu_header_sget_value",
			   MU_HEADER_BCC, rc);
	  exit (1);
	}
    }

  mu_address_get_count (rcpt_addr, &count);
  if (count == 0)
    {
      mu_error (_("no recipients"));
      exit (1);
    }
  
  MU_ASSERT (mu_url_create (&urlhint, "smtp://"));
  MU_ASSERT (mu_url_create_hint (&url, argv[0], MU_URL_PARSE_DEFAULT,
				 urlhint));
  mu_url_invalidate (url);
  MU_ASSERT (mu_mailer_create_from_url (&mailer, url));
  MU_ASSERT (mu_mailer_open (mailer, MU_STREAM_RDWR));
  MU_ASSERT (mu_mailer_send_message (mailer, msg, from_addr, rcpt_addr));
  mu_mailer_close (mailer);
  mu_mailer_destroy (&mailer);
  return 0;
}