/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. *//* * Mailbox checking code by Robert J. Gibson, adapted for PD ksh by * John R. MacMillan */#include "config.h"#ifdef KSH#include "sh.h"#include "ksh_stat.h"#include "ksh_time.h"#define MBMESSAGE "you have mail in $_"typedef struct mbox { struct mbox *mb_next; /* next mbox in list */ char *mb_path; /* path to mail file */ char *mb_msg; /* to announce arrival of new mail */ time_t mb_mtime; /* mtime of mail file */} mbox_t;/* * $MAILPATH is a linked list of mboxes. $MAIL is a treated as a * special case of $MAILPATH, where the list has only one node. The * same list is used for both since they are exclusive. */static mbox_t *mplist;static mbox_t mbox;static time_t mlastchkd; /* when mail was last checked */static time_t mailcheck_interval;static void munset ARGS((mbox_t *mlist)); /* free mlist and mval */static mbox_t * mballoc ARGS((char *p, char *m)); /* allocate a new mbox */static void mprintit ARGS((mbox_t *mbp));voidmcheck(){ register mbox_t *mbp; time_t now; struct tbl *vp; struct stat stbuf; now = time((time_t *) 0); if (mlastchkd == 0) mlastchkd = now; if (now - mlastchkd >= mailcheck_interval) { mlastchkd = now; if (mplist) mbp = mplist; else if ((vp = global("MAIL")) && (vp->flag & ISSET)) mbp = &mbox; else mbp = NULL; while (mbp) { if (mbp->mb_path && stat(mbp->mb_path, &stbuf) == 0 && S_ISREG(stbuf.st_mode)) { if (stbuf.st_size && mbp->mb_mtime != stbuf.st_mtime && stbuf.st_atime <= stbuf.st_mtime) mprintit(mbp); mbp->mb_mtime = stbuf.st_mtime; } else { /* * Some mail readers remove the mail * file if all mail is read. If file * does not exist, assume this is the * case and set mtime to zero. */ mbp->mb_mtime = 0; } mbp = mbp->mb_next; } }}voidmcset(interval) long interval;{ mailcheck_interval = interval;}voidmbset(p) register char *p;{ struct stat stbuf; if (mbox.mb_msg) afree((void *)mbox.mb_msg, APERM); if (mbox.mb_path) afree((void *)mbox.mb_path, APERM); /* Save a copy to protect from export (which munges the string) */ mbox.mb_path = str_save(p, APERM); mbox.mb_msg = NULL; if (p && stat(p, &stbuf) == 0 && S_ISREG(stbuf.st_mode)) mbox.mb_mtime = stbuf.st_mtime; else mbox.mb_mtime = 0;}voidmpset(mptoparse) register char *mptoparse;{ register mbox_t *mbp; register char *mpath, *mmsg, *mval; char *p; munset( mplist ); mplist = NULL; mval = str_save(mptoparse, APERM); while (mval) { mpath = mval; if ((mval = strchr(mval, PATHSEP)) != NULL) { *mval = '\0', mval++; } /* POSIX/bourne-shell say file%message */ for (p = mpath; (mmsg = strchr(p, '%')); ) { /* a literal percent? (POSIXism) */ if (mmsg[-1] == '\\') { /* use memmove() to avoid overlap problems */ memmove(mmsg - 1, mmsg, strlen(mmsg) + 1); p = mmsg + 1; continue; } break; } /* at&t ksh says file?message */ if (!mmsg && !Flag(FPOSIX)) mmsg = strchr(mpath, '?'); if (mmsg) { *mmsg = '\0'; mmsg++; } mbp = mballoc(mpath, mmsg); mbp->mb_next = mplist; mplist = mbp; }}static voidmunset(mlist)register mbox_t *mlist;{ register mbox_t *mbp; while (mlist != NULL) { mbp = mlist; mlist = mbp->mb_next; if (!mlist) afree((void *)mbp->mb_path, APERM); afree((void *)mbp, APERM); }}static mbox_t *mballoc(p, m) char *p; char *m;{ struct stat stbuf; register mbox_t *mbp; mbp = (mbox_t *)alloc(sizeof(mbox_t), APERM); mbp->mb_next = NULL; mbp->mb_path = p; mbp->mb_msg = m; if (stat(mbp->mb_path, &stbuf) == 0 && S_ISREG(stbuf.st_mode)) mbp->mb_mtime = stbuf.st_mtime; else mbp->mb_mtime = 0; return(mbp);}static voidmprintit( mbp )mbox_t *mbp;{ struct tbl *vp; /* Ignore setstr errors here (arbitrary) */ setstr((vp = local("_", FALSE)), mbp->mb_path, KSH_RETURN_ERROR); shellf("%s\n", substitute(mbp->mb_msg ? mbp->mb_msg : MBMESSAGE, 0)); unset(vp, 0);}#endif /* KSH */
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
/*
* Mailbox checking code by Robert J. Gibson, adapted for PD ksh by
* John R. MacMillan
*/
#include "config.h"
#ifdef KSH
#include "sh.h"
#include "ksh_stat.h"
#include "ksh_time.h"
#define MBMESSAGE "you have mail in $_"
typedef struct mbox {
struct mbox *mb_next; /* next mbox in list */
char *mb_path; /* path to mail file */
char *mb_msg; /* to announce arrival of new mail */
time_t mb_mtime; /* mtime of mail file */
} mbox_t;
/*
* $MAILPATH is a linked list of mboxes. $MAIL is a treated as a
* special case of $MAILPATH, where the list has only one node. The
* same list is used for both since they are exclusive.
*/
static mbox_t *mplist;
static mbox_t mbox;
static time_t mlastchkd; /* when mail was last checked */
static time_t mailcheck_interval;
static void munset ARGS((mbox_t *mlist)); /* free mlist and mval */
static mbox_t * mballoc ARGS((char *p, char *m)); /* allocate a new mbox */
static void mprintit ARGS((mbox_t *mbp));
void
mcheck()
{
register mbox_t *mbp;
time_t now;
struct tbl *vp;
struct stat stbuf;
now = time((time_t *) 0);
if (mlastchkd == 0)
mlastchkd = now;
if (now - mlastchkd >= mailcheck_interval) {
mlastchkd = now;
if (mplist)
mbp = mplist;
else if ((vp = global("MAIL")) && (vp->flag & ISSET))
mbp = &mbox;
else
mbp = NULL;
while (mbp) {
if (mbp->mb_path && stat(mbp->mb_path, &stbuf) == 0
&& S_ISREG(stbuf.st_mode))
{
if (stbuf.st_size
&& mbp->mb_mtime != stbuf.st_mtime
&& stbuf.st_atime <= stbuf.st_mtime)
mprintit(mbp);
mbp->mb_mtime = stbuf.st_mtime;
} else {
/*
* Some mail readers remove the mail
* file if all mail is read. If file
* does not exist, assume this is the
* case and set mtime to zero.
*/
mbp->mb_mtime = 0;
}
mbp = mbp->mb_next;
}
}
}
void
mcset(interval)
long interval;
{
mailcheck_interval = interval;
}
void
mbset(p)
register char *p;
{
struct stat stbuf;
if (mbox.mb_msg)
afree((void *)mbox.mb_msg, APERM);
if (mbox.mb_path)
afree((void *)mbox.mb_path, APERM);
/* Save a copy to protect from export (which munges the string) */
mbox.mb_path = str_save(p, APERM);
mbox.mb_msg = NULL;
if (p && stat(p, &stbuf) == 0 && S_ISREG(stbuf.st_mode))
mbox.mb_mtime = stbuf.st_mtime;
else
mbox.mb_mtime = 0;
}
void
mpset(mptoparse)
register char *mptoparse;
{
register mbox_t *mbp;
register char *mpath, *mmsg, *mval;
char *p;
munset( mplist );
mplist = NULL;
mval = str_save(mptoparse, APERM);
while (mval) {
mpath = mval;
if ((mval = strchr(mval, PATHSEP)) != NULL) {
*mval = '\0', mval++;
}
/* POSIX/bourne-shell say file%message */
for (p = mpath; (mmsg = strchr(p, '%')); ) {
/* a literal percent? (POSIXism) */
if (mmsg[-1] == '\\') {
/* use memmove() to avoid overlap problems */
memmove(mmsg - 1, mmsg, strlen(mmsg) + 1);
p = mmsg + 1;
continue;
}
break;
}
/* at&t ksh says file?message */
if (!mmsg && !Flag(FPOSIX))
mmsg = strchr(mpath, '?');
if (mmsg) {
*mmsg = '\0';
mmsg++;
}
mbp = mballoc(mpath, mmsg);
mbp->mb_next = mplist;
mplist = mbp;
}
}
static void
munset(mlist)
register mbox_t *mlist;
{
register mbox_t *mbp;
while (mlist != NULL) {
mbp = mlist;
mlist = mbp->mb_next;
if (!mlist)
afree((void *)mbp->mb_path, APERM);
afree((void *)mbp, APERM);
}
}
static mbox_t *
mballoc(p, m)
char *p;
char *m;
{
struct stat stbuf;
register mbox_t *mbp;
mbp = (mbox_t *)alloc(sizeof(mbox_t), APERM);
mbp->mb_next = NULL;
mbp->mb_path = p;
mbp->mb_msg = m;
if (stat(mbp->mb_path, &stbuf) == 0 && S_ISREG(stbuf.st_mode))
mbp->mb_mtime = stbuf.st_mtime;
else
mbp->mb_mtime = 0;
return(mbp);
}
static void
mprintit( mbp )
mbox_t *mbp;
{
struct tbl *vp;
/* Ignore setstr errors here (arbitrary) */
setstr((vp = local("_", FALSE)), mbp->mb_path, KSH_RETURN_ERROR);
shellf("%s\n", substitute(mbp->mb_msg ? mbp->mb_msg : MBMESSAGE, 0));
unset(vp, 0);
}
#endif /* KSH */