bug-bash
[Top][All Lists]
Advanced

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

Re: mail check fails when first mail creates new mail file


From: Michael Mueller
Subject: Re: mail check fails when first mail creates new mail file
Date: Sun, 19 Sep 2004 12:27:10 +0200
User-agent: Mozilla/5.0

Found two more problems in the source related to this.

1) After the $MAIL file is deleted file_mod_date_changed() returns 0 and update_mail_file() is not called. When new mail arrives, mailfiles[i]->file_size contains the size of the old mail file. Depending on this obsolete value file_has_grown() may return 0 and there will again be no "You have new mail" message.

2) If I do a "cp /dev/null $MAIL" I get "You have new mail".

I'm appending a complete patch which should fix all of this. (but 100% reliable mail checking seems to be close to impossible.)

Michael




Michael Mueller wrote:
Configuration Information [Automatically generated, do not change]:
Machine: i686
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i686' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i686-pc-linux-gnu' -DCONF_VENDOR='pc' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -g uname output: Linux m1 2.6.4-52-default #1 Wed Sep 15 14:02:03 CEST 2004 i686 i686 i386 GNU/Linux
Machine Type: i686-pc-linux-gnu

Bash Version: 2.05b
Patch Level: 0
Release Status: release

Description:

        If my $MAIL file does not exist (after I deleted all mails) and
        a new mail arrives, bash does not output a

                You have new mail in $MAIL

        as it used to do in older versions (quite a while ago). Only
        when the second mail arrives I am notified.

        Having no $MAIL file is normal after deleting all mail using
        /usr/bin/mail.

Repeat-By:

    MAIL=/var/spool/mail/michaelm
    $ MAILCHECK=0   # check for mail before next prompt
    $ mail
    No mail for michaelm
    $ ls -l $MAIL
    /bin/ls: /var/spool/mail/michaelm: No such file or directory
    $ # send some mail to myself.
    $ mail michaelm
    Subject: t
    .
    EOT
    $ ls -lu $MAIL; ls -l $MAIL
    -rw-------  1 michaelm users 591 Sep 18 13:11 /var/spool/mail/michaelm
    -rw-------  1 michaelm users 591 Sep 18 13:11 /var/spool/mail/michaelm
    $
    $ # mail check failed. I have new mail.
    $ # send another mail.
    $ mail michaelm
    Subject: t2
    .
    EOT
    $
    You have new mail in /var/spool/mail/michaelm
    $

Fix:

    This is caused by this code in mailcheck.c, function check_mail:

          /* If the user has just run a program which manipulates the
             mail file, then don't bother explaining that the mail
             file has been manipulated.  Since some systems don't change
             the access time to be equal to the modification time when
             the mail in the file is manipulated, check the size also.If
             the file has not grown, continue. */
          if ((atime >= mtime) || !file_is_bigger)
            continue;

    In bash-1.14.7 This used to be:

        if ((atime >= mtime) && !file_is_bigger)

    I'm not sure when and why the && was changed into ||.

    If mail is used to delete all mails, it deletes the $MAIL file. If
    the first mail arrives, $MAIL is recreated with atime == mtime and
    bash skips the mail check.

    I don't know what was bad about the old code. But I changed it into:

        if ((atime > mtime) || (atime == mtime && !file_is_bigger))
            continue;

    This might be even better.





--

=== Michael Mueller ==================
Tel. + 49 8171 63600
Fax. + 49 8171 63615
Web: http://www.mm.kay-mueller.de
     http://www.planets.kay-mueller.de
======================================
*** mailcheck.c.orig    Thu Jan 10 20:23:15 2002
--- mailcheck.c Sun Sep 19 11:55:49 2004
*************** free_mail_files ()
*** 206,213 ****
    mailfiles = (FILEINFO **)NULL;
  }
  
! /* Return non-zero if FILE's mod date has changed and it has not been
!    accessed since modified. */
  static int
  file_mod_date_changed (i)
       int i;
--- 206,213 ----
    mailfiles = (FILEINFO **)NULL;
  }
  
! /* Return non-zero if FILE's mod date has changed or if it was
!    deleted since the last check. */
  static int
  file_mod_date_changed (i)
       int i;
*************** file_mod_date_changed (i)
*** 215,228 ****
    time_t mtime;
    struct stat finfo;
    char *file;
  
    file = mailfiles[i]->name;
    mtime = mailfiles[i]->mod_time;
  
!   if ((mailstat (file, &finfo) == 0) && (finfo.st_size > 0))
!     return (mtime != finfo.st_mtime);
  
!   return (0);
  }
  
  /* Return non-zero if FILE's access date has changed. */
--- 215,230 ----
    time_t mtime;
    struct stat finfo;
    char *file;
+   off_t size;
  
    file = mailfiles[i]->name;
    mtime = mailfiles[i]->mod_time;
+   size = mailfiles[i]->file_size;
  
!   if ((mailstat (file, &finfo) != 0))
!     return (size > 0);        /* file was deleted? */
  
!   return (mtime != finfo.st_mtime);
  }
  
  /* Return non-zero if FILE's access date has changed. */
*************** check_mail ()
*** 377,382 ****
--- 379,385 ----
  
  #define atime mailfiles[i]->access_time
  #define mtime mailfiles[i]->mod_time
+ #define size mailfiles[i]->file_size
  
          /* Have to compute this before the call to update_mail_file, which
             resets all the information. */
*************** check_mail ()
*** 389,396 ****
             file has been manipulated.  Since some systems don't change
             the access time to be equal to the modification time when
             the mail in the file is manipulated, check the size also.  If
!            the file has not grown, continue. */
!         if ((atime >= mtime) || !file_is_bigger)
            continue;
  
          /* If the mod time is later than the access time and the file
--- 392,400 ----
             file has been manipulated.  Since some systems don't change
             the access time to be equal to the modification time when
             the mail in the file is manipulated, check the size also.  If
!            the file has not grown, continue. Also if file has been
!            truncated to 0, continue. */
!         if ((atime >= mtime && !file_is_bigger) || size == 0)
            continue;
  
          /* If the mod time is later than the access time and the file

reply via email to

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