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
rpw3@fortune.UUCP (12/17/83)
#R:ucf-cs:-111900:fortune:11600033:000:1072 fortune!rpw3 Dec 17 04:00:00 1983 This is the top of my ".cshrc". I also use the if($prompt), but include most of the aliases in any case, since I like to have those command available in shell escapes (yes, it's slow). The only way I know to handle the ".cshrc before .login" problem is by looking at my $PATH (which is changed from system default in .login). I needed that for the SSH (sub-shell prompt) kludge, which makes each additional level of sub-shell have another ">" in the prompt: 7> csh 1>> date Sat Dec 17 03:50:23 PST 1983 2>> ^D 8> I had to do that since 4.1 csh doesn't default unset variables to the null string, the way good old Bourne does. When building the string of >>>'s, I had to know when the first one was. ------------ if( $path[1] != /fs/rpw3/bin ) then # we haven't seen .login yet setenv SSH '\!' # avoid "unset variable" error echo '[source .cshrc]' endif setenv SSH $SSH'>' if ($?prompt) then set prompt=$SSH' ' set mail=/usr/spool/mail/rpw3 endif # set function keys alias a 'echo -n ^L;echo -n' alias b '( cd $HOME/mail ; mail \!* )' <<etc., etc.>>
fair@dual.UUCP (Erik E. Fair) (12/28/83)
Another useful way to check whether .login has been done already is the construction: if ($?TERMCAP) then foo endif At least, it's useful for those of you who put your termcap descriptions in the environment. I do, since it's faster than searching /etc/termcap for it, what ever `it' might happen to be... Erik E. Fair {ucbvax,amd70,zehntel,unisoft,onyx,its}!dual!fair Dual Systems Corporation, Berkeley, California