Пример #1
0
static int
top0 (msgset_t *mspec, mu_message_t msg, void *data)
{
  mu_stream_t stream;
  char *buf = NULL;
  size_t size = 0, n;
  int lines;
  
  if (mailvar_get (&lines, "toplines", mailvar_type_number, 1)
      || lines < 0)
    return 1;

  mu_message_get_streamref (msg, &stream);
  for (; lines > 0; lines--)
    {
      int status = mu_stream_getline (stream, &buf, &size, &n);
      if (status != 0 || n == 0)
	break;
      mu_printf ("%s", buf);
    }
  free (buf);
  mu_stream_destroy (&stream);
  set_cursor (mspec->msg_part[0]);

  util_mark_read (msg);

  return 0;
}
Пример #2
0
/* If we did not grap the ack already, call pop3_readline() but handle
   Nonblocking also.  */
int
mu_pop3_response (mu_pop3_t pop3, size_t *pnread)
{
  size_t n = 0;
  int status = 0;

  if (pop3 == NULL)
    return EINVAL;

  if (!MU_POP3_FISSET (pop3, MU_POP3_ACK))
    {
      status = mu_stream_getline (pop3->carrier, &pop3->ackbuf,
				  &pop3->acksize, NULL);
      if (status == 0)
	{
	  n = mu_rtrim_class (pop3->ackbuf, MU_CTYPE_SPACE);
	  MU_POP3_FSET (pop3, MU_POP3_ACK); /* Flag that we have the ack.  */
	}
    }
  else if (pop3->ackbuf)
    n = strlen (pop3->ackbuf);

  if (n < 3)
    status = MU_ERR_BADREPLY;
  else if (strncmp (pop3->ackbuf, "-ERR", 4) == 0)
    status = MU_ERR_REPLY;
  else if (strncmp (pop3->ackbuf, "+OK", 3))
    status = MU_ERR_BADREPLY;
  
  if (pnread)
    *pnread = n;
  return status;
}
Пример #3
0
int
pop_header_blurb (mu_stream_t stream, size_t maxlines,
		  char **pbuf, size_t *plen)
{
  int status;
  mu_opool_t opool;
  size_t size = 0;
  char *buf = NULL;
  size_t n;
  size_t nlines = 0;
  
  status = mu_opool_create (&opool, 0);
  if (status)
    return status;
      
  while ((status = mu_stream_getline (stream, &buf, &size, &n)) == 0 && n > 0)
    {
      size_t len = mu_rtrim_class (buf, MU_CTYPE_ENDLN);
      if (len == 0)
	break;
      mu_opool_append (opool, buf, len);
      mu_opool_append_char (opool, '\n');
      if (maxlines && ++nlines >= maxlines)
	break;
    }
      
  if (status == 0)
    {
      n = mu_opool_size (opool);
      if (n > size)
	{
	  char *p = realloc (buf, n);
	  if (!p)
	    {
	      free (buf);
	      status = ENOMEM;
	    }
	  else
	    buf = p;
	}
    }

  if (status == 0)
    {
      mu_opool_copy (opool, buf, n);
      *pbuf = buf;
      *plen = n;
    }
  else
    free (buf);
  mu_opool_destroy (&opool);

  return 0;
}
Пример #4
0
/* If we did not grap the ack already, call pop3_readline() but handle
   Nonblocking also.  */
