I have been trying to track down some sort of bug that clients are
causing in qpopper at seemingly random instances.  There is no
discernable pattern to them that I can see.

This is 3.1.2 code.

The errors look like this:

        EOF from  at 10.20.11.79 (this.host.our.domain.tld): [0] 29
        (Illegal seek); 0 (Success) [popper.c:337]

The error is *not* always an `illegal seek'; it is often times a `no
such file or directory' and can contain other errors as well, but these
are the most common.

Notice the subsequent interpretation of the error on the stream: Success.

The problem is in myfgets():

    while ( --size > 0 ) {
        if ( ( nbytes = read ( fileno(fp), cp, 1 ) ) <= 0 )
            break;

        if ( *cp == '\n' ) {
            *++cp = '\0';
            found_nl++;
            break;
        }
        ++cp;
    }

    if ( ( nbytes <= 0 ) || ( cp == str ) ) {
        if ( nbytes == 0 ) {
            pop_log ( p, POP_NOTICE, HERE, "EOF from %s at %s (%s): "
                      "[%i] %i (%s); %d (%s)",
                      p->user, p->ipaddr, p->client,$
                      nbytes, errno, STRERROR(errno),
                      ferror(fp), STRERROR(ferror(fp)) );


Notice how streams are used to handle the files, but system calls are
used rather than high-level stream routines! Well that was strange (why
use the streams at all if you are going to do descriptor-based IO?) but
you'll notice that `errno' and its perror() interpretation is printed,
followed by the streams-equivalents.

This is where the strange, inconsistent error messages are coming from.
The problem is that errno should only be used if read() has returned a
`-1', and ferror() should probably never be used (there anyways) since
the IO we're doing is low-level, FD based.  Now since read() returned 0
(EOF), errno can be set at the time of the strerror() call to be any
random memory contents, because there was no error condition.  Read did
not set the errno itself, because there was no error that occurred.  I
do not think that C defines all routines that could modify errno first
modifiy it to be `0' when entering the function.

So we are returning errno values and passing them to strerror, when
errno probably got defined before by some completely, unrelated routing,
probably in setup code for the C library.

This code is bogus and needs to be removed because it is leading people
(like me) on wild goose chases trying to figure out what file is "no
such file or directory" or what is "invalid seek."  Probably to get rid
of errno/strerror/ferror altogether and just note that an EOF occurred.

That leads me to my question: why do so many clients return EOF so
often? These are mostly Outlook, MailMan and Netscape that generate
these, and it's a fast local LAN.

Do these clients simply close the connection without doing a `quit'?
Anyone else get these?

CCing [EMAIL PROTECTED] in case they handle `bug reports'; this one
is definitely a bug since the errno values are completely unrelated to
any possible error condition in this code path.

Reply via email to