#include <mailutils/stream.h>

 -- Function: int stream_create (stream_t *PSTREAM, int FLAGS, void *OWNER)

     MU_STREAM_READ
          The stream is open read only.

     MU_STREAM_WRITE
          The stream is open write only.

     MU_STREAM_RDWR
          The stream is open read and write.

     MU_STREAM_APPEND
          The stream is open in append mode for writing.

     MU_STREAM_CREAT
          The stream is created.

     MU_STREAM_NONBLOCK
          The stream is set non blocking.

     MU_STREAM_NO_CHECK
          Stream is destroyed without checking for the owner.

 -- Function: void stream_destroy (stream_t *PSTREAM, void *OWNER)

 -- Function: int stream_open (stream_t STREAM, const char *NAME, intPORT, int FLAG)

 -- Function: int stream_close (stream_t STREAM)

 -- Function: int stream_get_fd (stream_t STREAM, int *PFD)

 -- Function: int stream_read (stream_t STREAM, char *BUFFER, size_t BUFLEN, off_t OFFSET, size_t *PWRITEN)

 -- Function: int stream_readline (stream_t STREAM, char *BUFFER, size_t BUFLEN, off_t OFFSET, size_t *PWRITEN)

 -- Function: int stream_size (stream_t STREAM, off_t *PSIZE)

 -- Function: int stream_truncate (stream_t STREAM, off_t SIZE)

 -- Function: int stream_write (stream_t STREAM, const char *BUFFER, size_t BUFLEN, off_t OFFSET, size_t *PWRITEN)

 -- Function: int stream_flush (stream_t STREAM)

 -- Function: int stream_get_flags (stream_t STREAM, int *PFLAGS)

 -- Function: int stream_get_state (stream_t STREAM, int *PSTATE)

     MU_STREAM_STATE_OPEN
          Last action was stream_open.

     MU_STREAM_STATE_READ
          Last action was stream_read or stream_readline.

     MU_STREAM_STATE_WRITE
          Last action was stream_write.

     MU_STREAM_STATE_CLOSE
          Last action was stream_close.

 -- Function: int file_stream_create (stream_t *PSTREAM)

 -- Function: int mapfile_stream_create (stream_t *PSTREAM)

 -- Function: int encoder_stream_create (stream_t *PSTREAM, stream_t IOSTREAM, const char *ENCODING)

 -- Function: int decoder_stream_create (stream_t *PSTREAM, stream_t IOSTREAM, const char *ENCODING)

 -- Function: int tcp_stream_create (stream_t *PSTREAM)

An example using tcp_stream_create to make a simple web client:

     #include <stdlib.h>
     #include <stdio.h>
     #include <errno.h>
     #include <string.h>
     #include <unistd.h>
     #include <sys/select.h>

     #include <mailutils/io.h>

     const char *wbuf = "GET / HTTP/1.0\r\n\r\n";
     char rbuf[1024];

     int
     main(int argc, char **argv)
     {
       int ret, off = 0, fd;
       stream_t stream;
       size_t nb;
       fd_set fds;

       argc = argc, argv = argv;

       ret = tcp_stream_create (&stream);
       if (ret != 0)
         {
            fprintf (stderr, "tcp_stream_create: %s\n",
                     mailutils_error(ret));
            exit (EXIT_FAILURE);
         }

     connect_again:
       ret = stream_open (stream, "www.netscape.com", 80,
                          MU_STREAM_NONBLOCK);
       if (ret != 0)
         {
            if (ret == MU_ERROR_EAGAIN)
              {
                  ret = stream_get_fd(stream, &fd);
                  if (ret != 0)
                    {
                        fprintf (stderr, "stream_get_fd: %s\n",
                                 mailutils_error(ret));
                        exit (EXIT_FAILURE);
                    }
                    FD_ZERO (&fds);
                    FD_SET (fd, &fds);
                    select (fd+1, NULL, &fds, NULL, NULL);
                    goto connect_again;
               }
               fprintf (stderr, "stream_open: %s\n", mailutils_error (ret));
               exit (EXIT_FAILURE);
         }

         ret = stream_get_fd (stream, &fd);
         if (ret != 0)
           {
              fprintf(stderr, "stream_get_fd: %s\n", strerror(ret));
              exit (EXIT_FAILURE);
           }

     write_again:
         ret = stream_write (stream, wbuf + off, strlen (wbuf), 0, &nb);
         if (ret != 0 )
           {
              if (ret == EAGAIN)
                {
                   FD_ZERO (&fds);
                   FD_SET (fd, &fds);
                   select (fd + 1, NULL, &fds, NULL, NULL);
                   off += nb;
                   goto write_again;
                }
              fprintf (stderr, "stream_write: %s\n", strerror(ret));
              exit (EXIT_FAILURE)
           }

           if (nb != strlen (wbuf))
             {
                fprintf(stderr, "stream_write: %s\n", "nb != wbuf length");
                exit (EXIT_FAILURE);
             }

           do
             {
     read_again:
                ret = stream_read (stream, rbuf, sizeof (rbuf), 0, &nb);
                if (ret != 0)
                  {
                     if (ret == EAGAIN)
                       {
                          FD_ZERO (&fds);
                          FD_SET (fd, &fds);
                          select (fd + 1, &fds, NULL, NULL, NULL);
                          goto read_again;
                        }
                      fprintf (stderr, "stream_read: %s\n", strerror(ret));
                      exit(EXIT_FAILURE);
                   }
                   write (2, rbuf, nb);
              } while (nb);

              ret = stream_close (stream);
              if (ret!= 0)
                {
                   fprintf (stderr, "stream_close: %s\n", strerror(ret));
                   exit (EXIT_FAILURE);
                }

              stream_destroy (&stream, NULL);
              exit (EXIT_SUCCESS);
     }