bug-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bugs and propositions for pop3d


From: Sergey Poznyakoff
Subject: bugs and propositions for pop3d
Date: Sat, 21 Apr 2001 20:42:27 +0300 (EET DST)

Hello,

I am trying to test pop3d from mailutils in real production environment.
The system is GNU/Linux with 2.2.6 kernel.

While configuring/building I have discovered some bugs. Further,
in the course of using the program I thought about some improvements
which may be useful. I do not suppose, though, that these improvements
agree with the authors' planes, so I am attaching to this message
two patch files. First of them contains proposed patches for the
bugs that prevented program from compiling/functioning. The second
one contains all the modifications I did so far. If you would wish to
try them, please use -p0 -l options to patch. I feel mailutils is a very
useful package, and would gladly contribute to its development.

I would like to discuss some difficulties I have encountered.
The essential fixes (those in attachment #1) address the following
issues:

 1. ENOTSUP and MAP_FAILED used in some sources may not be defined on
    some systems.
 2. ARGPINCS= in configure.in gets assigned a relative path, due
    to which the compilation fails if the package is configured with
    --srcdir=<path> option.
 3. Child process in pop3d/pop3d.c lacks call to exit(), so if
    pop3d is run as a daemon, any child after exiting from
    pop3_mainloop  tries to accept() from already closed socket
    and issues spurious error messages.
 4. pop3_sigchld() lacks signal() call, due to which the signal handler
    gets cleared after first SIGCHLD and all subsequent children, when
    finished, just hang around like zombies.


The proposed `improvements' (though the term may be argued, of course :)
address the following:

 1. Several sources from mailbox subdirectory call fprintf(stderr,...)
    to issue error messages. As the stderr usually gets connected to
    the output socket, the client program receives all these error
    messages and gets confused, since they do not start with
    rfc-compliant +OK, -ERR keywords. So I have added a module
    error.c and changed all these fprintf's to error()'s. Actual
    function that ouputs the messages can be supplied by the
    application using error_set_print() call. Source files
    mailbox/error.c and include/mailutils/error.h are contained in
    attachments 3 and 4.
 2. System administrators often prefere to have more information about
    unsuccessfull authentications. I have added more verbose logging
    to pop3d/user.c. Both failed attempts and possible account probes
    (USER immediately followed by QUIT) are logged.
 3. It is often convenient to separate log outputs from POP and SMTP
    servers. So, I have added --with-log-facility flag which allows
    to specify to which log facility the logging output should be
    directed.
 4. I have also made pop3d to be less verbose about its WELCOME
    prompt. When the symbol TERSE_MODE is defined, pop3d introduces
    itself just as
           +OK POP3 ready <apop_hash>     
    insead of divulging its type and version. This is a bit paranoid,
    but it is better to be on the safe side...

Finally, what seems to be a real problem is simultaneous access to
the maildrop. All locking/unlocking works just fine, but I have
come across the following situation: two sessions access the same
mailbox simultaneously, both do LIST, then one of them does
DELE on some message, then QUIT. The remaining session does a RETR
and dies miserably, since its internal indices are already out of sync
with the real maildrop contents. The comment on mbox_is_updated()
function addresses this but the function itself is never called.
So I added a call to mailbox_is_updated() to the pop3_mainloop()
function just before the processing of a keyword. Also I have added
ERR_MBOX_SYNC define to help handle the situation when
mbox_is_updated() bails out.
After these changes, the second session just gets the message

      -ERR Mailbox updated by other party or corrupt

and the connection is closed. This behaviour seems to be compatible
with RFC, but maybe it would be better to deny simultaneous
accesses altogether?      

Kind regards,
Sergey Poznyakoff
GNU Radius developer.
Index: acconfig.h
===================================================================
RCS file: /cvs/mailutils/acconfig.h,v
retrieving revision 1.6
diff -c -b -w -r1.6 acconfig.h
*** acconfig.h  2001/01/20 04:34:38     1.6
--- acconfig.h  2001/04/21 15:10:37
***************
*** 29,31 ****
--- 29,36 ----
  
  /* Define if using libreadline */
  #undef WITH_READLINE
+ 
+ @BOTTOM@
+ 
+ #undef LOG_FACILITY
+ 
Index: configure.in
===================================================================
RCS file: /cvs/mailutils/configure.in,v
retrieving revision 1.40
diff -c -b -w -r1.40 configure.in
*** configure.in        2001/04/20 04:37:47     1.40
--- configure.in        2001/04/21 15:10:37
***************
*** 42,47 ****
--- 42,57 ----
    *)   AC_MSG_ERROR(bad value ${withval} for --with-db) ;;
    esac],[usedb2=no])
  
+ AC_MSG_CHECKING(for log facility) 
+ log_facility="LOG_MAIL"
+ AC_ARG_WITH(log-facility,
+   [  --with-log-facility=facility   enable logging to the given facility],
+   AC_TRY_COMPILE([#include <syslog.h>],
+                   int lf = $withval,
+                   log_facility=$withval))
+ AC_DEFINE_UNQUOTED(LOG_FACILITY, $log_facility)
+ AC_MSG_RESULT($log_facility)
+ 
  dnl Check for headers
  AC_HEADER_STDC
  AC_HEADER_DIRENT
***************
*** 79,85 ****
        AC_REPLACE_FUNCS(strndup strnlen strchrnul)
        ARGPLIBS="../argp/libargp.a"
        ARGPLIB="libargp.a"
!       ARGPINCS="-I../argp"
        AC_SUBST(ARGPLIBS)
        AC_SUBST(ARGPLIB)
        AC_SUBST(ARGPINCS)
--- 89,95 ----
        AC_REPLACE_FUNCS(strndup strnlen strchrnul)
        ARGPLIBS="../argp/libargp.a"
        ARGPLIB="libargp.a"
!       ARGPINCS="-I\$(top_srcdir)/argp"
        AC_SUBST(ARGPLIBS)
        AC_SUBST(ARGPLIB)
        AC_SUBST(ARGPINCS)
Index: include/mailutils/stream.h
===================================================================
RCS file: /cvs/mailutils/include/mailutils/stream.h,v
retrieving revision 1.7
diff -c -b -w -r1.7 stream.h
*** include/mailutils/stream.h  2001/04/18 04:34:42     1.7
--- include/mailutils/stream.h  2001/04/21 15:10:50
***************
*** 34,39 ****
--- 34,43 ----
  # endif
  #endif /*__P */
  
+ #ifndef ENOTSUP
+ # define ENOTSUP EOPNOTSUPP
+ #endif
+ 
  struct _stream;
  typedef struct _stream *stream_t;
  
Index: mailbox/mapfile_stream.c
===================================================================
RCS file: /cvs/mailutils/mailbox/mapfile_stream.c,v
retrieving revision 1.10
diff -c -b -w -r1.10 mapfile_stream.c
*** mailbox/mapfile_stream.c    2001/04/18 04:34:42     1.10
--- mailbox/mapfile_stream.c    2001/04/21 15:11:03
***************
*** 34,39 ****
--- 34,42 ----
  #ifdef _POSIX_MAPPED_FILES
  #include <sys/mman.h>
  
+ #ifndef MAP_FAILED
+ # define MAP_FAILED (void*)-1
+ #endif
  
  struct _mapfile_stream
  {
Index: mailbox/mbx_mbox.c
===================================================================
RCS file: /cvs/mailutils/mailbox/mbx_mbox.c,v
retrieving revision 1.43
diff -c -b -w -r1.43 mbx_mbox.c
*** mailbox/mbx_mbox.c  2001/04/17 03:31:19     1.43
--- mailbox/mbx_mbox.c  2001/04/21 15:11:05
***************
*** 475,491 ****
  {
    off_t size = 0;
    mbox_data_t mud = mailbox->data;
!   if (stream_size (mailbox->stream, &size) != 0)
      return 0;
    if (size < mud->size)
      {
        observable_notify (mailbox->observable, MU_EVT_MAILBOX_CORRUPT);
        /* And be verbose.  ? */
        fprintf (stderr, "* BAD : Mailbox corrupted, shrank size\n");
        /* FIXME: should I crash.  */
        return 1;
      }
!   return (mud->size == size);
  }
  
  /* Try to create an uniq file, we no race conditions.   */
--- 475,491 ----
  {
    off_t size = 0;
    mbox_data_t mud = mailbox->data;
!   if (mud->size == 0 || stream_size (mailbox->stream, &size) != 0)
      return 0;
    if (size < mud->size)
      {
        observable_notify (mailbox->observable, MU_EVT_MAILBOX_CORRUPT);
        /* And be verbose.  ? */
        fprintf (stderr, "* BAD : Mailbox corrupted, shrank size\n");
        /* FIXME: should I crash.  */
        return 1;
      }
!   return (mud->size != size);
  }
  
  /* Try to create an uniq file, we no race conditions.   */
Index: pop3d/extra.c
===================================================================
RCS file: /cvs/mailutils/pop3d/extra.c,v
retrieving revision 1.10
diff -c -b -w -r1.10 extra.c
*** pop3d/extra.c       2001/02/02 04:00:10     1.10
--- pop3d/extra.c       2001/04/21 15:11:10
***************
*** 118,123 ****
--- 118,128 ----
        syslog (LOG_INFO, "No socket to send to");
        break;
  
+     case ERR_MBOX_SYNC:
+       syslog(LOG_ERR, "mailbox was updated by other party: %s", username);
+       fprintf(ofile, "-ERR Mailbox updated by other party or corrupt\r\n");
+       break;
+ 
      default:
        fprintf (ofile, "-ERR Quitting (reason unknown)\r\n");
        syslog (LOG_ERR, "Unknown quit");
***************
*** 156,162 ****
  void
  pop3_signal (int signo)
  {
!   (void)signo;
    pop3_abquit (ERR_SIGNAL);
  }
  
--- 161,167 ----
  void
  pop3_signal (int signo)
  {
!   syslog(LOG_CRIT, "got signal %d", signo);   
    pop3_abquit (ERR_SIGNAL);
  }
  
Index: pop3d/pop3d.c
===================================================================
RCS file: /cvs/mailutils/pop3d/pop3d.c,v
retrieving revision 1.22
diff -c -b -w -r1.22 pop3d.c
*** pop3d/pop3d.c       2001/04/16 02:26:31     1.22
--- pop3d/pop3d.c       2001/04/21 15:11:10
***************
*** 205,210 ****
--- 209,216 ----
    char *buf, *arg, *cmd;
    struct hostent *htbuf;
    char *local_hostname;
+   struct sockaddr_in cs;
+   int len;
  
    ifile = infile;
    ofile = fdopen (outfile, "w");
***************
*** 213,220 ****
    state = AUTHORIZATION;
    curr_time = time (NULL);
  
!   /* FIXME:  Retreive hostname with getpeername() and log.  */
!   syslog (LOG_INFO, "Incoming connection opened");
  
    /* Prepare the shared secret for APOP.  */
    local_hostname = malloc (MAXHOSTNAMELEN + 1);
--- 219,231 ----
    state = AUTHORIZATION;
    curr_time = time (NULL);
  
!   /* log information on the connecting client */
!   len = sizeof cs;
!   if (getpeername(infile, (struct sockaddr*)&cs, &len) < 0) 
!       syslog(LOG_ERR, "can't obtain IP address of client: %s",
!             strerror(errno));
!   else
!       syslog(LOG_INFO, "connect from %s", inet_ntoa(cs.sin_addr));
          
    /* Prepare the shared secret for APOP.  */
    local_hostname = malloc (MAXHOSTNAMELEN + 1);
***************
*** 248,253 ****
--- 264,272 ----
        cmd = pop3_cmd (buf);
        arg = pop3_args (buf);
  
+       if (state == TRANSACTION && mailbox_is_updated (mbox)) 
+       pop3_abquit(ERR_MBOX_SYNC);
+       
        if (strlen (arg) > POP_MAXCMDLEN || strlen (cmd) > POP_MAXCMDLEN)
        status = ERR_TOO_LONG;
        else if (strlen (cmd) > 4)
***************
*** 358,372 ****
--- 377,395 ----
      {
        if (children > maxchildren)
          {
+           syslog(LOG_ERR, "too many children");
            pause ();
            continue;
          }
+       
        connfd = accept (listenfd, (struct sockaddr *)&client, &size);
        if (connfd == -1)
          {
            if (errno == EINTR)
            continue;
            syslog (LOG_ERR, "accept: %s", strerror (errno));
            exit (-1);
          }
  
***************
*** 376,383 ****
        else if (pid == 0) /* Child.  */
          {
            close (listenfd);
-         /* syslog(); FIXME log the info on the connectiing client.  */
            pop3_mainloop (connfd, connfd);
          }
        else
          {
--- 399,406 ----
        else if (pid == 0) /* Child.  */
          {
            close (listenfd);
            pop3_mainloop (connfd, connfd);
+         exit(0);
          }
        else
          {
Index: pop3d/pop3d.h
===================================================================
RCS file: /cvs/mailutils/pop3d/pop3d.h,v
retrieving revision 1.14
diff -c -b -w -r1.14 pop3d.h
*** pop3d/pop3d.h       2001/04/14 20:17:27     1.14
--- pop3d/pop3d.h       2001/04/21 15:11:10
***************
*** 158,163 ****
--- 158,164 ----
  #define ERR_NO_OFILE    14
  #define ERR_TIMEOUT   15
  #define ERR_UNKNOWN   16
+ #define ERR_MBOX_SYNC   17
  
  #ifndef __P
  # ifdef __STDC__
Index: pop3d/signal.c
===================================================================
RCS file: /cvs/mailutils/pop3d/signal.c,v
retrieving revision 1.2
diff -c -b -w -r1.2 signal.c
*** pop3d/signal.c      2001/01/11 04:46:34     1.2
--- pop3d/signal.c      2001/04/21 15:11:11
***************
*** 8,14 ****
    pid_t pid;
    int status;
  
-   (void)signo;
    while ( (pid = waitpid(-1, &status, WNOHANG)) > 0)
        --children;
  }
--- 8,14 ----
    pid_t pid;
    int status;
  
    while ( (pid = waitpid(-1, &status, WNOHANG)) > 0)
        --children;
+   signal(signo, pop3_sigchld);
  }
Index: pop3d/user.c
===================================================================
RCS file: /cvs/mailutils/pop3d/user.c,v
retrieving revision 1.10
diff -c -b -w -r1.10 user.c
*** pop3d/user.c        2001/04/14 20:17:27     1.10
--- pop3d/user.c        2001/04/21 15:11:11
***************
*** 24,32 ****
  static char *_user;
  static int _perr = 0;
  
! #define PAM_ERROR if (_perr || (pamerror != PAM_SUCCESS)) { \
!     pam_end(pamh, 0); \
!     return ERR_BAD_LOGIN; }
  
  static int
  PAM_gnupop3d_conv (int num_msg, const struct pam_message **msg, struct 
pam_response **resp, void *appdata_ptr)
--- 24,31 ----
  static char *_user;
  static int _perr = 0;
  
! #define PAM_ERROR if (_perr || (pamerror != PAM_SUCCESS)) \
!     goto pam_errlab;  
  
  static int
  PAM_gnupop3d_conv (int num_msg, const struct pam_message **msg, struct 
pam_response **resp, void *appdata_ptr)
***************
*** 145,152 ****
--- 144,154 ----
          spw = getspnam ((char *)arg);
          if (spw == NULL || strcmp (spw->sp_pwdp, crypt (pass, spw->sp_pwdp)))
  #endif /* HAVE_SHADOW_H */
+         {        
+           syslog (LOG_INFO, "User '%s': authentication faled", arg);    
            return ERR_BAD_LOGIN;
          }
+       }
  #else /* !USE_LIBPAM */
        _user = (char *) arg;
        _pwd = pass;
***************
*** 160,167 ****
        PAM_ERROR;
        pamerror = pam_setcred (pamh, PAM_ESTABLISH_CRED);
        PAM_ERROR;
        pam_end (pamh, PAM_SUCCESS);
!       openlog ("gnu-pop3d", LOG_PID, LOG_MAIL);
  #endif /* USE_LIBPAM */
  
  
--- 162,174 ----
        PAM_ERROR;
        pamerror = pam_setcred (pamh, PAM_ESTABLISH_CRED);
        PAM_ERROR;
+ pam_errlab:      
        pam_end (pamh, PAM_SUCCESS);
!       openlog ("gnu-pop3d", LOG_PID, LOG_FACILITY);
!       if (pamerror != PAM_SUCCESS) {                          
!             syslog (LOG_INFO, "User '%s': authentication faled", _user);
!             return ERR_BAD_LOGIN;
!       }
  #endif /* USE_LIBPAM */
  
  
***************
*** 210,215 ****
--- 217,223 ----
      }
    else if (strcasecmp (cmd, "QUIT") == 0)
      {
+       syslog(LOG_INFO, "Possible probe of account '%s'", arg);            
        free (cmd);
        return pop3_quit (pass);
      }
Index: acconfig.h
===================================================================
RCS file: /cvs/mailutils/acconfig.h,v
retrieving revision 1.6
diff -c -b -w -r1.6 acconfig.h
*** acconfig.h  2001/01/20 04:34:38     1.6
--- acconfig.h  2001/04/21 15:10:37
***************
*** 29,31 ****
--- 29,36 ----
  
  /* Define if using libreadline */
  #undef WITH_READLINE
+ 
+ @BOTTOM@
+ 
+ #undef LOG_FACILITY
+ 
Index: configure.in
===================================================================
RCS file: /cvs/mailutils/configure.in,v
retrieving revision 1.40
diff -c -b -w -r1.40 configure.in
*** configure.in        2001/04/20 04:37:47     1.40
--- configure.in        2001/04/21 15:10:37
***************
*** 42,47 ****
--- 42,57 ----
    *)   AC_MSG_ERROR(bad value ${withval} for --with-db) ;;
    esac],[usedb2=no])
  
+ AC_MSG_CHECKING(for log facility) 
+ log_facility="LOG_MAIL"
+ AC_ARG_WITH(log-facility,
+   [  --with-log-facility=facility   enable logging to the given facility],
+   AC_TRY_COMPILE([#include <syslog.h>],
+                   int lf = $withval,
+                   log_facility=$withval))
+ AC_DEFINE_UNQUOTED(LOG_FACILITY, $log_facility)
+ AC_MSG_RESULT($log_facility)
+ 
  dnl Check for headers
  AC_HEADER_STDC
  AC_HEADER_DIRENT
***************
*** 79,85 ****
        AC_REPLACE_FUNCS(strndup strnlen strchrnul)
        ARGPLIBS="../argp/libargp.a"
        ARGPLIB="libargp.a"
!       ARGPINCS="-I../argp"
        AC_SUBST(ARGPLIBS)
        AC_SUBST(ARGPLIB)
        AC_SUBST(ARGPINCS)
--- 89,95 ----
        AC_REPLACE_FUNCS(strndup strnlen strchrnul)
        ARGPLIBS="../argp/libargp.a"
        ARGPLIB="libargp.a"
!       ARGPINCS="-I\$(top_srcdir)/argp"
        AC_SUBST(ARGPLIBS)
        AC_SUBST(ARGPLIB)
        AC_SUBST(ARGPINCS)
Index: doc/mailutils.texi
===================================================================
RCS file: /cvs/mailutils/doc/mailutils.texi,v
retrieving revision 1.16
diff -c -b -w -r1.16 mailutils.texi
*** doc/mailutils.texi  2001/04/05 04:20:16     1.16
--- doc/mailutils.texi  2001/04/21 15:10:41
***************
*** 158,164 ****
  @end group
  @end example
  
! For example writing a simple @command{from} command that will list the
  @emph{From} and @emph{Subject} headers of every mail in a folder.
  
  @example
--- 158,164 ----
  @end group
  @end example
  
! For example writing a simple @code{from} command that will list the
  @emph{From} and @emph{Subject} headers of every mail in a folder.
  
  @example
Index: include/mailutils/stream.h
===================================================================
RCS file: /cvs/mailutils/include/mailutils/stream.h,v
retrieving revision 1.7
diff -c -b -w -r1.7 stream.h
*** include/mailutils/stream.h  2001/04/18 04:34:42     1.7
--- include/mailutils/stream.h  2001/04/21 15:10:50
***************
*** 34,39 ****
--- 34,43 ----
  # endif
  #endif /*__P */
  
+ #ifndef ENOTSUP
+ # define ENOTSUP EOPNOTSUPP
+ #endif
+ 
  struct _stream;
  typedef struct _stream *stream_t;
  
Index: mailbox/Makefile.am
===================================================================
RCS file: /cvs/mailutils/mailbox/Makefile.am,v
retrieving revision 1.22
diff -c -b -w -r1.22 Makefile.am
*** mailbox/Makefile.am 2001/04/18 04:34:42     1.22
--- mailbox/Makefile.am 2001/04/21 15:10:59
***************
*** 19,24 ****
--- 19,25 ----
  auth.c \
  body.c \
  debug.c \
+ error.c \
  envelope.c \
  file_stream.c \
  filter.c \
Index: mailbox/file_stream.c
===================================================================
RCS file: /cvs/mailutils/mailbox/file_stream.c,v
retrieving revision 1.19
diff -c -b -w -r1.19 file_stream.c
*** mailbox/file_stream.c       2001/04/18 04:34:42     1.19
--- mailbox/file_stream.c       2001/04/21 15:11:00
***************
*** 30,35 ****
--- 30,36 ----
  #include <unistd.h>
  
  #include <mailutils/stream.h>
+ #include <mailutils/error.h>
  
  struct _file_stream
  {
***************
*** 265,271 ****
          fdbuf.st_nlink != 1 ||
          filebuf.st_nlink != 1 ||
          (fdbuf.st_mode & S_IFMT) != S_IFREG) {
!       fprintf(stderr,"%s must be a plain file with one link\n", filename);
        return EINVAL;
        }
      }
--- 266,272 ----
          fdbuf.st_nlink != 1 ||
          filebuf.st_nlink != 1 ||
          (fdbuf.st_mode & S_IFMT) != S_IFREG) {
!       error("%s must be a plain file with one link\n", filename);
        return EINVAL;
        }
      }
Index: mailbox/folder_imap.c
===================================================================
RCS file: /cvs/mailutils/mailbox/folder_imap.c,v
retrieving revision 1.16
diff -c -b -w -r1.16 folder_imap.c
*** mailbox/folder_imap.c       2001/04/16 21:05:51     1.16
--- mailbox/folder_imap.c       2001/04/21 15:11:02
***************
*** 40,45 ****
--- 40,46 ----
  #endif
  
  #include <imap0.h>
+ #include <mailutils/error.h>
  
  /* Variable use for the registrar.  */
  static struct _record _imap_record =
***************
*** 1509,1515 ****
                {
                  status = imap_rfc822_header (f_imap, &sp);
                }
!             /* else fprintf (stderr, "not supported RFC822 option\n");  */
            }
          else
            {
--- 1510,1516 ----
                {
                  status = imap_rfc822_header (f_imap, &sp);
                }
!             /* else error("not supported RFC822 option\n");  */
            }
          else
            {
***************
*** 1520,1526 ****
        {
          status = imap_uid (f_imap, &sp);
        }
!       /* else fprintf (stderr, "not supported FETCH command\n");  */
      }
    return status;
  }
--- 1521,1527 ----
        {
          status = imap_uid (f_imap, &sp);
        }
!       /* else error("not supported FETCH command\n");  */
      }
    return status;
  }
***************
*** 1737,1743 ****
        }
  #if 0
        /* Comment out to see all reading traffic.  */
!       fprintf (stderr, "\t\t%s", f_imap->buffer);
  #endif
  
        /* We do not want to step over f_imap->buffer since it can be use
--- 1738,1744 ----
        }
  #if 0
        /* Comment out to see all reading traffic.  */
!       error("\t\t%s", f_imap->buffer);
  #endif
  
        /* We do not want to step over f_imap->buffer since it can be use
***************
*** 1778,1784 ****
                      /* The human-readable text contains a special alert that
                         MUST be presented to the user in a fashion that calls
                         the user's attention to the message.  */
!                     fprintf (stderr, "ALERT: %s\n", (sp) ? sp : "");
                    }
                  else if (strcasecmp (subtag, "BADCHARSET") == 0)
                    {
--- 1779,1785 ----
                      /* The human-readable text contains a special alert that
                         MUST be presented to the user in a fashion that calls
                         the user's attention to the message.  */
!                     error("ALERT: %s\n", (sp) ? sp : "");
                    }
                  else if (strcasecmp (subtag, "BADCHARSET") == 0)
                    {
***************
*** 1885,1902 ****
                {
                  /* Not sure why we would get an untagged ok...but we do... */
                  /* Still should we be verbose about is ? */
!                 fprintf (stderr, "Untagged OK: %s\n", remainder);
                }
            }
          else if (strcasecmp (response, "NO") == 0)
            {
              /* This does not mean failure but rather a strong warning.  */
!             fprintf (stderr, "Untagged NO: %s\n", remainder);
            }
          else if (strcasecmp (response, "BAD") == 0)
            {
              /* We're dead, protocol/syntax error.  */
!             fprintf (stderr, "Untagged BAD: %s\n", remainder);
            }
          else if (strcasecmp (response, "PREAUTH") == 0)
            {
--- 1886,1903 ----
                {
                  /* Not sure why we would get an untagged ok...but we do... */
                  /* Still should we be verbose about is ? */
!                 error("Untagged OK: %s\n", remainder);
                }
            }
          else if (strcasecmp (response, "NO") == 0)
            {
              /* This does not mean failure but rather a strong warning.  */
!             error("Untagged NO: %s\n", remainder);
            }
          else if (strcasecmp (response, "BAD") == 0)
            {
              /* We're dead, protocol/syntax error.  */
!             error("Untagged BAD: %s\n", remainder);
            }
          else if (strcasecmp (response, "PREAUTH") == 0)
            {
***************
*** 1956,1962 ****
          else
            {
              /* Once again, check for something strange.  */
!             fprintf (stderr, "unknown untagged response: \"%s\"  %s\n",
                       response, remainder);
            }
        }
--- 1957,1963 ----
          else
            {
              /* Once again, check for something strange.  */
!             error("unknown untagged response: \"%s\"  %s\n",
                       response, remainder);
            }
        }
***************
*** 1980,1986 ****
                  folder_get_observable (f_imap->folder, &observable);
                  observable_notify (observable, MU_EVT_AUTHORITY_FAILED);
                }
!             fprintf (stderr, "NO/Bad Tagged: %s %s\n", response, remainder);
              status = EINVAL;
            }
        }
--- 1981,1987 ----
                  folder_get_observable (f_imap->folder, &observable);
                  observable_notify (observable, MU_EVT_AUTHORITY_FAILED);
                }
!             error("NO/Bad Tagged: %s %s\n", response, remainder);
              status = EINVAL;
            }
        }
Index: mailbox/mapfile_stream.c
===================================================================
RCS file: /cvs/mailutils/mailbox/mapfile_stream.c,v
retrieving revision 1.10
diff -c -b -w -r1.10 mapfile_stream.c
*** mailbox/mapfile_stream.c    2001/04/18 04:34:42     1.10
--- mailbox/mapfile_stream.c    2001/04/21 15:11:03
***************
*** 34,39 ****
--- 34,42 ----
  #ifdef _POSIX_MAPPED_FILES
  #include <sys/mman.h>
  
+ #ifndef MAP_FAILED
+ # define MAP_FAILED (void*)-1
+ #endif
  
  struct _mapfile_stream
  {
Index: mailbox/mbx_default.c
===================================================================
RCS file: /cvs/mailutils/mailbox/mbx_default.c,v
retrieving revision 1.7
diff -c -b -w -r1.7 mbx_default.c
*** mailbox/mbx_default.c       2001/01/16 06:14:52     1.7
--- mailbox/mbx_default.c       2001/04/21 15:11:03
***************
*** 29,34 ****
--- 29,35 ----
  #endif
  
  #include <mailutils/mailbox.h>
+ #include <mailutils/error.h>
  
  #ifndef _PATH_MAILDIR
  # define _PATH_MAILDIR "/usr/spool/mail"
***************
*** 69,75 ****
          user = (getenv ("LOGNAME")) ? getenv ("LOGNAME") : getenv ("USER");
          if (user == NULL)
            {
!             fprintf (stderr, "Who am I ?\n");
              return EINVAL;
            }
        }
--- 70,76 ----
          user = (getenv ("LOGNAME")) ? getenv ("LOGNAME") : getenv ("USER");
          if (user == NULL)
            {
!             error("Who am I ?\n");
              return EINVAL;
            }
        }
Index: mailbox/mbx_imap.c
===================================================================
RCS file: /cvs/mailutils/mailbox/mbx_imap.c,v
retrieving revision 1.25
diff -c -b -w -r1.25 mbx_imap.c
*** mailbox/mbx_imap.c  2001/04/14 20:17:27     1.25
--- mailbox/mbx_imap.c  2001/04/21 15:11:04
***************
*** 29,34 ****
--- 29,35 ----
  #include <time.h>
  
  #include <mailutils/address.h>
+ #include <mailutils/error.h>
  #include <mailbox0.h>
  #include <registrar0.h>
  #include <imap0.h>
***************
*** 636,642 ****
              f_imap->state = IMAP_NO_STATE;
  
            default:
!             /* fprintf (stderr, "imap_expunge: unknow state\n"); */
              break;
            } /* switch (state) */
          } /* message_get_attribute() */
--- 637,643 ----
              f_imap->state = IMAP_NO_STATE;
  
            default:
!             /* error("imap_expunge: unknow state\n"); */
              break;
            } /* switch (state) */
          } /* message_get_attribute() */
***************
*** 859,865 ****
        MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer);
  
      default:
!       /* fprintf (stderr, "imap_expunge: unknow state\n"); */
        break;
      }
    f_imap->state = IMAP_NO_STATE;
--- 860,866 ----
        MAILBOX_DEBUG0 (m_imap->mailbox, MU_DEBUG_PROT, f_imap->buffer);
  
      default:
!       /* error("imap_expunge: unknow state\n"); */
        break;
      }
    f_imap->state = IMAP_NO_STATE;
Index: mailbox/mbx_mbox.c
===================================================================
RCS file: /cvs/mailutils/mailbox/mbx_mbox.c,v
retrieving revision 1.43
diff -c -b -w -r1.43 mbx_mbox.c
*** mailbox/mbx_mbox.c  2001/04/17 03:31:19     1.43
--- mailbox/mbx_mbox.c  2001/04/21 15:11:05
***************
*** 54,59 ****
--- 54,60 ----
  #include <mailutils/body.h>
  #include <mailutils/header.h>
  #include <mailutils/attribute.h>
+ #include <mailutils/error.h>
  #include <registrar0.h>
  #include <mailbox0.h>
  
***************
*** 105,111 ****
  #define H_X_UIDL                    14
    "X-UIDL"
  };
- 
  /* Keep the file positions of where the headers and bodies start and end.
     attr_flags is the "Status:" message.  */
  struct _mbox_message
--- 106,111 ----
***************
*** 475,491 ****
  {
    off_t size = 0;
    mbox_data_t mud = mailbox->data;
!   if (stream_size (mailbox->stream, &size) != 0)
      return 0;
    if (size < mud->size)
      {
        observable_notify (mailbox->observable, MU_EVT_MAILBOX_CORRUPT);
        /* And be verbose.  ? */
!       fprintf (stderr, "* BAD : Mailbox corrupted, shrank size\n");
        /* FIXME: should I crash.  */
        return 1;
      }
!   return (mud->size == size);
  }
  
  /* Try to create an uniq file, we no race conditions.   */
--- 475,491 ----
  {
    off_t size = 0;
    mbox_data_t mud = mailbox->data;
!   if (mud->size == 0 || stream_size (mailbox->stream, &size) != 0)
      return 0;
    if (size < mud->size)
      {
        observable_notify (mailbox->observable, MU_EVT_MAILBOX_CORRUPT);
        /* And be verbose.  ? */
!       error("* BAD : Mailbox corrupted, shrank size");
        /* FIXME: should I crash.  */
        return 1;
      }
!   return (mud->size != size);
  }
  
  /* Try to create an uniq file, we no race conditions.   */
***************
*** 591,597 ****
      {
        if (tmpmboxname)
        free (tmpmboxname);
!       fprintf (stderr, "Failed to create temporary file when expunging.\n");
        return errno;
      }
  
--- 591,597 ----
      {
        if (tmpmboxname)
        free (tmpmboxname);
!       error("Failed to create temporary file when expunging.");
        return errno;
      }
  
***************
*** 651,657 ****
        mailbox_destroy (&tmpmailbox);
        remove (tmpmboxname);
        free (tmpmboxname);
!       fprintf (stderr, "Failed to grab the lock\n");
        return ENOLCK;
      }
  
--- 651,657 ----
        mailbox_destroy (&tmpmailbox);
        remove (tmpmboxname);
        free (tmpmboxname);
!       error("Failed to grab the lock");
        return ENOLCK;
      }
  
***************
*** 703,709 ****
              status = mbox_get_message (mailbox, i, &msg);
              if (status != 0)
                {
!                 fprintf (stderr, "Error expunge:%d: %s", __LINE__,
                           strerror (status));
                  goto bailout0;
                }
--- 703,709 ----
              status = mbox_get_message (mailbox, i, &msg);
              if (status != 0)
                {
!                 error("Error %s:%d: %s", __FILE__, __LINE__,
                          strerror (status));
                  goto bailout0;
                }
***************
*** 712,718 ****
                                         &total, 1, (i == save_imapbase));
          if (status != 0)
            {
!             fprintf (stderr, "Error expunge:%d: %s", __LINE__,
                       strerror (status));
              goto bailout0;
            }
--- 712,718 ----
                                         &total, 1, (i == save_imapbase));
          if (status != 0)
            {
!             error("Error %s:%d: %s", __FILE__, __LINE__,
                       strerror (status));
              goto bailout0;
            }
***************
*** 735,741 ****
                  || (status = stream_write (tmpmailbox->stream, buffer, n,
                                             total, &n) != 0))
                {
!                 fprintf (stderr, "Error expunge:%d: %s", __LINE__,
                           strerror (status));
                  goto bailout0;
                }
--- 735,741 ----
                  || (status = stream_write (tmpmailbox->stream, buffer, n,
                                             total, &n) != 0))
                {
!                 error("Error %s:%d: %s", __FILE__, __LINE__,
                           strerror (status));
                  goto bailout0;
                }
***************
*** 747,753 ****
          status = stream_write (tmpmailbox->stream, "\n", 1, total, &n);
          if (status != 0)
            {
!             fprintf (stderr, "Error expunge:%d: %s", __LINE__,
                       strerror (status));
              goto bailout0;
            }
--- 747,753 ----
          status = stream_write (tmpmailbox->stream, "\n", 1, total, &n);
          if (status != 0)
            {
!             error("Error %s:%d: %s", __FILE__, __LINE__,
                       strerror (status));
              goto bailout0;
            }
***************
*** 777,783 ****
                                       total, &n);
                if (status != 0)
                  {
!                   fprintf (stderr, "Error expunge:%d: %s", __LINE__,
                             strerror (status));
                    goto bailout0;
                  }
--- 777,783 ----
                                       total, &n);
                if (status != 0)
                  {
!                   error("Error %s:%d: %s", __FILE__, __LINE__,
                             strerror (status));
                    goto bailout0;
                  }
***************
*** 788,794 ****
        else if (len < 0)
          {
            /* Corrupted mailbox.  */
!           fprintf (stderr, "Error expunge:%d: %s", __LINE__,
                     strerror (status));
            goto bailout0;
          }
--- 788,794 ----
        else if (len < 0)
          {
            /* Corrupted mailbox.  */
!           error("Error %s:%d: %s", __FILE__, __LINE__,
                     strerror (status));
            goto bailout0;
          }
***************
*** 809,815 ****
          status = stream_write (mailbox->stream, buffer, n, offset, &n);
          if (status != 0)
            {
!             fprintf (stderr, "Error expunge:%d: %s\n", __LINE__,
                       strerror (status));
              goto bailout;
            }
--- 809,815 ----
          status = stream_write (mailbox->stream, buffer, n, offset, &n);
          if (status != 0)
            {
!             error("Error %s:%d: %s\n", __FILE__, __LINE__,
                       strerror (status));
              goto bailout;
            }
***************
*** 823,829 ****
    status = stream_truncate (mailbox->stream, total + marker);
    if (status != 0)
      {
!       fprintf (stderr, "Error expunging:%d: %s\n", __LINE__,
               strerror (status));
        goto bailout;
      }
--- 823,829 ----
    status = stream_truncate (mailbox->stream, total + marker);
    if (status != 0)
      {
!       error("Error %s:%d: %s\n", __FILE__, __LINE__,
               strerror (status));
        goto bailout;
      }
***************
*** 1247,1253 ****
    message_t msg = NULL;
  
    /* Sanity checks.  */
!   if (pmsg == NULL || mud == NULL)
      return EINVAL;
  
    /* If we did not start a scanning yet do it now.  */
--- 1247,1253 ----
    message_t msg = NULL;
  
    /* Sanity checks.  */
!   if (pmsg == NULL || mud == NULL || mbox_is_updated(mailbox))
      return EINVAL;
  
    /* If we did not start a scanning yet do it now.  */
***************
*** 1400,1406 ****
  }
  
  /* FIXME: We need to escape body line that begins with "From ", this
!    will required to read the body by line instead of by chuncks hurting
     perfomance big time when expunging.  But should not this be the
     responsability of the client ?  */
  static int
--- 1400,1406 ----
  }
  
  /* FIXME: We need to escape body line that begins with "From ", this
!    will require to read the body line by line instead of by chunks hurting
     perfomance big time when expunging.  But should not this be the
     responsability of the client ?  */
  static int
Index: mailbox/mbx_pop.c
===================================================================
RCS file: /cvs/mailutils/mailbox/mbx_pop.c,v
retrieving revision 1.45
diff -c -b -w -r1.45 mbx_pop.c
*** mailbox/mbx_pop.c   2001/04/16 21:05:51     1.45
--- mailbox/mbx_pop.c   2001/04/21 15:11:06
***************
*** 43,48 ****
--- 43,49 ----
  #include <mailutils/attribute.h>
  #include <mailutils/url.h>
  #include <mailutils/auth.h>
+ #include <mailutils/error.h>
  #include <mailbox0.h>
  #include <registrar0.h>
  
***************
*** 452,458 ****
    return 0;
  }
  
! /* Open the connection to the sever, and send the authentication.
     FIXME: Should also send the CAPA command to detect for example the suport
     for TOP, APOP, ... and DTRT(Do The Right Thing).  */
  static int
--- 453,459 ----
    return 0;
  }
  
! /* Open the connection to the server, and send the authentication.
     FIXME: Should also send the CAPA command to detect for example the suport
     for TOP, APOP, ... and DTRT(Do The Right Thing).  */
  static int
***************
*** 578,584 ****
  
      default:
        /*
!       fprintf (stderr, "pop_open unknown state\n");
        */
        break;
      }/* End AUTHORISATION state. */
--- 579,585 ----
  
      default:
        /*
!       error("pop_open unknown state\n");
        */
        break;
      }/* End AUTHORISATION state. */
***************
*** 634,646 ****
          lets just be verbose about the error but close the connection
          anyway.  */
        if (strncasecmp (mpd->buffer, "+OK", 3) != 0)
!       fprintf (stderr, "pop_close: %s\n", mpd->buffer);
        stream_close (mbox->stream);
        break;
  
      default:
        /*
!       fprintf (stderr, "pop_close unknow state");
        */
        break;
      } /* UPDATE state.  */
--- 635,647 ----
          lets just be verbose about the error but close the connection
          anyway.  */
        if (strncasecmp (mpd->buffer, "+OK", 3) != 0)
!       error("pop_close: %s\n", mpd->buffer);
        stream_close (mbox->stream);
        break;
  
      default:
        /*
!       error("pop_close unknow state");
        */
        break;
      } /* UPDATE state.  */
***************
*** 881,887 ****
  
      default:
        /*
!       fprintf (stderr, "pop_messages_count: unknow state\n");
        */
        break;
      }
--- 882,888 ----
  
      default:
        /*
!       error("pop_messages_count: unknow state\n");
        */
        break;
      }
***************
*** 996,1002 ****
                  break;
  
                default:
!                 /* fprintf (stderr, "pop_expunge: unknow state\n"); */
                  break;
                } /* switch (state) */
            } /* if attribute_is_deleted() */
--- 997,1003 ----
                  break;
  
                default:
!                 /* error("pop_expunge: unknow state\n"); */
                  break;
                } /* switch (state) */
            } /* if attribute_is_deleted() */
***************
*** 1086,1092 ****
  
      default:
        /*
!       fprintf (stderr, "pop_message_size state\n");
        */
        break;
      }
--- 1087,1093 ----
  
      default:
        /*
!       error("pop_message_size state\n");
        */
        break;
      }
***************
*** 1211,1217 ****
    return 0;
  }
  
! /* Get the UIDL.  Client should be prepare since it may fail.  UIDL is
     optional on many POP servers.
     FIXME:  We should check this with CAPA and fall back to a md5 scheme ?
     Or maybe check for "X-UIDL" a la Qpopper ?  */
--- 1212,1218 ----
    return 0;
  }
  
! /* Get the UIDL.  Client should be prepared since it may fail.  UIDL is
     optional on many POP servers.
     FIXME:  We should check this with CAPA and fall back to a md5 scheme ?
     Or maybe check for "X-UIDL" a la Qpopper ?  */
***************
*** 1277,1283 ****
  
      default:
        /*
!       fprintf (stderr, "pop_uidl state\n");
        */
        break;
      }
--- 1278,1284 ----
  
      default:
        /*
!       error("pop_uidl state\n");
        */
        break;
      }
***************
*** 1371,1377 ****
        MAILBOX_DEBUG0 (mpd->mbox, MU_DEBUG_PROT, mpd->buffer);
        if (strncasecmp (mpd->buffer, "+OK", 3) != 0)
        {
!         /* fprintf (stderr, "TOP not implemented\n"); */
          /* Fall back to RETR call.  */
          mpd->state = POP_NO_STATE;
          mpm->skip_header = 0;
--- 1372,1378 ----
        MAILBOX_DEBUG0 (mpd->mbox, MU_DEBUG_PROT, mpd->buffer);
        if (strncasecmp (mpd->buffer, "+OK", 3) != 0)
        {
!         /* error("TOP not implemented\n"); */
          /* Fall back to RETR call.  */
          mpd->state = POP_NO_STATE;
          mpm->skip_header = 0;
***************
*** 1730,1736 ****
        /* A convenient break, this is here we can return 0, we're done.  */
  
      default:
!       /* fprintf (stderr, "pop_retr unknow state\n"); */
        break;
      } /* Switch state.  */
  
--- 1731,1737 ----
        /* A convenient break, this is here we can return 0, we're done.  */
  
      default:
!       /* error("pop_retr unknow state\n"); */
        break;
      } /* Switch state.  */
  
Index: mailbox/message.c
===================================================================
RCS file: /cvs/mailutils/mailbox/message.c,v
retrieving revision 1.48
diff -c -b -w -r1.48 message.c
*** mailbox/message.c   2001/04/10 05:13:51     1.48
--- mailbox/message.c   2001/04/21 15:11:07
***************
*** 258,264 ****
      return EINVAL;
    if (msg->owner != owner)
       return EACCES;
!   /* Make sure we destoy the old if it was own by the mesg */
    /* FIXME:  I do not know if somebody has already a ref on this ? */
    if (msg->header)
      header_destroy (&(msg->header), msg);
--- 258,264 ----
      return EINVAL;
    if (msg->owner != owner)
       return EACCES;
!   /* Make sure we destroy the old if it was own by the mesg */
    /* FIXME:  I do not know if somebody has already a ref on this ? */
    if (msg->header)
      header_destroy (&(msg->header), msg);
Index: mailbox/stream.c
===================================================================
RCS file: /cvs/mailutils/mailbox/stream.c,v
retrieving revision 1.10
diff -c -b -w -r1.10 stream.c
*** mailbox/stream.c    2001/04/05 04:17:09     1.10
--- mailbox/stream.c    2001/04/21 15:11:09
***************
*** 35,40 ****
--- 35,41 ----
  #include <string.h>
  
  #include <stream0.h>
+ #include <mailutils/error.h>
  
  static int refill (stream_t, off_t);
  
***************
*** 335,341 ****
              (void)memcpy ((void *)s, (void *)p, len);
              total += len;
              s[len] = 0;
!             //fprintf (stderr, ":%d %d:%s", len, total, s);
              if (pnread)
                *pnread = total;
              return 0;
--- 336,342 ----
              (void)memcpy ((void *)s, (void *)p, len);
              total += len;
              s[len] = 0;
!             //error(":%d %d:%s", len, total, s);
              if (pnread)
                *pnread = total;
              return 0;
***************
*** 344,356 ****
          is->rbuffer.ptr += len;
          is->rbuffer.offset += len;
          (void)memcpy((void *)s, (void *)p, len);
!         //fprintf (stderr, "!:%d %d\n", len, total);
          total += len;
          s += len;
          count -= len;
          }
        *s = 0;
!       //fprintf (stderr, "1:%s", s);
        if (pnread)
        *pnread = s - buf;
      }
--- 345,357 ----
          is->rbuffer.ptr += len;
          is->rbuffer.offset += len;
          (void)memcpy((void *)s, (void *)p, len);
!         //error("!:%d %d\n", len, total);
          total += len;
          s += len;
          count -= len;
          }
        *s = 0;
!       //error("1:%s", s);
        if (pnread)
        *pnread = s - buf;
      }
***************
*** 627,635 ****
        status = stream->_read (stream, stream->rbuffer.ptr,
                              stream->rbuffer.bufsiz, offset,
                              (size_t *)&(stream->rbuffer.count));
!       //fprintf (stderr, "COUNT%d\n", stream->rbuffer.count);
        //stream->rbuffer.ptr[stream->rbuffer.count] = 0;
!       //fprintf (stderr, "%s\n", stream->rbuffer.ptr);
        return status;
      }
    return ENOTSUP;
--- 628,636 ----
        status = stream->_read (stream, stream->rbuffer.ptr,
                              stream->rbuffer.bufsiz, offset,
                              (size_t *)&(stream->rbuffer.count));
!       //error("COUNT%d\n", stream->rbuffer.count);
        //stream->rbuffer.ptr[stream->rbuffer.count] = 0;
!       //error("%s\n", stream->rbuffer.ptr);
        return status;
      }
    return ENOTSUP;
Index: pop3d/capa.c
===================================================================
RCS file: /cvs/mailutils/pop3d/capa.c,v
retrieving revision 1.3
diff -c -b -w -r1.3 capa.c
*** pop3d/capa.c        2001/01/29 06:13:03     1.3
--- pop3d/capa.c        2001/04/21 15:11:10
***************
*** 31,38 ****
--- 31,40 ----
    fprintf (ofile, "USER\r\n");
    fprintf (ofile, "UIDL\r\n");
    fprintf (ofile, "RESP-CODES\r\n");
+ #ifndef TERSE_MODE
    if (state == TRANSACTION)   /* let's not advertise to just anyone */
      fprintf (ofile, "IMPLEMENTATION %s %s\r\n", IMPL, VERSION);
+ #endif
    fprintf (ofile, ".\r\n");
    return OK;
  }
Index: pop3d/extra.c
===================================================================
RCS file: /cvs/mailutils/pop3d/extra.c,v
retrieving revision 1.10
diff -c -b -w -r1.10 extra.c
*** pop3d/extra.c       2001/02/02 04:00:10     1.10
--- pop3d/extra.c       2001/04/21 15:11:10
***************
*** 118,123 ****
--- 118,128 ----
        syslog (LOG_INFO, "No socket to send to");
        break;
  
+     case ERR_MBOX_SYNC:
+       syslog(LOG_ERR, "mailbox was updated by other party: %s", username);
+       fprintf(ofile, "-ERR Mailbox updated by other party or corrupt\r\n");
+       break;
+ 
      default:
        fprintf (ofile, "-ERR Quitting (reason unknown)\r\n");
        syslog (LOG_ERR, "Unknown quit");
***************
*** 156,162 ****
  void
  pop3_signal (int signo)
  {
!   (void)signo;
    pop3_abquit (ERR_SIGNAL);
  }
  
--- 161,167 ----
  void
  pop3_signal (int signo)
  {
!   syslog(LOG_CRIT, "got signal %d", signo);   
    pop3_abquit (ERR_SIGNAL);
  }
  
Index: pop3d/pop3d.c
===================================================================
RCS file: /cvs/mailutils/pop3d/pop3d.c,v
retrieving revision 1.22
diff -c -b -w -r1.22 pop3d.c
*** pop3d/pop3d.c       2001/04/16 02:26:31     1.22
--- pop3d/pop3d.c       2001/04/21 15:11:10
***************
*** 49,54 ****
--- 49,57 ----
  
  const char *short_options ="d::hip:t:v";
  
+ static void syslog_error_printer(const char *fmt, va_list ap);
+ 
+ 
  int
  main (int argc, char **argv)
  {
***************
*** 127,133 ****
    signal (SIGILL, pop3_signal);
    signal (SIGBUS, pop3_signal);
    signal (SIGFPE, pop3_signal);
!   signal (SIGSEGV, pop3_signal);
    signal (SIGTERM, pop3_signal);
    signal (SIGSTOP, pop3_signal);
    signal (SIGPIPE, pop3_signal);
--- 130,136 ----
    signal (SIGILL, pop3_signal);
    signal (SIGBUS, pop3_signal);
    signal (SIGFPE, pop3_signal);
!   signal (SIGSEGV, pop3_signal);
    signal (SIGTERM, pop3_signal);
    signal (SIGSTOP, pop3_signal);
    signal (SIGPIPE, pop3_signal);
***************
*** 142,148 ****
    chdir ("/");
  
    /* Set up for syslog.  */
!   openlog ("gnu-pop3d", LOG_PID, LOG_MAIL);
  
    umask (S_IROTH | S_IWOTH | S_IXOTH);        /* 007 */
  
--- 145,152 ----
    chdir ("/");
  
    /* Set up for syslog.  */
!   openlog ("gnu-pop3d", LOG_PID, LOG_FACILITY);
!   error_set_print(syslog_error_printer);
    
    umask (S_IROTH | S_IWOTH | S_IXOTH);        /* 007 */
  
***************
*** 205,210 ****
--- 209,216 ----
    char *buf, *arg, *cmd;
    struct hostent *htbuf;
    char *local_hostname;
+   struct sockaddr_in cs;
+   int len;
  
    ifile = infile;
    ofile = fdopen (outfile, "w");
***************
*** 213,220 ****
    state = AUTHORIZATION;
    curr_time = time (NULL);
  
!   /* FIXME:  Retreive hostname with getpeername() and log.  */
!   syslog (LOG_INFO, "Incoming connection opened");
  
    /* Prepare the shared secret for APOP.  */
    local_hostname = malloc (MAXHOSTNAMELEN + 1);
--- 219,231 ----
    state = AUTHORIZATION;
    curr_time = time (NULL);
  
!   /* log information on the connecting client */
!   len = sizeof cs;
!   if (getpeername(infile, (struct sockaddr*)&cs, &len) < 0) 
!       syslog(LOG_ERR, "can't obtain IP address of client: %s",
!             strerror(errno));
!   else
!       syslog(LOG_INFO, "connect from %s", inet_ntoa(cs.sin_addr));
          
    /* Prepare the shared secret for APOP.  */
    local_hostname = malloc (MAXHOSTNAMELEN + 1);
***************
*** 238,245 ****
--- 249,261 ----
    free (local_hostname);
  
    fflush (ofile);
+ #ifdef TERSE_MODE
+ # undef WELCOME
+ # define WELCOME "ready"
+ #endif  
    fprintf (ofile, "+OK POP3 " WELCOME " %s\r\n", md5shared);
  
+   
    while (state != UPDATE)
      {
        fflush (ofile);
***************
*** 248,253 ****
--- 264,272 ----
        cmd = pop3_cmd (buf);
        arg = pop3_args (buf);
  
+       if (state == TRANSACTION && mailbox_is_updated (mbox)) 
+       pop3_abquit(ERR_MBOX_SYNC);
+       
        if (strlen (arg) > POP_MAXCMDLEN || strlen (cmd) > POP_MAXCMDLEN)
        status = ERR_TOO_LONG;
        else if (strlen (cmd) > 4)
***************
*** 358,372 ****
--- 377,395 ----
      {
        if (children > maxchildren)
          {
+           syslog(LOG_ERR, "too many children");
            pause ();
            continue;
          }
+       
        connfd = accept (listenfd, (struct sockaddr *)&client, &size);
        if (connfd == -1)
          {
            if (errno == EINTR)
            continue;
            syslog (LOG_ERR, "accept: %s", strerror (errno));
+         if (errno==0)
+                 continue;
            exit (-1);
          }
  
***************
*** 376,383 ****
        else if (pid == 0) /* Child.  */
          {
            close (listenfd);
-         /* syslog(); FIXME log the info on the connectiing client.  */
            pop3_mainloop (connfd, connfd);
          }
        else
          {
--- 399,406 ----
        else if (pid == 0) /* Child.  */
          {
            close (listenfd);
            pop3_mainloop (connfd, connfd);
+         exit(0);
          }
        else
          {
***************
*** 385,388 ****
--- 408,417 ----
          }
        close (connfd);
      }
+ }
+ 
+ 
+ void syslog_error_printer(const char *fmt, va_list ap)
+ {
+     vsyslog(LOG_CRIT, fmt, ap);
  }
Index: pop3d/pop3d.h
===================================================================
RCS file: /cvs/mailutils/pop3d/pop3d.h,v
retrieving revision 1.14
diff -c -b -w -r1.14 pop3d.h
*** pop3d/pop3d.h       2001/04/14 20:17:27     1.14
--- pop3d/pop3d.h       2001/04/21 15:11:10
***************
*** 158,163 ****
--- 158,164 ----
  #define ERR_NO_OFILE    14
  #define ERR_TIMEOUT   15
  #define ERR_UNKNOWN   16
+ #define ERR_MBOX_SYNC   17
  
  #ifndef __P
  # ifdef __STDC__
Index: pop3d/signal.c
===================================================================
RCS file: /cvs/mailutils/pop3d/signal.c,v
retrieving revision 1.2
diff -c -b -w -r1.2 signal.c
*** pop3d/signal.c      2001/01/11 04:46:34     1.2
--- pop3d/signal.c      2001/04/21 15:11:11
***************
*** 8,14 ****
    pid_t pid;
    int status;
  
-   (void)signo;
    while ( (pid = waitpid(-1, &status, WNOHANG)) > 0)
        --children;
  }
--- 8,14 ----
    pid_t pid;
    int status;
  
    while ( (pid = waitpid(-1, &status, WNOHANG)) > 0)
        --children;
+   signal(signo, pop3_sigchld);
  }
Index: pop3d/user.c
===================================================================
RCS file: /cvs/mailutils/pop3d/user.c,v
retrieving revision 1.10
diff -c -b -w -r1.10 user.c
*** pop3d/user.c        2001/04/14 20:17:27     1.10
--- pop3d/user.c        2001/04/21 15:11:11
***************
*** 24,32 ****
  static char *_user;
  static int _perr = 0;
  
! #define PAM_ERROR if (_perr || (pamerror != PAM_SUCCESS)) { \
!     pam_end(pamh, 0); \
!     return ERR_BAD_LOGIN; }
  
  static int
  PAM_gnupop3d_conv (int num_msg, const struct pam_message **msg, struct 
pam_response **resp, void *appdata_ptr)
--- 24,31 ----
  static char *_user;
  static int _perr = 0;
  
! #define PAM_ERROR if (_perr || (pamerror != PAM_SUCCESS)) \
!     goto pam_errlab;  
  
  static int
  PAM_gnupop3d_conv (int num_msg, const struct pam_message **msg, struct 
pam_response **resp, void *appdata_ptr)
***************
*** 145,152 ****
--- 144,154 ----
          spw = getspnam ((char *)arg);
          if (spw == NULL || strcmp (spw->sp_pwdp, crypt (pass, spw->sp_pwdp)))
  #endif /* HAVE_SHADOW_H */
+         {        
+           syslog (LOG_INFO, "User '%s': authentication faled", arg);    
            return ERR_BAD_LOGIN;
          }
+       }
  #else /* !USE_LIBPAM */
        _user = (char *) arg;
        _pwd = pass;
***************
*** 160,167 ****
        PAM_ERROR;
        pamerror = pam_setcred (pamh, PAM_ESTABLISH_CRED);
        PAM_ERROR;
        pam_end (pamh, PAM_SUCCESS);
!       openlog ("gnu-pop3d", LOG_PID, LOG_MAIL);
  #endif /* USE_LIBPAM */
  
  
--- 162,174 ----
        PAM_ERROR;
        pamerror = pam_setcred (pamh, PAM_ESTABLISH_CRED);
        PAM_ERROR;
+ pam_errlab:      
        pam_end (pamh, PAM_SUCCESS);
!       openlog ("gnu-pop3d", LOG_PID, LOG_FACILITY);
!       if (pamerror != PAM_SUCCESS) {                          
!             syslog (LOG_INFO, "User '%s': authentication faled", _user);
!             return ERR_BAD_LOGIN;
!       }
  #endif /* USE_LIBPAM */
  
  
***************
*** 210,215 ****
--- 217,223 ----
      }
    else if (strcasecmp (cmd, "QUIT") == 0)
      {
+       syslog(LOG_INFO, "Possible probe of account '%s'", arg);            
        free (cmd);
        return pop3_quit (pass);
      }
/* GNU mailutils - a suite of utilities for electronic mail
   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Library Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <mailutils/error.h>

static void default_error_printer(const char *fmt, va_list ap)
{
    vfprintf(stderr, fmt, ap);
    fprintf(stderr, "\n");
}

error_pfn_t error_printer = default_error_printer;

void
error(char *fmt, ...)
{
    va_list ap;

    if (!error_printer)
        return;
    va_start(ap, fmt);
    (*error_printer)(fmt, ap);
    va_end(ap);
}

void
error_set_print(error_pfn_t pfn)
{
    error_printer = pfn;
}

#ifndef _ERROR_H
#define _ERROR_H

#ifndef __P
#ifdef __STDC__
#define __P(args) args
#else
#define __P(args) ()
#endif
#endif /*__P */

typedef int (*error_pfn_t)();

void error(char *fmt, ...);
void error_set_print(error_pfn_t);

#endif

reply via email to

[Prev in Thread] Current Thread [Next in Thread]