Пример #1
0
char *
dispatch_docstring (const char *text)
{
  mu_stream_t str;
  struct mutool_action_tab *p;
  mu_off_t size;
  size_t n;
  char *ret;
  
  mu_memory_stream_create (&str, MU_STREAM_RDWR);
  mu_stream_printf (str, "%s\n%s\n\n", text, _("Commands are:"));
  for (p = mutool_action_tab; p->name; p++)
    mu_stream_printf (str, "  %s %-16s - %s\n",
		      mu_program_name,
		      p->name, gettext (p->docstring));
  mu_stream_printf (str,
		      _("\nTry `%s COMMAND --help' to get help on a particular "
		      "COMMAND.\n\n"),
		      mu_program_name);
  mu_stream_printf (str, "%s\n", _("Options are:"));
  mu_stream_flush (str);
  mu_stream_size (str, &size);
  ret = mu_alloc (size + 1);
  mu_stream_seek (str, 0, MU_SEEK_SET, NULL);
  mu_stream_read (str, ret, size, &n);
  ret[n] = 0;
  mu_stream_destroy (&str);
  return ret;
}
Пример #2
0
int
main (int argc, char * argv [])
{
  int c;
  mu_stream_t in, out;
  int reread_option = 0;
  mu_off_t reread_off;
  int skip_option = 0;
  mu_off_t skip_off;
  
  while ((c = getopt (argc, argv, "hs:r:")) != EOF)
    switch (c)
      {
      case 'r':
	reread_option = 1;
	reread_off = strtoul (optarg, NULL, 10);
	break;

      case 's':
	skip_option = 1;
	skip_off = strtoul (optarg, NULL, 10);
	break;

      case 'h':
	printf ("usage: cat [-s off]\n");
	exit (0);

      default:
	exit (1);
      }
	

  MU_ASSERT (mu_stdio_stream_create (&in, MU_STDIN_FD, MU_STREAM_SEEK));
  MU_ASSERT (mu_stdio_stream_create (&out, MU_STDOUT_FD, 0));

  if (skip_option)
    {
      mu_stream_printf (out, "skipping to %lu:\n",
			(unsigned long) skip_off);
      MU_ASSERT (mu_stream_seek (in, skip_off, MU_SEEK_SET, NULL));
    }
  
  MU_ASSERT (mu_stream_copy (out, in, 0, NULL));

  if (reread_option)
    {
      mu_stream_printf (out, "rereading from %lu:\n",
			(unsigned long) reread_off);
      MU_ASSERT (mu_stream_seek (in, reread_off, MU_SEEK_SET, NULL));
      MU_ASSERT (mu_stream_copy (out, in, 0, NULL));
    }
  
  mu_stream_close (in);
  mu_stream_destroy (&in);
  mu_stream_close (out);
  mu_stream_destroy (&out);
  return 0;
}
Пример #3
0
int
mu_vgetyn (const char *fmt, va_list ap)
{
  char repl[64];

  while (1)
    {
      int rc;
      size_t n;
      
      mu_stream_vprintf (mu_strout, fmt, ap);
      mu_stream_write (mu_strout, "? ", 2, NULL);
      mu_stream_flush (mu_strout);
      if (mu_stream_read (mu_strin, repl, sizeof repl, &n) || n == 0)
	return 0;
      mu_rtrim_class (repl, MU_CTYPE_ENDLN);

      rc = mu_true_answer_p (repl);
      
      if (rc >= 0)
	return rc;
      
      /* TRANSLATORS: See msgids "nN" and "yY". */
      mu_stream_printf (mu_strout, "%s", _("Please answer yes or no: "));
    }
  return 0; /* to pacify gcc */
}
Пример #4
0
int
mu_vgetans (const char *variants, const char *fmt, va_list ap)
{
  char repl[64];

  while (1)
    {
      size_t n;
      char *p;
      
      mu_stream_vprintf (mu_strout, fmt, ap);
      mu_stream_write (mu_strout, "? ", 2, NULL);
      mu_stream_flush (mu_strout);
      if (mu_stream_read (mu_strin, repl, sizeof repl, &n) || n == 0)
	return 0;
      mu_rtrim_class (repl, MU_CTYPE_ENDLN);

      p = strchr (variants, *repl);
      if (p)
	return *p;
      
      mu_stream_printf (mu_strout, _("Please answer one of [%s]: "), variants);
    }
  return 0; /* to pacify gcc */
}
Пример #5
0
/* Send the completion response and reset the state.  */
int
io_format_completion_response (mu_stream_t str,
			       struct imap4d_command *command, int rc, 
			       const char *format, va_list ap)
{
  int new_state;
  int status = 0;
  const char *sc = sc2string (rc);

  imap4d_sync ();
  
  mu_stream_printf (str, "%s %s%s ",
		    command->tag, sc, command->name);
  mu_stream_vprintf (str, format, ap);
  mu_stream_write (str, "\n", 1, NULL);

  /* Reset the state.  */
  if (rc == RESP_OK)
    new_state = command->success;
  else if (command->failure <= state)
    new_state = command->failure;
  else
    new_state = STATE_NONE;

  if (new_state != STATE_NONE)
    {
      if (new_state == STATE_AUTH)
	set_xscript_level (MU_XSCRIPT_NORMAL);
      state = new_state;
    }
  
  return status;
}
Пример #6
0
/* Send an untagged response.  */
int
io_untagged_response (int rc, const char *format, ...)
{
  int status;
  va_list ap;

  mu_stream_printf (iostream, "* %s", sc2string (rc));
  va_start (ap, format);
  status = mu_stream_vprintf (iostream, format, ap);
  va_end (ap);
  mu_stream_write (iostream, "\n", 1, NULL);
  return status;
}
Пример #7
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;
}
Пример #8
0
int
mu_imapio_getline (struct _mu_imapio *io)
{
  int rc;
  char *last_arg;
  int xlev = MU_XSCRIPT_NORMAL;
  
  if (io->_imap_reply_ready)
    {
      mu_wordsplit_free_words (&io->_imap_ws);
      io->_imap_reply_ready = 0;
    }
  
  for (;;)
    {
      rc = mu_stream_getline (io->_imap_stream,
			      &io->_imap_buf_base, &io->_imap_buf_size,
			      &io->_imap_buf_level);
      if (rc)
	break;
      if (io->_imap_buf_level == 0)
	break;
      io->_imap_buf_level = mu_rtrim_class (io->_imap_buf_base,
					    MU_CTYPE_ENDLN);
      
      rc = initial_parse (io);
      if (rc == IMAPIO_ERR)
	{
	  rc = MU_ERR_PARSE;
	  break;
	}
      else if (rc == IMAPIO_RESP)
	{
	  rc = 0;
	  break;
	}
	
      rc = mu_wordsplit_len (io->_imap_buf_base + io->_imap_ws.ws_endp,
			     io->_imap_buf_level - io->_imap_ws.ws_endp,
			     &io->_imap_ws, io->_imap_ws_flags);
      if (rc)
	{
	  rc = MU_ERR_PARSE;
	  break;
	}
      
      if (io->_imap_ws.ws_wordc == 0)
	break;
      
      last_arg = io->_imap_ws.ws_wordv[io->_imap_ws.ws_wordc - 1];
      if (last_arg[0] == '{' && last_arg[strlen (last_arg)-1] == '}')
	{
	  int rc;
	  unsigned long number;
	  char *sp = NULL;

	  if (!io->_imap_trace_payload)
	    xlev = mu_imapio_set_xscript_level (io, MU_XSCRIPT_PAYLOAD);
	  
	  number = strtoul (last_arg + 1, &sp, 10);
	  /* Client can ask for non-synchronised literal,
	     if a '+' is appended to the octet count. */
	  if (*sp == '}')
	    {
	      if (io->_imap_server)
		mu_stream_printf (io->_imap_stream, "+ GO AHEAD\n");
	    }
	  else if (*sp != '+')
	    break;

	  if (number + 1 > io->_imap_buf_size)
	    {
	      size_t newsize = number + 1;
	      void *newp = realloc (io->_imap_buf_base, newsize);
	      if (!newp)
		{
		  rc = ENOMEM;
		  break;
		}
	      io->_imap_buf_base = newp;
	      io->_imap_buf_size = newsize;
	    }
	      
          for (io->_imap_buf_level = 0; io->_imap_buf_level < number; )
            {
               size_t sz;
	       rc = mu_stream_read (io->_imap_stream,
				    io->_imap_buf_base + io->_imap_buf_level,
				    number - io->_imap_buf_level,
				    &sz);
               if (rc || sz == 0)
                 break;
               io->_imap_buf_level += sz;
            }
	  mu_imapio_set_xscript_level (io, xlev);
	  if (rc)
	    break;
	  io->_imap_buf_base[io->_imap_buf_level++] = 0;

	  free (last_arg);
	  io->_imap_ws.ws_wordv[--io->_imap_ws.ws_wordc] = NULL;
	  if (mu_wordsplit_len (io->_imap_buf_base, io->_imap_buf_level,
				&io->_imap_ws,
				io->_imap_ws_flags|MU_WRDSF_NOSPLIT))
	    {
	      rc = MU_ERR_PARSE;
	      break;
	    }
	}
      else
	break;
    }

  if (!io->_imap_trace_payload)
    mu_imapio_set_xscript_level (io, xlev);

  io->_imap_reply_ready = 1;
  return rc;
}
Пример #9
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;
}