Пример #1
0
/* Open the file.  For MU_STREAM_READ, the code tries mmap() first and fall
   back to normal file.  */
static int
mbox_open (mu_mailbox_t mailbox, int flags)
{
  mbox_data_t mud = mailbox->data;
  int status = 0;

  if (mud == NULL)
    return EINVAL;

  mailbox->flags = flags;

  /* Get a stream.  */
  if (mailbox->stream == NULL)
    {
      /* We do not try to mmap for CREAT or APPEND, it is not supported.  */
      status = (flags & MU_STREAM_CREAT)
	|| (mailbox->flags & MU_STREAM_APPEND);

      /* Try to mmap () the file first.  */
      if (status == 0)
	{
	  status = mu_mapfile_stream_create (&mailbox->stream, mud->name, mailbox->flags);
	  if (status == 0)
	    {
	      status = mu_stream_open (mailbox->stream);
	    }
	}

      /* Fall back to normal file if mmap() failed.  */
      if (status != 0)
	{
	  status = mu_file_stream_create (&mailbox->stream, mud->name, mailbox->flags);
	  if (status != 0)
	    return status;
	  status = mu_stream_open (mailbox->stream);
	}
      /* All failed, bail out.  */
      if (status != 0)
	{
	  mu_stream_destroy (&mailbox->stream, NULL);
	  return status;
	}
      /* Even on top of normal FILE *, lets agressively cache.  But this
	 may not be suitable for system tight on memory.  */
      mu_stream_setbufsiz (mailbox->stream, BUFSIZ);
    }
  else
    {
      status = mu_stream_open (mailbox->stream);
      if (status != 0)
	return status;
    }

  MU_DEBUG2 (mailbox->debug, MU_DEBUG_TRACE1, "mbox_open (%s, 0x%x)\n",
	     mud->name, mailbox->flags);

  if (mailbox->locker == NULL)
    status = mu_locker_create (&(mailbox->locker), mud->name, 0);
  return status;
}
Пример #2
0
int
mu_tcp_stream_create_from_sa (mu_stream_t *pstream,
			      struct mu_sockaddr *remote_addr,
			      struct mu_sockaddr *source_addr, int flags)
{
  int rc;
  mu_stream_t stream;
  struct _tcp_instance *tcp;

  tcp = _create_tcp_stream (flags | MU_STREAM_RDWR);
  if (!tcp)
    return ENOMEM;

  tcp->remote_addr = remote_addr;
  tcp->source_addr = source_addr;
  
  stream = (mu_stream_t) tcp;
  rc = mu_stream_open (stream);
  if (rc == 0 || rc == EAGAIN || rc == EINPROGRESS)
    *pstream = stream;
  else
    {
      /* Make sure sockaddrs are not freed on error */
      tcp->remote_addr = tcp->source_addr = NULL;
      mu_stream_destroy (&stream);
    }
  return rc;
}
Пример #3
0
int
mail_tmp_begin (struct mail_tmp **pmtmp, const char *from)
{
  int status;
  struct mail_tmp *mtmp = malloc (sizeof *mtmp);
  
  if (!mtmp)
    return ENOMEM;

  memset (mtmp, 0, sizeof *mtmp);

  mtmp->tempfile = mu_tempname (NULL);
  if ((status = mu_file_stream_create (&mtmp->stream, mtmp->tempfile,
				       MU_STREAM_RDWR)))
    {
      free (mtmp);
      maidag_error (_("unable to open temporary file: %s"),
		    mu_strerror (status));
      return status;
    }

  if ((status = mu_stream_open (mtmp->stream)))
    {
      free (mtmp);
      maidag_error (_("unable to open temporary file: %s"),
		    mu_strerror (status));
      return status;
    }
  mtmp->from = from;
  *pmtmp = mtmp;
  return 0;
}
Пример #4
0
/* Open the connection to the server. */
int
mu_nntp_connect (mu_nntp_t nntp)
{
  int status;

  /* Sanity checks.  */
  if (nntp == NULL)
    return EINVAL;

  /* A networking stack.  */
  if (nntp->carrier == NULL)
    return EINVAL;

  /* Enter the nntp state machine, and boogy  */
  switch (nntp->state)
    {
    default:
      /* FALLTHROUGH */
      /* If nntp was in an error state going through here should clear it.  */

    case MU_NNTP_NO_STATE:
      status = mu_nntp_disconnect (nntp);
      MU_NNTP_CHECK_EAGAIN (nntp, status);
      nntp->state = MU_NNTP_CONNECT;

    case MU_NNTP_CONNECT:
      /* Establish the connection.  */
      status = mu_stream_open (nntp->carrier);
      MU_NNTP_CHECK_EAGAIN (nntp, status);
      nntp->acknowledge = 0;
      nntp->state = MU_NNTP_GREETINGS;

    case MU_NNTP_GREETINGS:
      /* Get the greetings.  */
      {
	size_t len = 0;
	int code;
	status = mu_nntp_response (nntp, NULL, 0, &len);
	MU_NNTP_CHECK_EAGAIN (nntp, status);
	mu_nntp_debug_ack (nntp);
	/* 200 Service available, posting allowed */
	/* 201 Servie available, posting prohibited */
	code = mu_nntp_response_code(nntp);
	if (code != MU_NNTP_RESP_CODE_POSTING_ALLOWED && code != MU_NNTP_RESP_CODE_POSTING_PROHIBITED)
	  {
	    mu_stream_close (nntp->carrier);
	    nntp->state = MU_NNTP_NO_STATE;
	    return EACCES;
	  }
	nntp->state = MU_NNTP_NO_STATE;
      }
    } /* End AUTHORISATION state. */

  return status;
}
Пример #5
0
static PyObject *
api_stream_open (PyObject *self, PyObject *args)
{
  int status;
  PyStream *py_stm;

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

  status = mu_stream_open (py_stm->stm);
  return _ro (PyInt_FromLong (status));
}
Пример #6
0
static int
_iostream_open (struct _mu_stream *str)
{
  struct _mu_iostream *sp = (struct _mu_iostream *)str;
  int rc;
  rc = mu_stream_open (sp->transport[_MU_STREAM_INPUT]);
  if (rc)
    {
      sp->last_err_str = _MU_STREAM_INPUT;
      return rc;
    }
  if (sp->transport[_MU_STREAM_INPUT] != sp->transport[_MU_STREAM_OUTPUT])
    {
      rc = mu_stream_open (sp->transport[_MU_STREAM_OUTPUT]);
      if (rc)
	{
	  sp->last_err_str = _MU_STREAM_OUTPUT;
	  mu_stream_close (sp->transport[_MU_STREAM_INPUT]);
	}
    }
  return rc;
}
Пример #7
0
/* Display the contents of the given file on the terminal */
static void
display_file (const char *name)
{
  const char *pager = mh_global_profile_get ("moreproc", getenv ("PAGER"));

  if (pager)
    mh_spawnp (pager, name);
  else
    {
      mu_stream_t stream;
      int rc;
      size_t off = 0;
      size_t n;
      char buffer[512];
      
      rc = mu_file_stream_create (&stream, name, MU_STREAM_READ);
      if (rc)
	{
	  mu_error ("mu_file_stream_create: %s", mu_strerror (rc));
	  return;
	}
      rc = mu_stream_open (stream);
      if (rc)
	{
	  mu_error ("mu_stream_open: %s", mu_strerror (rc));
	  return;
	} 
      
      while (mu_stream_read (stream, buffer, sizeof buffer - 1, off, &n) == 0
	     && n != 0)
	{
	  buffer[n] = '\0';
	  printf ("%s", buffer);
	  off += n;
	}
      mu_stream_destroy (&stream, NULL);
    }
}      
Пример #8
0
static int
_streamref_open (struct _mu_stream *str)
{
  struct _mu_streamref *sp = (struct _mu_streamref *)str;
  return streamref_return (sp, mu_stream_open (sp->transport));
}
Пример #9
0
/* Open the connection to the server. The server sends an affirmative greeting
   that may contain a timestamp for APOP.  */