int
mu_pop3_response (mu_pop3_t pop3, size_t *pnread)
{
  size_t n = 0;
  int status = 0;

  if (pop3 == NULL)
    return EINVAL;

  if (!MU_POP3_FISSET (pop3, MU_POP3_ACK))
    {
      status = mu_stream_getline (pop3->carrier, &pop3->ackbuf,
				  &pop3->acksize, NULL);
      if (status == 0)
	{
	  n = mu_rtrim_class (pop3->ackbuf, MU_CTYPE_SPACE);
	  MU_POP3_FSET (pop3, MU_POP3_ACK); /* Flag that we have the ack.  */
	}
      else
	{
	  /* Provide them with an error.  */
	  if (pop3->acksize < sizeof (POP3_DEFERR))
	    {
	      char *p = realloc (pop3->ackbuf, sizeof (POP3_DEFERR));
	      if (p)
		{
		  pop3->ackbuf = p;
		  pop3->acksize = sizeof (POP3_DEFERR);
		}
	    }
	  if (pop3->ackbuf)
	    strncpy (pop3->ackbuf, POP3_DEFERR, pop3->acksize);
	}
    }
  else if (pop3->ackbuf)
    n = strlen (pop3->ackbuf);

  if (n < 3)
    status = MU_ERR_BADREPLY;
  else if (strncmp (pop3->ackbuf, "-ERR", 4) == 0)
    status = MU_ERR_REPLY;
  else if (strncmp (pop3->ackbuf, "+OK", 3))
    status = MU_ERR_BADREPLY;
  
  if (pnread)
    *pnread = n;
  return status;
}
Пример #5
0
void
ioloop (char *id, mu_stream_t in, mu_stream_t out)
{
  char *buf = NULL;
  size_t size = 0, n;
  int rc;
  
  while ((rc = mu_stream_getline (in, &buf, &size, &n)) == 0 && n > 0)
    {
      if (rc)
	{
	  mu_error("%s: read error: %s", id, mu_stream_strerror (in, rc));
	  exit (1);
	}
      MU_ASSERT (mu_stream_write (out, buf, n, NULL));
    }
  mu_stream_flush (out);
  if (verbose)
    fprintf (stderr, "%s exited\n", id);
}
Пример #6
0
/* FIXME: Is it needed? */
int
mu_pop3_getline (mu_pop3_t pop3)
{
  size_t n;
  int status = mu_stream_getline (pop3->carrier, &pop3->rdbuf,
				  &pop3->rdsize, &n);
  if (status == 0)
    {
      if (n == 0)
	return EIO;
      n = mu_rtrim_class (pop3->rdbuf, MU_CTYPE_SPACE);

      /* When examining a multi-line response, the client checks to see if the
	 line begins with the termination octet "."(DOT). If yes and if octets
	 other than CRLF follow, the first octet of the line (the termination
	 octet) is stripped away.  */
      if (n >= 2 &&
	  pop3->rdbuf[0] == '.' &&
	  pop3->rdbuf[1] != '\n')
	memmove (pop3->rdbuf, pop3->rdbuf + 1, n);
    }
  return status;
}
Пример #7
0
int
mu_pop3_stream_to_list (mu_pop3_t pop3, mu_stream_t stream, mu_list_t list)
{
  int status;
  size_t n;
  
  while ((status = mu_stream_getline (stream, &pop3->rdbuf, &pop3->rdsize, &n))
	 == 0
	 && n > 0)
    {
      char *np = strdup (pop3->rdbuf);
      if (!np)
	{
	  status = ENOMEM;
	  break;
	}
      mu_rtrim_class (np, MU_CTYPE_SPACE);
      status = mu_list_append (list, np);
      if (status)
	break;
    }
  return status;
}
Пример #8
0
void
io_getline (char **pbuf, size_t *psize, size_t *pnbytes)
{
  size_t len;
  int rc = mu_stream_getline (iostream, pbuf, psize, &len);
  if (rc == 0)
    {
      char *s = *pbuf;

      if (len == 0)
        {
          imap4d_bye (ERR_NO_IFILE);
          /*FIXME rc = ECONNABORTED;*/
        }
      len = mu_rtrim_class (s, MU_CTYPE_ENDLN);
      if (pnbytes)
	*pnbytes = len;
    }
  else
    {
      mu_error (_("read error: %s"), mu_strerror (rc));
      imap4d_bye (ERR_NO_IFILE);
    }
}
Пример #9
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;
}