[net.bugs.4bsd] bug in ucbmail and 4.1bsd csh

goldfarb@ucf-cs.UUCP (Ben Goldfarb Esq.) (12/08/83)

I resolved a nasty problem here recently that involved both ucbmail
and csh.  I'll describe both, but I only have a fix for ucbmail;
I'd like to hear some opinions on what to do about csh.  These both
apply to 4.1bsd, since I am still waiting for Berkeley to send us
a 4.2 tape.

The user who unearthed the ucbmail problem had a line like the
following in his .mailrc:
   
     set record=~clay/mailout

When he sent mail, most of the time he would have no difficulties,
but occasionally he would get the error message:

     "~clay/mailout": Ambiguous

Checking it out, I found that the code that expands the tilde in
ucbmail forks an instance of csh which pipes the result of "echo ~clay/mailout"
back to mail.  In fio.c (ver. 2.2 7/20/81) the execl appears in the routine
expand() as follows:

     execl(Shell, Shell, "-c", cmdbuf, 0);

The problem with this is that if the user has set the mail variable in
his .cshrc and if h happens to have mail in his spool file,
the instance of csh that was invoked by mail will return
"You have mail." instead of the user's home directory.  Obviously,
ucbmail considers this ambiguous, but it was a bitch to track down since
the error message gives the argument of echo, not the string returned
from csh through the pipe.  This, of course, only happens when the
invoker has mail in his spool file.

I think the solution to this is obvious at this point.  Don't source the
user's .cshrc when you exec the shell and the problem disappears with
the added benefit that the exit from mail is quicker.  Thus, the above line
should be changed to:

     execl(Shell, Shell, "-cf", cmdbuf, 0);

Please let me know if anyone sees any problems in not sourceing .cshrc
in this case; I can't see any.

Now on to the csh problem.  I ran into it when I was investigating the 
previous situation since it involves the conditions under which csh
prints "You have mail." when a new shell is invoked.  I noticed that 
when I invoked a new shell with user=me from my login shell I didn't
get the message even though I had mail in the spool file, but when
I did the same su'ed to clay with user=clay I definitely did get the
message (he had mail in his spool file as well).  I found that the
following lines in checkmail() in csh.c were the reason:

     		if (stb.st_size == 0 || stb.st_atime > stb.st_mtime ||
		    (stb.st_atime < chktim && stb.st_mtime < chktim) ||
		    loginsh && !new)
			continue;

Specifically, the condition "stb.st_atime > stb.st_mtime" was succeeding
for me but failing for Clay even though both spool files hadn't been 
either accessed or updated in some time.  In my case, the spool file
is quite a bit larger than his which is possibly the reason why my
atime is always one second greater than my mtime, whereas his atime
and mtime are the same.

I could change the condition to "stb.st_atime > stb.st_mtime + 1", but that
looks like a kludge.  Does anyone have any strong feelings about how this
problem can be corrected?

Please submit responses to the net, since I think this is of general 
interest.

					Ben Goldfarb
					University of Central Florida
					uucp: {duke, decvax}!ucf-cs!goldfarb
					ARPA: goldfarb.ucf-cs@Rand-Relay

smk@linus.UUCP (Steven M. Kramer) (12/10/83)

The -c in the mail is not really a bug.  The basic format that SHOULD
be used for most cshrc files should be:

if ($?prompt)
	<most of your commands, set, aliases, ...>
else
	<stuff you set for programs, like vispell -- remember that?>
endif

What this will do is improve performance by NOT doing the commands
you use interactively (the 1st ones) when the csh is called from
programs or you run shell scripts.  I've used this for 1.5 years and
it works great.  However, since cshrc is called before login, you
have to kludge login a bit because certain things may not be set
right.  However, it is easily solvable.
-- 
	--steve kramer
	{allegra,genrad,ihnp4,utzoo,philabs,uw-beaver}!linus!smk	(UUCP)
	linus!smk@mitre-bedford						(MIL)

henk@dutesta.UUCP (Henk Hesselink) (12/14/83)

The way I stop a non-interactive C-shell from sourcing my .cshrc commands
is by checking if this shell incarnation has a prompt.  The whole .cshrc
file is enclosed by a test on $prompt:

        if ($?prompt) then
         .cshrc commands
        endif

This means that it isn't necessary to change all programs using csh for
filename expansion etc. to use the -f flag and the shell starts up almost
as fast.

-- 
Henk Hesselink, Delft Univ. of Technology
..!{decvax,philabs}!mcvax!dutesta!henk