int
mu_pop3_connect (mu_pop3_t pop3)
{
  int status;

  /* Sanity checks.  */
  if (pop3 == NULL)
    return EINVAL;

  /* A networking stack.  */
  if (pop3->carrier == NULL)
    return EINVAL;

  /* Enter the pop state machine, and boogy: AUTHORISATION State.  */
  switch (pop3->state)
    {
    default:
      /* FALLTHROUGH */
      /* If pop3 was in an error state going through here should clear it.  */

    case MU_POP3_NO_STATE:
      /* If the stream was previoulsy open this is sudden death:
         for many pop servers, it is important to let them time to remove any locks or move
         the .user.pop files.  This happen when we do close() and immediately open().
         For example, the user does not want to read the entire file, and wants to start
	 to read a new message, closing the connection and immediately
	 contacting the server again, and he'll end up having
	 "-ERR Mail Lock busy" or something similar. To prevent this race
	 condition we sleep 2 seconds.  You can see this behaviour in an
	 environment where QPopper(Qualcomm POP3 server) is use and the user as a big mailbox. */
      status = mu_pop3_disconnect (pop3);
      if (status != 0)
        mu_pop3_sleep (2);
      pop3->state = MU_POP3_CONNECT;

    case MU_POP3_CONNECT:
      /* Establish the connection.  */
      status = mu_stream_open (pop3->carrier);
      MU_POP3_CHECK_EAGAIN (pop3, status);
      pop3->acknowledge = 0;
      pop3->state = MU_POP3_GREETINGS;

    case MU_POP3_GREETINGS:
      /* Get the greetings.  */
      {
	size_t len = 0;
	char *right, *left;
	status = mu_pop3_response (pop3, NULL, 0, &len);
	MU_POP3_CHECK_EAGAIN (pop3, status);
	mu_pop3_debug_ack (pop3);
	if (mu_c_strncasecmp (pop3->ack.buf, "+OK", 3) != 0)
	  {
	    mu_stream_close (pop3->carrier);
	    pop3->state = MU_POP3_NO_STATE;
	    return EACCES;
	  }

	/* Get the timestamp.  */
	right = memchr (pop3->ack.buf, '<', len);
	if (right)
	  {
	    len = len - (right - pop3->ack.buf);
	    left = memchr (right, '>', len);
	    if (left)
	      {
		len = left - right + 1;
		pop3->timestamp = calloc (len + 1, 1);
		if (pop3->timestamp == NULL)
		  {
		    mu_stream_close (pop3->carrier);
		    MU_POP3_CHECK_ERROR (pop3, ENOMEM);
		  }
		memcpy (pop3->timestamp, right, len);
	      }
	  }
	pop3->state = MU_POP3_NO_STATE;
      }
    } /* End AUTHORISATION state. */

  return status;
}