1 /* $NetBSD: mail.c,v 1.5 2006/01/15 18:16:30 jschauma Exp $ */
4 * Mailbox checking code by Robert J. Gibson, adapted for PD ksh by
10 __RCSID("$NetBSD: mail.c,v 1.5 2006/01/15 18:16:30 jschauma Exp $");
21 #define MBMESSAGE "You have mail in $_"
24 struct mbox
*mb_next
; /* next mbox in list */
25 char *mb_path
; /* path to mail file */
26 char *mb_msg
; /* to announce arrival of new mail */
27 time_t mb_mtime
; /* mtime of mail file */
31 * $MAILPATH is a linked list of mboxes. $MAIL is a treated as a
32 * special case of $MAILPATH, where the list has only one node. The
33 * same list is used for both since they are exclusive.
36 static mbox_t
*mplist
;
38 static time_t mlastchkd
; /* when mail was last checked */
39 static time_t mailcheck_interval
;
41 static void munset
ARGS((mbox_t
*mlist
)); /* free mlist and mval */
42 static mbox_t
* mballoc
ARGS((char *p
, char *m
)); /* allocate a new mbox */
43 static void mprintit
ARGS((mbox_t
*mbp
));
53 now
= time((time_t *) 0);
56 if (now
- mlastchkd
>= mailcheck_interval
) {
61 else if ((vp
= global("MAIL")) && (vp
->flag
& ISSET
))
67 if (mbp
->mb_path
&& stat(mbp
->mb_path
, &stbuf
) == 0
68 && S_ISREG(stbuf
.st_mode
))
71 && mbp
->mb_mtime
!= stbuf
.st_mtime
72 && stbuf
.st_atime
<= stbuf
.st_mtime
)
74 mbp
->mb_mtime
= stbuf
.st_mtime
;
77 * Some mail readers remove the mail
78 * file if all mail is read. If file
79 * does not exist, assume this is the
80 * case and set mtime to zero.
93 mailcheck_interval
= interval
;
103 afree((void *)mbox
.mb_msg
, APERM
);
105 afree((void *)mbox
.mb_path
, APERM
);
106 /* Save a copy to protect from export (which munges the string) */
107 mbox
.mb_path
= str_save(p
, APERM
);
109 if (p
&& stat(p
, &stbuf
) == 0 && S_ISREG(stbuf
.st_mode
))
110 mbox
.mb_mtime
= stbuf
.st_mtime
;
117 register char *mptoparse
;
119 register mbox_t
*mbp
;
120 register char *mpath
, *mmsg
, *mval
;
125 mval
= str_save(mptoparse
, APERM
);
128 if ((mval
= strchr(mval
, PATHSEP
)) != NULL
) {
129 *mval
= '\0', mval
++;
131 /* POSIX/bourne-shell say file%message */
132 for (p
= mpath
; (mmsg
= strchr(p
, '%')); ) {
133 /* a literal percent? (POSIXism) */
134 if (mmsg
[-1] == '\\') {
135 /* use memmove() to avoid overlap problems */
136 memmove(mmsg
- 1, mmsg
, strlen(mmsg
) + 1);
142 /* at&t ksh says file?message */
143 if (!mmsg
&& !Flag(FPOSIX
))
144 mmsg
= strchr(mpath
, '?');
149 mbp
= mballoc(mpath
, mmsg
);
150 mbp
->mb_next
= mplist
;
157 register mbox_t
*mlist
;
159 register mbox_t
*mbp
;
161 while (mlist
!= NULL
) {
163 mlist
= mbp
->mb_next
;
165 afree((void *)mbp
->mb_path
, APERM
);
166 afree((void *)mbp
, APERM
);
176 register mbox_t
*mbp
;
178 mbp
= (mbox_t
*)alloc(sizeof(mbox_t
), APERM
);
182 if (stat(mbp
->mb_path
, &stbuf
) == 0 && S_ISREG(stbuf
.st_mode
))
183 mbp
->mb_mtime
= stbuf
.st_mtime
;
195 /* Ignore setstr errors here (arbitrary) */
196 setstr((vp
= local("_", FALSE
)), mbp
->mb_path
, KSH_RETURN_ERROR
);
198 shellf("%s\n", substitute(mbp
->mb_msg
? mbp
->mb_msg
: MBMESSAGE
, 0));