[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